A <span> or <a> has no native appearance, so
appearance: button resolves to none on it. Per
css-ui-4 the
appearance property never affects display. Chrome up to
M156 computes display: inline-block instead of the specified
display: inline.
<span style="appearance: button; display: inline">span</span>
/* computed display */
Chrome 156 -> inline-block (wrong)
Firefox 157 -> inline
Safari 27 -> inline
Computed display of elements without a native appearance. Every row
must report the specified value.
| Element | appearance | specified display | computed display | Result |
|---|
The case from
Mozilla bug 2074147:
an <a> with no in-flow content, appearance: button and a
specified width/height. With the correct
display: inline the box sizes to 0 and nothing is painted; with Chrome's
promotion to inline-block a 240x60 red area appears, and sites start to
depend on it.
Running...
LayoutTheme::AdjustStyle() coerces inline and table display
values to inline-block (and list-item/table to
block) for every element that carries an appearance value other
than none -- before the effective appearance is known to be
none. The coercion is a layout requirement of native widget boxes, which are
atomic inline-level or block-level and can never be table parts, so it has to key off the
element type rather than off the appearance value.
// third_party/blink/renderer/core/layout/layout_theme.cc
if (IsLaidOutAsWidget(element, appearance)) {
AdjustDisplayForWidget(builder);
}
// Widget elements keep the adjusted display even when author styles
// suppress their effective appearance; elements without a native
// appearance keep the specified display.
bool IsLaidOutAsWidget(const Element& element, AppearanceValue appearance) {
return appearance != AppearanceValue::kNone ||
AutoAppearanceFor(element) != AppearanceValue::kNone;
}
#408002786 -- same code path
suppressed ::marker on <details>/<li>
with appearance: auto. The element-type condition fixes it too.
#492945641 -- the earlier
attempt at #408002786 keyed off the effective appearance and broke
<button style="display: table-cell; border: none"> in tables
(P0, reverted via flag). Those buttons stay inline-block here, and a unit
test covers the case.
WPT: css/css-ui/appearance-display-001.html,
css/css-ui/appearance-auto-details-list-item.html.