Finding variable names for themes

Hello

I had a hard time finding the right variable names for my theme, respectively updating them accordingly when there was a change in home assistant updates. While it was a bit of a pain, I found a quite easy & straight-forward way to deal with variable names in themes. Since I didn’t found an up to date “how to find variable names” topic, I thought I’ll share my findings.

Please note this is just some reverse engineering and I’m not a HA developer. A more experience HA developer might give some more insights into the variable design.

To keep it simple, I assume basic knowledge in web development (especially CSS), shell (e.g. sh, bash, zsh) & git CLI is given :slight_smile: If somebody has a question regarding these topics, just reply and I’m happy to help.

HA STYLE

First of all, the variables for all themes can be found in the HA frontend repo under src/resources/ha-style.ts. Feel free to have a look at the (base) variables and overwrite them in your theme.

Please note you don’t have to overwrite all the variables of the theme, because some of them are just a layer of indirection (see description below). If you overwrite all of the variables, your template will just become bloated with useless definitions and harder to maintain. Start with the basic ones on top and see where it leads you to.

CONCEPT / LAYER OF INDIRECTION

There are some base variables, which are the “most generic ones”. They’re used everywhere and you might already get a nice theme by just overwriting them. However, there are also specific variables for different elements. In fact, there are multiple layers of indirection. This is where it gets a bit more complex - but not as complicated as it seems at first.

To shed some light, I try to elaborate the layer of indirection in this specific case. In web development (and thus HA) you’ve different elements. For example, there are form elements like input (textfield) & select (dropdown). Both those elements have their own variables, in this specific case at the time of writing this:

  • input uses --mdc-text-field-fill-color as background color variable
  • select uses --mdc-select-fill-color as background color variable

You can now set both variables to a specific value, for example white. However, in this case you need to set the same value multiple times. This is doable, but it’s a bit annoying & repeating when it comes to maintenance. Instead of setting the variable directly, HA developers introduced a layer of indirection, which looks like this:

  • input still uses --mdc-text-field-fill-color as background color variable
  • select still uses --mdc-select-fill-color as background color variable
  • variable --mdc-text-field-fill-color uses value of --input-fill-color
  • variable --mdc-select-fill-color also uses value of --input-fill-color

As you can see, you can now overwrite --mdc-text-field-fill-color & --mdc-select-fill-color if you want to have different colours in the text & select fields - or you can simply overwrite --input-fill-color to change the colour of both fields at the same time.

Please let me know if something is unclear :slight_smile:

FINDING VARIABLE NAMES OF ELEMENTS

You want to find the CSS variable name used for the specific element you’re trying to style. Open the element in the web developer tools by doing one of the following steps in Chrome (other browsers support the same thing, there are only minor differences):

  • Either… Use the inspect shortcut (Shift-Cmd-C in Chrome on macOS) then select the element
  • Or… Right-click on the element, then select “Inspect”
  • Or… Go to View > Developer > Inspect Elements, click on the cursor icon in the dev tools, then select the element

You should see something like this (example is an input field):

On the right, you can see the styles and the variable used for that style. In this case it’s var(--mdc-text-field-fill-color, whitesmoke). The variable name is --mdc-text-field-fill-color, with a default whitesmoke (used when variable is not found / defined).

THE POWER OF GIT GREP

An alternative way to find variable names and their defintions, is by using web developer tools & Git.

For that, I recommend cloning the frontend repository, by either using HTTPS or SSH:

# HTTPS (simpler, no configuration required since public):
git clone https://github.com/home-assistant/frontend.git

# SSH (SSH key needs to be configured on GH):
git clone [email protected]:home-assistant/frontend.git

Now we can grep the source code for the variable usage. Please note, Git has grep support built-in and it’s much faster than it’s standalone CLI counterpart, since Git is using its internal caching mechanisms:

$ git grep -- "mdc-text-field-fill-color"

hassio/src/addon-store/hassio-addon-store.ts:        --mdc-text-field-fill-color: var(--sidebar-background-color);
src/layouts/hass-tabs-subpage-data-table.ts:        --mdc-text-field-fill-color: var(--sidebar-background-color);
src/layouts/hass-tabs-subpage-data-table.ts:        --mdc-text-field-fill-color: var(--input-fill-color);
src/panels/config/application_credentials/ha-config-application-credentials.ts:        background-color: var(--mdc-text-field-fill-color, whitesmoke);
src/panels/config/entities/ha-config-entities.ts:          background-color: var(--mdc-text-field-fill-color, whitesmoke);
src/panels/config/integrations/ha-config-integrations.ts:          --mdc-text-field-fill-color: var(--sidebar-background-color);
src/panels/config/logs/ha-config-logs.ts:          --mdc-text-field-fill-color: var(--sidebar-background-color);
src/panels/developer-tools/state/developer-tools-state.js:          --mdc-text-field-fill-color: transparent;
src/resources/codemirror.ts:      "var(--code-editor-background-color, var(--mdc-text-field-fill-color, whitesmoke))",
src/resources/codemirror.ts:      "var(--code-editor-gutter-color, var(--mdc-text-field-fill-color, whitesmoke))",
src/resources/styles.ts:  "mdc-text-field-fill-color": "var(--input-fill-color)",

You can see where the variable is used in the source code. What’s important is its definition right here:

src/resources/styles.ts:  "mdc-text-field-fill-color": "var(--input-fill-color)",

As you can see, mdc-text-field-fill-color points to --input-fill-color.
You can now do another grep on input-fill-color to find the usage & definition of it:

$ git grep -- "input-fill-color"

src/resources/styles.ts:  "input-fill-color": "rgba(255, 255, 255, 0.05)",

We now found out that

  • mdc-text-field-color points to input-fill-color
  • input-fill-color is defined to rgba(255, 255, 255, 0.05).

If you want to know which side effects will occur when input-fill-color is set, simply do another grep for input-fill-color and so on…

8 Likes

Hello,

thank you very much for the good instructions! I have already been able to change many colours with it. Unfortunately, I am not able to change the colour of an active button. Via the developer console in Chrome I get the information that it should be the variable rgb-state-binary-sensor-color.

However, when I use the theme, the icon appears in white colour rgb(255, 255, 255). I don’t know much about html/css, but I suspect that the following output may be helpful for error analysis:

element.style {
}
constructed stylesheet
:host {
    display: var(--ha-icon-display, inline-flex);
    align-items: centre;
    justify-content: centre;
    position: relative;
    vertical-align: middle;
    fill: currentcolor;
    width: var(--mdc-icon-size, 24px);
    height: var(--mdc-icon-size, 24px);
}
style attribute {
    colour: rgb(var(--rgb-state-binary-sensor-color));
}
constructed stylesheet
ha-state-icon {
    width: 40%;
    height: auto;
    colour: var(--paper-item-icon-color, #44739e); # !! this entry is crossed out
    --mdc-icon-size: 100%;

I then tried to change numerous variables once - but without success. Only the use of “primary-text-color” also colours the button dark red as desired. However, I would not like to change the text colour.

test1:
  rgb-state-binary-sensor-color: darkred
  paper-item-icon-color: darkred
  primary-color: darkred
  accent-color: darkred
  paper-item-icon-color: darkred
  paper-item-icon-active-color: darkred
  state-icon-color: darkred
  state-icon-active-color: darkred
  state-color: darkred
  rgb-state-binary-sensor-alerting-color: darkred
  rgb-state-binary-sensor-color: darkred
  light-primary-color: darkred
  idle-line-color: darkred
  hover-line-color: darkred
  disabled-line-color: darkred
  outlined-idle-border-color: darkred
  outlined-hover-border-color: darkred
  outlined-disabled-border-color: darkred
  fill-color: darkred
  input-fill-color: darkred
  disabled-fill-color: darkred
  ink-color: darkred
  label-ink-color: darkred
  disabled-ink-color: darkred
  dropdown-icon-color: darkred
  divider-color: darkred
  mdc-ripple-color: darkred
  rgb-mdc-ripple-color: darkred
  input-idle-line-color: darkred
  input-hover-line-color: darkred
  input-disabled-line-color: darkred
  input-outlined-idle-border-color: darkred
  input-outlined-hover-border-color: darkred
  input-outlined-disabled-border-color: darkred
  input-fill-color: darkred
  input-disabled-fill-color: darkred
  input-ink-color: darkred
  input-label-ink-color: darkred
  input-disabled-ink-color: darkred
  input-dropdown-icon-color: darkred
  codemirror-variable-2: darkred

  # # primary-text-color: darkred

Can someone please help me? :sparkling_heart:

Now it is explained in the documentation: