Skip to content

Consider making box-sizing: border-box the default for Blockly v13 #9205

Description

@cpcallen

Check for duplicates

  • I have searched for similar issues before opening a new one.

Problem

The CSS attribute box-sizing affects how box dimensions are computed, and unfortunately for default value, content-box, is not ideal in most situations when trying to size one item inside another.

One example of where this becomes an issue is when trying to add a border around the toolbox to denote that it is focused: by default the sizing of the toolbox does not take the border into account, so the toolbox gets a few pixels wider and taller. The width isn't a big problem: it just pushes lightly further into the workspace—but the height is, because the bottom edge of the toolbox gets cut off by the overall size of the workspace:

Image

This specific issue is being fixed in #9201 (having previously been fixed with a much larger hammer in google/blocly-keyboard-experimentation#511) , but Blockly has had to apply box-sizing: border-box to a number of elements in order for them to be sized correctly.

This annoyance is so common in web design that many app stylesheets and some CSS resets include something like:

*, *::before, *::after {
  box-sizing: border-box;
}

in order to ensure that the attribute defaults to border-box everywhere—and note that box-sizing is not inheritable, so hence the need for wildcards here.

Because of the poor default value, the non-inheritability, and therefore likelihood that an app author will use a wildcard selector like * to apply box-sizing: border-box to their entire app, Blockly cannot rely on the value of the box-sizing attribute unless we set it directly.

Request

I propose that we include the following style in core/css.ts:

:is(
  .injectionDiv,
  .blocklyWidgetDiv,
  .blocklyDropdownDiv,
  .blocklyTooltipDiv,
) * {
  box-sizing: border-box;
}

This should have the effect of setting box-sizing to border-box on every element of Blockly, without affecting any of the surrounding app.

N.B.: This is a breaking change, because it applies box-sizing: border-box to everything within Blockly, including plugins and developer-supplied custom field editors, etc., which might (in principle at least) depend on the default box-sizing: content-box.

Alternatives considered

Setting box-sizing globally

We could add * {box-sizing: border-box} to core/css.ts, and this would certainly take care of the problem but would also change the default for the entire page, which we should definitely avoid.

Inheriting box-sizing:

An alternative to consider would be change the default for blockly by applying the attribute to the top-level divs and making it inherited by the rest of the app:

.injectionDiv, .blocklyWidgetDiv, .blocklyDropdownDiv, .blocklyTooltipDiv,html {
  box-sizing: border-box;
}

:is(
  .injectionDiv,
  .blocklyWidgetDiv,
  .blocklyDropdownDiv,
  .blocklyTooltipDiv,
) :is (* *, *:before, *:after) {
  box-sizing: inherit;
}

which would facilitate opting-out any plugins/components that actually rely on the CSS default: it would only be necessary to add box-sizing: content-box to the containing element and the contents would all be opt-ed out.

This however still requires an explicit opt-out for any component actually depending on the CSS defaut value, so it's not a panacea to avoid breaking changes.

Continuing to only set box-sizing where specifically needed

This has two main disadvantages:

  • We will continue to run into problems where layout is wrong until we explicitly add box-sizing: border-box.
  • If there are any parts of blockly that (intentionally or otherwise) depend on the default box-sizing: content-box, they are likely to be broken by app developers specifying a global default of border-box, since they will do so by wildcard.

Additional context

There have been a few issues which were caused by the bad default value for box-sizing, e.g.:

Activity

  1. self-assigned this
    on Jan 8, 2026
  2. moved this from Todo to In Progress in Blocklyon Jan 8, 2026
  3. moved this from In Progress to Done in Blocklyon Jan 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

  • Status
    Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions