-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Description
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:
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 ofborder-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.:
- PR [zelos] Cross browser pixel perfect text input #3466 fixed cross-browser field rendering differences by adding
box-sizing: border-boxtoblocklyHtmlInput(FieldTextInput). - Dropdown menu always scrollable #2128 was suspected to have been caused by
box-sizingthough became irreproducible before this could be verified.