---
description: Customizing the look and feel of your application with CSS.
title: Style with CSS
image: images/blockly_banner.png
---

# Style with CSS

Blockly applications are constructed of HTML and SVG elements. These elements
are labeled with CSS classes that identify what they represent (e.g.
`blocklyBlock`, `blocklyField`) as well as their state (e.g. `blocklyEditing`,
`blocklySelected`). Blockly also provides a default set of CSS rules.

You can use CSS to style your application:

- Override Blockly's CSS rules with your own rules.
- Add your own CSS classes to Blockly components for additional specificity.
- Use CSS classes and rules to style custom components.

For a practical introduction to using CSS in blockly, see the [Use CSS in Blockly](/codelabs/css/codelab-overview)

:::note
The easiest way to style Blockly is with [themes](/guides/configure/appearance/themes). If you need finer-grained control, use CSS.
:::

## CSS classes

Blockly applications use CSS classes to identify elements to be styled. This
provides finer-grained control than type (element) selectors.

### Blockly CSS classes

Blockly uses CSS classes to provide the following kinds of information about the
HTML and SVG elements it uses.

- **Type.** Most Blockly CSS classes identify what an element represents. For
  example, the root element of a block is labeled `blocklyBlock`. Some
  elements are labeled with multiple classes, each more specific than the
  last. For example, the root element of a text input field is labeled
  `blocklyField`, `blocklyInputField`, and `blocklyTextInputField`. Type
  classes remain the same for the life of a component.

- **State.** Blockly also uses CSS classes to specify the state of a
  component. For example, when the cursor is on a text input field, its root
  element is labeled with the `blocklyEditing` class. When the cursor is moved
  away, this class is removed.

- **Additional information.** Blockly uses a few CSS classes to provide
  additional information. For example, the injection `<div>` has classes that
  provide the name of the workspace's current renderer and theme. These
  classes generally remain the same for the life of the application.

The easiest way to discover what CSS classes Blockly uses is to open your
browser's developer tools and inspect the elements used by your application.

### Custom CSS classes

You can use custom CSS classes to provide more specificity to Blockly
components.

#### Workspaces

To add or remove a CSS class from a workspace's injection `<div>`, call
`WorkspaceSvg.addClass` or `WorkspaceSvg.removeClass`.

#### Toolboxes

To add a CSS class to a button or a label in a toolbox, use the `web-class` key
in your JSON definition of the toolbox. For more information, see [Buttons and
labels](/guides/configure/toolboxes/buttons).

To override the CSS classes used for the various parts of a category, use the
`cssConfig` key in your JSON definition of the category. This allows you to
style individual categories. For more information, see [Category
CSS](/guides/configure/toolboxes/appearance#category-css).

#### Blocks

To add CSS classes to a custom block, pass a string or array of strings to the
`classes` key.

```js
Blockly.common.defineBlocksWithJsonArray([
  {
    type: 'string_length',
    message0: 'length of %1',
    args0: [
      {
        type: 'input_value',
        name: 'VALUE',
        check: 'String',
      },
    ],
    classes: 'myStringLengthBlock',
    output: 'Number',
    colour: 160,
  },
]);
```

You can also add or remove a CSS class from a block's `<g>` element by calling
`BlockSvg.addClass` or `BlockSvg.removeClass`.

#### Label fields

To add or remove a CSS class from the `<text>` element used by a label field or
serializable label field, call `FieldLabel.setClass`. You can also pass a class
name to the label's constructor.

### CSS classes and custom components

When constructing a custom component, use one of the following methods to add
custom CSS classes:

- If your component is a subclass of `Field` or `Icon`, override the
  `initView` method. For example:

  ```js
  class MyCustomField extends Blockly.FieldTextInput {
    ...

    initView() {
      super.initView();

      // Add custom CSS class so we can style the field.
      if (this.fieldGroup_) {
        Blockly.utils.dom.addClass(this.fieldGroup_, 'myCustomField');
      }
    }
  }
  ```

  For more information, see [Customizing fields with
  CSS](/guides/create-custom-blocks/fields/customizing-fields/creating#css)
  or [Create the icon's
  view](/guides/create-custom-blocks/icons/creating-custom-icons/basic-implementation#create-the-icons-view).

- When constructing an SVG element, pass your class to
  `Blockly.utils.dom.createSvgElement`:

  ```js
  this.svgRoot = Blockly.utils.dom.createSvgElement(Svg.G, {
    class: 'myCustomComponent',
  });
  ```

- When constructing an HTML element, use `Blockly.utils.dom.addClass`:

  ```js
  const myDiv = document.createElement('div');
  Blockly.utils.dom.addClass(myDiv, 'myInformation');
  ```

To add or remove classes after construction, use `Blockly.utils.dom.addClass` or
`Blockly.utils.dom.removeClass`.

```js
setMyHighlight(highlight) {
  if (highlight) {
    Blockly.utils.dom.addClass(this.svgRoot, 'myHighlight');
  } else {
    Blockly.utils.dom.removeClass(this.svgRoot, 'myHighlight');
  }
}
```

:::warning
Do not use `dom.addClass` or `dom.removeClass` to add classes to or
remove classes from components written by others, including Blockly. This might
lead to unpredictable results.
:::

## CSS rules background

If you understand SVG styling properties and the CSS cascade, you can
[skip](#css-rules) this section.

### SVG styling properties versus CSS properties \{#svg-style\}

SVG elements are styled with [SVG styling
properties](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute#presentation_attributes).
These can be used as attributes on SVG elements (aka **presentation
attributes**) or in CSS rules. Thus, all of the following do the same thing.

```svg
<!-- SVG file with presentation attributes. -->
<circle fill="red" ... />
```

```svg
<!-- SVG file with <style> tag. -->
<style>
  circle {fill:red;}
</style>
<circle ... />
```

```css
/* External CSS file.*/
circle {
  fill: red;
}
```

```svg
<!-- SVG file with inline style. -->
<circle style="fill:red;" ... />
```

The list of SVG styling properties is related to but different from the list of
CSS properties:

- **Same concept, same name.** For example, both SVG and CSS use `direction`
  to specify whether text is LTR or RTL.
- **Same concept, different name.** For example, SVG uses `fill` to specify
  fill color; CSS uses `background-color`.
- **CSS only.** CSS has many properties that are not in SVG, such as `margin`
  and `padding`.
- **SVG only.** SVG has a few properties that are not in CSS, such as `x` and
  `y`.

Thus, if you're styling an SVG element, use [SVG styling
properties](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute#presentation_attributes).
If you're styling an HTML element, use [CSS
properties](https://www.w3schools.com/CSSref/index.php).

### CSS cascade

The [CSS
cascade](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascade/Cascade#cascading_order)
determines the _priorities_ of CSS rules, which determine which rule to use if
more than one rule applies to a given property and element. The following
simplified cascade covers the parts of the cascade most commonly used by Blockly
and may help you resolve the question, "Why doesn't my CSS work?"

#### Simplified cascade \{#simplified\}

To determine which rule applies to a particular element and property, follow
these steps and stop when only one rule remains:

1.  Gather all the rules that apply to the property and element.
1.  If any rules have an `!important` annotation, discard all rules that don't
    have an `!important` annotation.
1.  Choose the rules with the highest
    [specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascade/Specificity).
    - [SVG presentation attributes](#svg-style) have a specificity of zero.
    - Rules in a `<style>` tag or external stylesheet have their specificity
      calculated normally.
    - Inline styles (styles set by a `style` attribute) have a specificity
      higher than any selector.

1.  Choose the rule that appears last in the document.
1.  If no rule applies, inherit the property's value from the element's parent.

This algorithm does not consider the following parts of the cascade:

- The [`transition`](https://developer.mozilla.org/en-US/docs/Web/CSS/transition)
  property, which has the highest priority. Blockly uses a few of these.
- The [`@media`](https://developer.mozilla.org/en-US/docs/Web/CSS/@media)
  at-rule. Blockly uses one of these.
- Rules specified by the browser or user.
- The `@scope` and `@layer` at-rules and the `animation` property, which are
  not used by Blockly.

## CSS rules

CSS rules specify how your application is styled. Blockly provides a default set
of rules that you can override with your own rules.

### Blockly CSS rules

Blockly provides a default set of CSS rules. How and where these rules are added
affects their [priority](#simplified).

#### Style tags

The majority of Blockly's CSS rules are specified in two `<style>` tags. Because
these tags occur near the top of the page, the rules in them have lower priority
than rules with the same specificity that occur later in the page.

##### Blockly.css.register rules

When Blockly is injected, it adds a `<style>` tag as a child of the `<head>`
tag. The rules in this tag come from:

- The `Blockly.css` namespace. To see these rules, open
  [core/css.ts](https://github.com/RaspberryPiFoundation/blockly/blob/main/packages/blockly/core/css.ts) and
  search for `let content`.
- Individual components, which call `Blockly.css.register` to add
  component-specific CSS rules. Because `css.register` adds these rules to the
  end of the `content` string, they have higher priority than rules with the
  same specificity that were added earlier. To see these rules, see the [calls
  to
  `Blockly.css.register`](https://github.com/search?q=repo%3ARaspberryPiFoundation%2Fblockly+css.register+path%3Acore&type=code).

If you do not want to use these rules, set the [`css` configuration
option](/guides/configure/configuration_struct#the-options-dictionary)
to `false`. In this case, you are responsible for providing an alternate set of
CSS rules.

##### Renderer rules

When the renderer is instantiated, it adds a `<style>` tag containing
renderer-specific CSS rules as a child of the `<head>` tag. Note that these
rules are always added -- they are not affected by the `css` configuration
option. To see these rules, search for the `getCss_` method in your renderer.

#### Inline styles

Inline styles are specified with the `style` attribute and are generally created
when the DOM for a component is created. For a partial list, see [this GitHub
query](https://github.com/search?q=repo%3ARaspberryPiFoundation%2Fblockly+.style+path%3Acore&type=code).

Inline styles apply directly to the element on which they occur and have a
specificity higher than any selector. For this reason, overriding them generally
requires you to use an [`!important`
annotation](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascade/Specificity#the_!important_exception).

#### SVG presentation attributes

[SVG presentation attributes](#svg-style) are SVG styling properties used as
attributes of SVG elements. They have a specificity of zero and cannot contain
an `!important` annotation, so they have the lowest priority of all of Blockly's
rules. Blockly generally creates them in [calls to
`createSvgElement`](https://github.com/search?q=repo%3ARaspberryPiFoundation%2Fblockly%20createsvgelement%20path%3Acore&type=code).

### Add your own CSS rules

You can add your own CSS rules using the same methods as Blockly:

- Call `Blockly.css.register` before injecting Blockly. Your rules will be
  added after Blockly's and have a higher priority than Blockly rules with the
  same specificity.
- Add a `<style>` tag or link to an external style sheet as a later child of
  the `<head>` tag. Because Blockly adds its rules as the first two children
  of the `<head>` tag, your rules will have a higher priority than Blockly
  rules with the same specificity.
- Use inline styles to add styles to elements in a custom component. These
  rules will have a higher specificity than any rules with a selector.
- Use presentation attributes on SVG elements in a custom component. These
  rules will have a lower specificity than any rules with a selector.

### Troubleshooting

If your CSS is not working, here are some possible causes:

- You are using CSS properties on an SVG element or SVG styling properties on
  an HTML element. See [SVG styling properties versus CSS
  properties](#svg-style).

- Your rule has a lower priority than another rule. This is usually due to a
  lower [specificity](#simplified). Possible ways to fix this are:
  - Use a class selector instead of a type (element) selector.
  - Use multiple selectors.
  - If possible, [add a custom class](#custom-css-classes) to your target
    element and use this class in your rule.
  - As a last resort, add an `!important` annotation to your rule. This is
    your only choice if a competing rule is specified using an inline style
    (`style` attribute).

- Your rule has the same specificity as another rule, but occurs earlier in
  the page. If you cannot increase the specificity of your rule, move it later
  in the page.

There are two types of CSS rules you cannot override:

- Properties that are set inside a `transition` rule.
- `!important` rules specified by the browser.
