Implement flex-flow shorthand semantics

Parse the unordered flex-direction/flex-wrap shorthand atomically, reset
omitted constituents to their initial values, and expose the same grammar
through CSS.supports and computed-style capability surfaces.

Add a Chromium-paired fixture covering both token orders, shorthand resets,
invalid-declaration fallback, and JavaScript capability reporting.
This commit is contained in:
SGavrl committed 2026-08-04 07:47:14 +00:00
1 parent c2b57c74a1
commit 98c53b6b15
5 files changed
+204 -4

No files matched your search

+13
View File
@@ -63,6 +63,19 @@
"eventtarget-lifecycle": [
{"name": "framework lifecycle EventTarget completes", "color": "#18723a", "x": 0, "y": 0, "width": 420, "height": 120}
],
"flex-flow": [
{"name": "direction-first shorthand starts a column", "color": "#087f5b", "x": 0, "y": 0, "width": 100, "height": 40},
{"name": "direction-first shorthand keeps column flow", "color": "#0ca678", "x": 0, "y": 40, "width": 100, "height": 40},
{"name": "wrap-first shorthand starts a column", "color": "#1971c2", "x": 200, "y": 0, "width": 100, "height": 40},
{"name": "wrap-first shorthand keeps column flow", "color": "#1c7ed6", "x": 200, "y": 40, "width": 100, "height": 40},
{"name": "direction-only shorthand resets nowrap", "color": "#e8590c", "x": 400, "y": 0, "width": 100, "height": 40},
{"name": "reset nowrap keeps the second item on the row", "color": "#f76707", "x": 500, "y": 0, "width": 100, "height": 40},
{"name": "wrap-only shorthand resets row direction", "color": "#7048e8", "x": 0, "y": 120, "width": 100, "height": 40},
{"name": "reset row direction wraps the second item", "color": "#7950f2", "x": 0, "y": 160, "width": 100, "height": 40},
{"name": "invalid later shorthand retains the column", "color": "#c2255c", "x": 200, "y": 120, "width": 100, "height": 40},
{"name": "invalid shorthand does not partially mutate", "color": "#d6336c", "x": 200, "y": 160, "width": 100, "height": 40},
{"name": "CSS supports accepts only the shorthand grammar", "color": "#18723a", "x": 400, "y": 120, "width": 180, "height": 40}
],
"flex-whitespace-items": [
{"name": "direct flex sidebar starts at container edge", "color": "#1971c2", "x": 0, "y": 0, "width": 225, "height": 180},
{"name": "direct flex body keeps its intended inset", "color": "#2b8a3e", "x": 225, "y": 0, "width": 675, "height": 200},
+40
View File
@@ -0,0 +1,40 @@
<!doctype html>
<meta charset="utf-8">
<style>
html, body { margin: 0; width: 900px; min-height: 1000px; }
.case { display: flex; position: absolute; width: 150px; height: 80px; }
.item { flex: none; width: 100px; height: 40px; }
#direction-first { left: 0; top: 0; flex-flow: column wrap; }
#wrap-first { left: 200px; top: 0; flex-flow: wrap column; }
/* A one-token shorthand resets the omitted longhand to its initial value. */
#direction-only { left: 400px; top: 0; flex-wrap: wrap; flex-flow: row; }
#wrap-only { left: 0; top: 120px; flex-direction: column; flex-flow: wrap; }
/* The invalid later shorthand must not partially replace either longhand. */
#invalid-later { left: 200px; top: 120px; flex-flow: column wrap; flex-flow: row column; }
#a1 { background: #087f5b; } #a2 { background: #0ca678; }
#b1 { background: #1971c2; } #b2 { background: #1c7ed6; }
#c1 { background: #e8590c; } #c2 { background: #f76707; }
#d1 { background: #7048e8; } #d2 { background: #7950f2; }
#e1 { background: #c2255c; } #e2 { background: #d6336c; }
#supports { position: absolute; left: 400px; top: 120px; width: 180px; height: 40px; background: #c92a2a; }
</style>
<div id="direction-first" class="case"><div id="a1" class="item"></div><div id="a2" class="item"></div></div>
<div id="wrap-first" class="case"><div id="b1" class="item"></div><div id="b2" class="item"></div></div>
<div id="direction-only" class="case"><div id="c1" class="item"></div><div id="c2" class="item"></div></div>
<div id="wrap-only" class="case"><div id="d1" class="item"></div><div id="d2" class="item"></div></div>
<div id="invalid-later" class="case"><div id="e1" class="item"></div><div id="e2" class="item"></div></div>
<div id="supports"></div>
<script>
const valid = ["column", "wrap", "column wrap", "wrap column"];
const invalid = ["row column", "nowrap wrap-reverse", "none"];
if (valid.every(value => CSS.supports("flex-flow", value)) &&
invalid.every(value => !CSS.supports("flex-flow", value))) {
document.querySelector("#supports").style.background = "#18723a";
}
</script>