From 3650c6095fd877a0007bbeda76b824547e3e3e36 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Aug 2026 18:00:52 +0100 Subject: [PATCH 1/4] build(deps-dev): bump file-type from 22.0.1 to 22.0.2 (#45222) Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 161af618adccc3a..25b852abf7c7d80 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "cspell-group-by-file-reporter": "^1.0.1", "env-cmd": "11.0.0", "fdir": "^6.5.0", - "file-type": "^22.0.1", + "file-type": "^22.0.2", "gray-matter": "^4.0.3", "imagemin": "^9.0.1", "imagemin-gifsicle": "^7.0.0", @@ -4164,9 +4164,9 @@ } }, "node_modules/file-type": { - "version": "22.0.1", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-22.0.1.tgz", - "integrity": "sha512-ww5Mhre0EE+jmBvOXTmXAbEMuZE7uX4a3+oRCQFNj8w++g3ev913N6tXQz0XTXbueQ5TWQfm6BdaViEHHn8bhA==", + "version": "22.0.2", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-22.0.2.tgz", + "integrity": "sha512-0H8TsCUGBLx+V5adH3EY52hTAcyLKbV1D4gq5cIOJ6DnQAHeV9Z2Hhuc5CoBX4YmvB2oL+JIC84z0qO7JsCoNw==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 31a374eab36d3af..8d9f40023a6b93d 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "cspell-group-by-file-reporter": "^1.0.1", "env-cmd": "11.0.0", "fdir": "^6.5.0", - "file-type": "^22.0.1", + "file-type": "^22.0.2", "gray-matter": "^4.0.3", "imagemin": "^9.0.1", "imagemin-gifsicle": "^7.0.0", From 3db375935d88624f69f3ed3977a4508be10642b3 Mon Sep 17 00:00:00 2001 From: Estelle Weyl Date: Tue, 18 Aug 2026 11:06:41 -0700 Subject: [PATCH 2/4] Module example update: CSS gaps (#45091) * Module example update: CSS gaps * Module example update: CSS gaps * make backwards compat * make backwards compat * form layout * Update files/en-us/web/css/guides/gaps/index.md Co-authored-by: Chris Mills --------- Co-authored-by: Chris Mills --- files/en-us/web/css/guides/gaps/index.md | 218 ++++++++++++++--------- 1 file changed, 133 insertions(+), 85 deletions(-) diff --git a/files/en-us/web/css/guides/gaps/index.md b/files/en-us/web/css/guides/gaps/index.md index d99ec3d3e13eadb..09e6e45d69301b7 100644 --- a/files/en-us/web/css/guides/gaps/index.md +++ b/files/en-us/web/css/guides/gaps/index.md @@ -11,6 +11,9 @@ The **CSS gaps** module lets you specify spacing, or "gaps", between items in [m While {{cssxref("margin")}} and {{cssxref("padding")}} specify visual spacing around individual boxes, the properties in this module enable specifying the spacing between adjacent boxes within a given layout context for layouts that have {{glossary("gutters")}} and gaps, when the spacing is different between sibling boxes as opposed to between the first box, last box, and the container's edge. You can show rules in every gap or in a subset of gaps, defining fully animatable rule widths, colors, and insets. +Gap decorations are painted within a gap as one or more gap decoration segments, with segments occurring between any two adjacent items. +When all segments are drawn, column and row rules span the entire height and width of the container. The {{cssxref("rule-visibility-items")}} property defines whether segments are to be drawn around areas that are not occupied by items. The {{cssxref("rule-break")}} properties determine if lines break when they intersect a gap, while {{cssxref("rule-inset")}} defines where segments start and end when rules do break. If they don't break, the {{cssxref("rule-overlap")}} property defines the painting order of the rules. + ## Gaps in action In this example, the 2021 poem from the USA inauguration, _The Hill We Climb_, by Amanda Gorman, is displayed across multiple columns, similar to the way articles are displayed in printed newspapers. If you have JavaScript enabled, controls enable changing the {{cssxref("column-gap")}}, {{cssxref("column-rule-color")}}, {{cssxref("column-rule-style")}} and {{cssxref("column-rule-width")}} properties, as well as the preferred number of columns and whether the title and a quote should span all of the columns. @@ -140,10 +143,6 @@ In this example, the 2021 poem from the USA inauguration, _The Hill We Climb_, b
-

- - -

@@ -152,41 +151,69 @@ In this example, the 2021 poem from the USA inauguration, _The Hill We Climb_, b

-

- - 1em; -

-

- - 0.25em; -

-

- - -

-

- - -

+
+

+ + +

+

+ + +

+

+ + +

+

+ + +

+

+ + 1em +

+

+ + 0.3em +

+

+ + 0% +

+
``` @@ -210,6 +237,9 @@ const ruleWidth = document.getElementById("ruleWidth"); const columnRuleStyle = document.getElementById("columnRuleStyle"); const ruleStyle = document.getElementById("ruleStyle"); const columnRuleColor = document.getElementById("colColor"); +const colHeight = document.getElementById("colHeight"); +const ruleInset = document.getElementById("ruleInset"); +const inset = document.getElementById("inset"); // Make options visible if JavaScript is enabled option.style.display = "revert"; @@ -222,18 +252,28 @@ colCount.addEventListener("change", () => { page.style.columnCount = colCount.value; }); -gapSize.addEventListener("change", () => { +colHeight.addEventListener("input", () => { + page.style.columnHeight = `${colHeight.value}vh`; +}); + +gapSize.addEventListener("input", () => { page.style.gap = `${gapSize.value}em`; - gap.innerText = `${gapSize.value}em;`; + gap.innerText = `${gapSize.value}em`; +}); +ruleInset.addEventListener("input", () => { + page.style.ruleInset = `${ruleInset.value}%`; + inset.innerText = `${ruleInset.value}%`; }); -columnRuleWidth.addEventListener("change", () => { +columnRuleWidth.addEventListener("input", () => { page.style.columnRuleWidth = `${columnRuleWidth.value}em`; - ruleWidth.innerText = `${columnRuleWidth.value}em;`; + page.style.ruleWidth = `${columnRuleWidth.value}em`; + ruleWidth.innerText = `${columnRuleWidth.value}em`; }); -columnRuleStyle.addEventListener("change", () => { +columnRuleStyle.addEventListener("input", () => { page.style.columnRuleStyle = columnRuleStyle.value; + page.style.ruleStyle = columnRuleStyle.value; }); colSpan.addEventListener("change", () => { @@ -244,8 +284,9 @@ blockSpan.addEventListener("change", () => { setColSpan(blockSpan, blockquote); }); -columnRuleColor.addEventListener("change", () => { +columnRuleColor.addEventListener("input", () => { page.style.columnRuleColor = colColor.value; + page.style.ruleColor = colColor.value; }); function showAndHideMenu() { @@ -275,7 +316,9 @@ function setColSpan(control, element) { article { column-count: 5; gap: 1em; - column-rule: 0.25em dashed currentColor; + column-rule: 0.3em double #ff0000; + rule: 0.3em double #ff0000; + column-height: 20vh; } .title { column-span: all; @@ -288,45 +331,6 @@ p { margin: 0 0 1em 0; line-height: 1.4; } -.code { - font-family: monospace; -} -.breakInside * { - break-inside: avoid; -} -#options { - position: fixed; - top: 1rem; - right: 1rem; - background: white; - display: none; -} -fieldset p { - margin-bottom: 0.25em; -} -legend { - position: relative; - top: 0; - transition: 200ms; -} -legend.closed { - top: 0.75em; -} -legend.closed + #controls { - display: none; -} -legend { - background-color: #dedede; - padding: 0.5em; -} -legend > button { - all: unset; - cursor: pointer; -} -legend.closed { - margin: -1em; - display: inline-block; -} blockquote { font-weight: bold; font-style: italic; @@ -338,6 +342,50 @@ blockquote p::after { vertical-align: baseline; color: red; } + +@layer form { + #options { + position: fixed; + top: 1rem; + right: 1rem; + background: white; + display: none; + padding: 0.5em 1em; + } + section { + font-family: monospace; + } + fieldset p { + margin-bottom: 0.25em; + } + legend { + position: relative; + top: 0; + transition: 200ms; + } + legend.closed { + top: 0.75em; + } + legend.closed + #controls { + display: none; + } + legend { + background-color: #dedede; + padding: 0.5em; + } + legend > button { + all: unset; + cursor: pointer; + } + legend.closed { + margin: -1em; + display: inline-block; + } + .output { + display: inline-block; + width: 2em; + } +} ``` {{EmbedLiveSample("multicol", "", "800px")}} From ae836b44d9faa0e9f581631ed1dcccd2a502b618 Mon Sep 17 00:00:00 2001 From: Chris Mills Date: Tue, 18 Aug 2026 19:19:19 +0100 Subject: [PATCH 3/4] Editorial review: Document the flex-wrap balance keyword and flex-line-count property (#44896) * Document the flex-wrap balance keyword and flex-line-count property * add note about flex-wrap implicit behavior * Add Wikipedia reference columns style example * Update files/en-us/web/css/guides/flexible_box_layout/wrapping_items/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/guides/flexible_box_layout/wrapping_items/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/guides/flexible_box_layout/wrapping_items/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/guides/flexible_box_layout/wrapping_items/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/guides/flexible_box_layout/wrapping_items/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-flow/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-line-count/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-wrap/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-line-count/index.md Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Fixes for estelle review comments * Update files/en-us/web/css/guides/flexible_box_layout/wrapping_items/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-line-count/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-wrap/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-wrap/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-wrap/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-wrap/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-line-count/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-line-count/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-line-count/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/guides/flexible_box_layout/wrapping_items/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-line-count/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-wrap/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-wrap/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-wrap/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-wrap/index.md Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * More review fixes * Update files/en-us/web/css/reference/properties/flex-line-count/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/guides/flexible_box_layout/wrapping_items/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-wrap/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-wrap/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-line-count/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-wrap/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-line-count/index.md Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update files/en-us/web/css/reference/properties/flex-wrap/index.md Co-authored-by: Estelle Weyl * Update files/en-us/web/css/reference/properties/flex-wrap/index.md Co-authored-by: Estelle Weyl * More changes --------- Co-authored-by: Estelle Weyl Co-authored-by: Estelle Weyl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../css/guides/flexible_box_layout/index.md | 5 +- .../wrapping_items/index.md | 95 +++++ .../reference/properties/flex-flow/index.md | 22 +- .../properties/flex-line-count/index.md | 383 ++++++++++++++++++ .../reference/properties/flex-wrap/index.md | 216 +++++++++- 5 files changed, 711 insertions(+), 10 deletions(-) create mode 100644 files/en-us/web/css/reference/properties/flex-line-count/index.md diff --git a/files/en-us/web/css/guides/flexible_box_layout/index.md b/files/en-us/web/css/guides/flexible_box_layout/index.md index 9d0bfd31877eebc..0827c578615f0b3 100644 --- a/files/en-us/web/css/guides/flexible_box_layout/index.md +++ b/files/en-us/web/css/guides/flexible_box_layout/index.md @@ -3,7 +3,9 @@ title: CSS flexible box layout short-title: Flexible box layout slug: Web/CSS/Guides/Flexible_box_layout page-type: css-module -spec-urls: https://drafts.csswg.org/css-flexbox/ +spec-urls: + - https://drafts.csswg.org/css-flexbox-2/ + - https://drafts.csswg.org/css-flexbox/ sidebar: cssref --- @@ -54,6 +56,7 @@ body { - {{cssxref("flex-direction")}} - {{cssxref("flex-flow")}} - {{cssxref("flex-grow")}} +- {{cssxref("flex-line-count")}} - {{cssxref("flex-shrink")}} - {{cssxref("flex-wrap")}} - {{cssxref("justify-content")}} diff --git a/files/en-us/web/css/guides/flexible_box_layout/wrapping_items/index.md b/files/en-us/web/css/guides/flexible_box_layout/wrapping_items/index.md index 0da2456fa7e64d1..b0c0fd5f83b4bf3 100644 --- a/files/en-us/web/css/guides/flexible_box_layout/wrapping_items/index.md +++ b/files/en-us/web/css/guides/flexible_box_layout/wrapping_items/index.md @@ -121,6 +121,101 @@ Wrapping works as you might expect when combined with `flex-direction`. If `flex Note that the reversing is only happening in the inline, row direction. We start on the right then go onto the second line and again start from the right. We aren't reversing in both directions, starting from the bottom coming up the container! +## Balanced wrapping + +One potential issue with flexbox wrapping is that, by default, the flex items are not distributed evenly across the lines. In the previous example, we have three items on the first three lines, but only one on the last line. We can distribute the flex items more evenly across the four flex lines by including the [`balance`](/en-US/docs/Web/CSS/Reference/Properties/flex-wrap#balance) keyword within the `flex-wrap` value, alongside the `wrap` or `wrap-reverse` keyword. + +This example uses the same HTML as the previous example, and nearly the same CSS, except that the `flex-wrap` value has been changed from `wrap` to `wrap balance`. + +```html hidden live-sample___balanced-wrap live-sample___line-count +
+
One
+
Two
+
Three
+
Four
+
Five
+
Six
+
Seven
+
Eight
+
Nine
+
Ten
+
+``` + +```css hidden live-sample___balanced-wrap +.box { + border: 2px dotted rgb(96 139 168); + display: flex; + flex-wrap: wrap balance; + flex-direction: row-reverse; + width: 500px; +} +.box > * { + border: 2px solid rgb(96 139 168); + border-radius: 5px; + background-color: rgb(96 139 168 / 0.2); + flex: 1 1 160px; +} +``` + +```css hidden live-sample___balanced-wrap live-sample___line-count +@supports not (flex-wrap: balance) { + body::before { + content: "Your browser does not support flex-wrap: balance."; + background-color: wheat; + text-align: center; + padding: 1rem 0; + + z-index: 1; + position: fixed; + inset: 40% 0 auto; + } +} +``` + +```css +flex-wrap: wrap balance; +``` + +This line could also have been written as just `flex-wrap: balance`. If `balance` is specified as the only keyword in the `flex-wrap` value, the other keyword defaults to `wrap`. We wrote it out explicitly so it is clearer what is going on. Note that including the `balance` keyword with the `nowrap` value is invalid, and the declaration will be ignored. + +The updated rendering looks like so: + +{{EmbedLiveSample("balanced-wrap")}} + +Note how the items are now distributed more evenly, or "balanced," with two lines of three items and two lines of two items. + +If you want to distribute your balanced flex items across a greater number of lines, you can do so using the {{cssxref("flex-line-count")}} property. This specifies a minimum number of lines. If we add the following to the previous example: + +```css hidden live-sample___line-count +.box { + border: 2px dotted rgb(96 139 168); + display: flex; + flex-wrap: wrap balance; + flex-line-count: 5; + flex-direction: row-reverse; + width: 500px; +} +.box > * { + border: 2px solid rgb(96 139 168); + border-radius: 5px; + background-color: rgb(96 139 168 / 0.2); + flex: 1 1 160px; +} +``` + +```css +flex-line-count: 5; +``` + +We end up with the following: + +{{EmbedLiveSample("line-count")}} + +We now have five lines of two flex items. + +The `flex-line-count` property has no effect on flex-containers that do not have the `balance` keyword included in their `flex-wrap` property values. + ## Single-dimensional layout explained As we have seen from the above examples if our items are allowed to grow and shrink, when there are fewer items in the last row or column then those items grow to fill the available space. diff --git a/files/en-us/web/css/reference/properties/flex-flow/index.md b/files/en-us/web/css/reference/properties/flex-flow/index.md index 8f68c2ca67ac765..3a74129cae34803 100644 --- a/files/en-us/web/css/reference/properties/flex-flow/index.md +++ b/files/en-us/web/css/reference/properties/flex-flow/index.md @@ -19,6 +19,10 @@ flex-flow: row wrap; flex-flow: row-reverse nowrap; ``` +```css interactive-example-choice +flex-flow: row wrap balance; +``` + ```css interactive-example-choice flex-flow: column wrap-reverse; ``` @@ -27,6 +31,10 @@ flex-flow: column wrap-reverse; flex-flow: column wrap; ``` +```css interactive-example-choice +flex-flow: column balance wrap; +``` + ```html interactive-example
@@ -36,6 +44,7 @@ flex-flow: column wrap;
Item Four
Item Five
Item Six
+
Item Seven
``` @@ -52,7 +61,7 @@ flex-flow: column wrap; background-color: rgb(0 0 255 / 0.2); border: 3px solid blue; width: 60px; - margin: 10px; + margin: 5px 10px; } ``` @@ -76,11 +85,14 @@ flex-flow: column-reverse; flex-flow: nowrap; flex-flow: wrap; flex-flow: wrap-reverse; +flex-flow: wrap balance; +flex-flow: balance wrap-reverse; /* flex-flow: <'flex-direction'> and <'flex-wrap'> */ flex-flow: row nowrap; flex-flow: column wrap; flex-flow: column-reverse wrap-reverse; +flex-flow: row-reverse balance wrap /* Global values */ flex-flow: inherit; @@ -114,6 +126,14 @@ In this example, the main-axis is the block direction with a reversed main-start } ``` +To distribute the flex items evenly across each flex line, you can include the `flex-wrap` keyword [`balance`](/en-US/docs/Web/CSS/Reference/Properties/flex-wrap#balance) in addition to `wrap`: + +```css +.container { + flex-flow: column-reverse wrap balance; +} +``` + ## Specifications {{Specifications}} diff --git a/files/en-us/web/css/reference/properties/flex-line-count/index.md b/files/en-us/web/css/reference/properties/flex-line-count/index.md new file mode 100644 index 000000000000000..3060d4ffa2c0f8f --- /dev/null +++ b/files/en-us/web/css/reference/properties/flex-line-count/index.md @@ -0,0 +1,383 @@ +--- +title: "`flex-line-count` CSS property" +short-title: flex-line-count +slug: Web/CSS/Reference/Properties/flex-line-count +page-type: css-property +browser-compat: css.properties.flex-line-count +sidebar: cssref +--- + +The **`flex-line-count`** [CSS](/en-US/docs/Web/CSS) property sets the minimum number of flex lines that flex items will be balanced over in cases where a flex container's {{cssxref("flex-wrap")}} or {{cssxref("flex-flow")}} property includes the `balance` keyword. + +{{InteractiveExample("CSS Demo: flex-line-count")}} + +```css interactive-example-choice +flex-line-count: 1; +``` + +```css interactive-example-choice +flex-line-count: 3; +``` + +```css interactive-example-choice +flex-line-count: 4; +``` + +```html interactive-example +
+
+
Item One
+
Item Two
+
Item Three
+
Item Four
+
Item Five
+
Item Six
+
+
+``` + +```css interactive-example +#example-element { + border: 1px solid #c5c5c5; + width: 80%; + display: flex; + flex-wrap: wrap balance; +} + +#example-element > div { + background-color: rgb(0 0 255 / 0.2); + border: 3px solid blue; + width: 60px; + margin: 10px; +} +``` + +## Syntax + +```css +/* Integer values */ +flex-line-count: 1; +flex-line-count: 3; +flex-line-count: 12; + +/* Global values */ +flex-line-count: inherit; +flex-line-count: initial; +flex-line-count: revert; +flex-line-count: revert-layer; +flex-line-count: unset; +``` + +### Values + +This property is specified as the following value: + +- {{cssxref("integer")}} + - : A positive integer setting the minimum number of flex lines that balanced, wrapped flex items will be distributed over. The default value is `1`. + +## Description + +The `flex-line-count` property sets the minimum number of flex lines that flex items will be distributed over in wrapping, balanced flex containers — in other words, flex containers that include a {{cssxref("flex-wrap")}} or {{cssxref("flex-flow")}} property with the `balance` keyword set in addition to the `wrap` or `wrap-reverse` keyword. + +A key use case for `flex-line-count` is creating a balanced set of two (or more) columns, regardless of the number of items in a list. In such cases, setting an explicit {{cssxref("height")}} or {{cssxref("max-height")}} won't work as you don't know how much content you will have, and may end up with fewer or more columns than desired. See [Creating balanced columns](#creating_balanced_columns) for an example implementation. + +If `balance` is not set, or if flex items are not set to wrap onto multiple flex lines, the `flex-line-count` property has no effect. + +If the `flex-line-count` value is equal to or greater than the number of flex items, there will be one flex item per flex line. + +## Formal definition + +{{cssinfo}} + +## Formal syntax + +{{csssyntax}} + +## Examples + +### Effect of different `flex-line-count` values + +This example demonstrates the effects of different values of `flex-line-count` on four boxes. + +#### HTML + +We include four container {{htmlelement("div")}}s, each with a `class` of `box` and ten child `
`s; each container `
` has a different `id` value. + +```html +
+
One
+
Two
+
Three
+
Four
+
Five
+
Six
+
Seven
+
Eight
+
Nine
+
Ten
+
+ +
...
+
...
+
...
+``` + +```html hidden live-sample___flex-line-count +

No balance

+ +
+
One
+
Two
+
Three
+
Four
+
Five
+
Six
+
Seven
+
Eight
+
Nine
+
Ten
+
+ +

flex-line-count: 3

+ +
+
One
+
Two
+
Three
+
Four
+
Five
+
Six
+
Seven
+
Eight
+
Nine
+
Ten
+
+ +

flex-line-count: 4

+ +
+
One
+
Two
+
Three
+
Four
+
Five
+
Six
+
Seven
+
Eight
+
Nine
+
Ten
+
+ +

flex-line-count: 5

+ +
+
One
+
Two
+
Three
+
Four
+
Five
+
Six
+
Seven
+
Eight
+
Nine
+
Ten
+
+``` + +#### CSS + +```css hidden live-sample___flex-line-count +* { + box-sizing: border-box; +} + +.box { + width: 100%; + border: 2px dotted gray; + margin-bottom: 20px; + gap: 10px; +} + +.box > * { + border: 2px solid rgb(96 139 168); + border-radius: 5px; + background-color: lightgray; +} +``` + +We apply `display: flex` to all the boxes to make them flex containers, then give them a `flex-wrap` value of `wrap balance` to make all their flex children wrap onto multiple, balanced lines. + +```css live-sample___flex-line-count +.box { + display: flex; + flex-wrap: wrap balance; +} +``` + +We also set a {{cssxref("flex")}} value of `1 1 150px` on the flex children, so they have a base width of `150px` and will distribute any excess space evenly across the items in each flex line. + +```css live-sample___flex-line-count +.box > * { + flex: 1 1 150px; +} +``` + +For the `#box-no-balance` flex container, we remove the balancing, thereby nullifying the line count, by overriding the original `flex-wrap: wrap balance` value with `wrap`. We apply different `flex-line-count` values to each flex container, incrementing them so their children are laid out over a progressively greater number of flex lines. + +```css live-sample___flex-line-count +#box-no-balance { + flex-line-count: 6; + flex-wrap: wrap; +} + +#box1 { + flex-line-count: 3; +} + +#box2 { + flex-line-count: 4; +} + +#box3 { + flex-line-count: 5; +} +``` + +We've hidden the rest of the CSS for brevity. + +#### Results + +{{ EmbedLiveSample("flex-line-count", "100%", "700") }} + +Note the following: + +- As the first flex container doesn't have the `balance` keyword set in its `flex-wrap` value, its children are not given a balanced distribution and its `flex-line-count` value is ignored. +- The second flex container's `flex-line-count: 3` declaration doesn't effect the layout of the flex children; as the flex items are by default distributed over four flex lines, any value of `4` or less has no effect. + +### Creating balanced columns + +This example demonstrates how `flex-line-count` can be used to create a balanced set of two columns. + +#### HTML + +We include an {{htmlelement("ol")}} element containing ten {{htmlelement("li")}} elements. + +```html +
    +
  1. + The Silent Cartographer, published by Meridian House, + released March 12, 2014. +
  2. +
  3. + Echoes of the Fallow Field, published by Northbridge Press, + released July 4, 2009. +
  4. + + ... +
+``` + +```html hidden live-sample___balanced-columns +
    +
  1. + The Silent Cartographer, published by Meridian House, + released March 12, 2014. +
  2. +
  3. + Echoes of the Fallow Field, published by Northbridge Press, + released July 4, 2009. +
  4. +
  5. + A Ledger of Small Regrets, published by Ashwood & Kline, + released November 21, 2017. +
  6. +
  7. + The Clockmaker's Daughter's Shadow, published by Hollow Pine + Publishing, released February 8, 2011. +
  8. +
  9. + Salt and Signal, published by Redcliffe Editions, released + September 30, 2019. +
  10. +
  11. + Under a Borrowed Sky, published by Fenwick & Marsh, released + May 16, 2006. +
  12. +
  13. + The Last Cartel of Winter, published by Graywolf Bindery, + released January 2, 2021. +
  14. +
  15. + Notes from an Unfinished Atlas, published by Coastline + Books, released June 27, 2013. +
  16. +
  17. + The Weight of Empty Rooms, published by Draymoor House, + released October 15, 2008. +
  18. +
  19. + A Brief History of Almost Everyone, published by Ferngate + Press, released April 9, 2022. +
  20. +
+``` + +#### CSS + +We set the list's {{cssxref("display")}} to `flex`. We set a {{cssxref("flex-direction")}} value of `column`and a {{cssxref("flex-wrap")}} value of `balance` using the {{cssxref("flex-flow")}} shorthand so that the flex lines are arranged in columns and will balance when wrapped. The {{cssxref("gap")}} value `10px 40px` specifies a gap of `10px` between flex items within each column and `40px` between flex lines. + +Finally, we set a `flex-line-count` value of `2`, meaning that, even though no fixed height is set on the list, its content will always be wrapped over two balanced columns, regardless of how much content is included. + +```css live-sample___balanced-columns +ol { + display: flex; + gap: 10px 40px; + flex-flow: column balance; + flex-line-count: 2; +} +``` + +```css hidden live-sample___flex-line-count live-sample___balanced-columns +* { + box-sizing: border-box; +} + +body { + padding: 10px 30px; +} + +@supports not (flex-line-count: 3) { + body::before { + content: "Your browser does not support the flex-line-count property."; + background-color: wheat; + text-align: center; + padding: 1rem 0; + + z-index: 1; + position: fixed; + inset: 40% 0 auto; + } +} +``` + +We've hidden the rest of the CSS for brevity. + +#### Results + +{{ EmbedLiveSample("balanced-columns", "100%", "350") }} + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{CSSXRef("flex-wrap")}} +- {{CSSXRef("flex-flow")}} shorthand +- [Basic concepts of flexbox](/en-US/docs/Web/CSS/Guides/Flexible_box_layout/Basic_concepts) +- [Mastering wrapping of flex items > Balanced wrapping](/en-US/docs/Web/CSS/Guides/Flexible_box_layout/Wrapping_items#balanced_wrapping) +- [CSS flexible box layout](/en-US/docs/Web/CSS/Guides/Flexible_box_layout) module diff --git a/files/en-us/web/css/reference/properties/flex-wrap/index.md b/files/en-us/web/css/reference/properties/flex-wrap/index.md index e6a95a6506834b9..52d95b3000df926 100644 --- a/files/en-us/web/css/reference/properties/flex-wrap/index.md +++ b/files/en-us/web/css/reference/properties/flex-wrap/index.md @@ -23,6 +23,10 @@ flex-wrap: wrap; flex-wrap: wrap-reverse; ``` +```css interactive-example-choice +flex-wrap: wrap balance; +``` + ```html interactive-example
@@ -32,6 +36,7 @@ flex-wrap: wrap-reverse;
Item Four
Item Five
Item Six
+
Item Seven
``` @@ -56,9 +61,13 @@ The {{cssxref("flex-flow")}} property shorthand can be used to set both the {{CS ## Syntax ```css -flex-wrap: nowrap; /* Default value */ +/* Keyword values */ +flex-wrap: nowrap; flex-wrap: wrap; flex-wrap: wrap-reverse; +flex-wrap: balance; +flex-wrap: wrap balance; +flex-wrap: balance wrap-reverse; /* Global values */ flex-wrap: inherit; @@ -70,14 +79,36 @@ flex-wrap: unset; ### Values -The `flex-wrap` property is specified as a single keyword chosen from the following values below: +This property is specified as a single value from the following list or as two space-separated values when using `balance`: - `nowrap` - - : The flex items are laid out in a single line which may cause the flex container to overflow. The cross-start is the equivalent of [inline-start or block-start](/en-US/docs/Glossary/Flow_relative_values), depending on the {{cssxref("flex-direction")}} value. This is the default value. + - : The flex items are laid out in a single line which may cause the flex container to overflow. This is the initial value. - `wrap` - - : The flex items break into multiple lines. The cross-start is the equivalent of [inline-start or block-start](/en-US/docs/Glossary/Flow_relative_values), depending on the current [writing mode](/en-US/docs/Web/CSS/Guides/Writing_modes), and the {{cssxref("flex-direction")}} value. + - : The flex items can break into multiple lines. - `wrap-reverse` - - : Behaves the same as `wrap`, but cross-start and cross-end are inverted. + - : Behaves the same as `wrap`, but with the lines laid out in reverse order. +- `balance` + - : Specifies that flex items broken across multiple lines are distributed so that the line lengths are as similar as possible. If `balance` is specified as the only keyword, the other keyword defaults to `wrap`. + +## Description + +The `flex-wrap` property is used to specify whether the flex container's child flex items may wrap onto multiple flex lines or not and, if set to wrap, whether the children should be evenly distributed across flex lines. + +The initial value of `nowrap` specifies that all items should be laid out on a single flex line, which means they may overflow the container. The `wrap` and `wrap-reverse` keywords prevent overflow by specifying that flex items can flow, or wrap, across multiple lines. + +With `wrap`, cross-start is the equivalent of [inline-start or block-start](/en-US/docs/Glossary/Flow_relative_values), depending on the {{cssxref("flex-direction")}} value and the current [writing mode](/en-US/docs/Web/CSS/Guides/Writing_modes). With `wrap-reverse`, cross-start is the equivalent of inline-end or block-end. + +### Balancing flex item distribution + +By default, when `wrap` or `wrap-reverse` is specified, each flex line is filled with flex items before items are wrapped onto the next line. This can result in an uneven distribution of items, with the last flex line composed of fewer items. If those items' {{cssxref("flex-grow")}} values are non-zero, the extra available space is distributed across these fewer items, making them much larger than the items on filled flex lines. + +The `balance` keyword can be used to distribute the items across lines in a more even manner. Optionally, the {{cssxref("flex-line-count")}} property can be used to define the minimum number of lines across which the balanced items should be distributed. + +If `balance` is the only keyword specified, the other keyword defaults to `wrap`. + +A balanced wrapping flex container can have a {{cssxref("flex-line-count")}} value applied to specify the minimum number of lines the flex items should be distributed over. The `flex-line-count` property has no effect if `balance` is not specified inside `flex-wrap`. + +If `balance` is specified alongside `nowrap`, the property is invalid. ## Formal definition @@ -93,7 +124,7 @@ The `flex-wrap` property is specified as a single keyword chosen from the follow #### HTML -```html +```html live-sample___flex-wrap-values

This is an example for flex-wrap:wrap

1
@@ -116,7 +147,7 @@ The `flex-wrap` property is specified as a single keyword chosen from the follow #### CSS -```css +```css live-sample___flex-wrap-values /* Common Styles */ .content, .content1, @@ -161,7 +192,176 @@ The `flex-wrap` property is specified as a single keyword chosen from the follow #### Results -{{ EmbedLiveSample('Setting flex container wrap values', '', '700') }} +{{ EmbedLiveSample("flex-wrap-values", "100%", "700") }} + +### Demonstrating the `balance` keyword + +This example demonstrates the effects of the `balance` keyword within the `flex-wrap` property and different `flex-line-count` values. + +#### HTML + +```html hidden live-sample___the-balance-keyword +
+
+ + +
+
+ + +
+
+ + + 3 +
+
+ +
+ +

Currently set: flex-wrap: wrap; flex-line-count: 3;

+ +
+``` + +We include a container {{htmlelement("div")}} with a `class` of `box`, which has ten child `
`s. + +```html live-sample___the-balance-keyword +
+
One
+
Two
+
Three
+
Four
+
Five
+
Six
+
Seven
+
Eight
+
Nine
+
Ten
+
+``` + +We also include controls to enable changing features of the flex container, including: + +- Toggling `flex-wrap` between the `wrap` and `wrap-reverse` values. +- Toggling the `balance` keyword on and off. +- Changing the `flex-line-count` value. + +We've hidden the HTML and JavaScript for brevity. + +#### CSS + +We apply `display: flex` to the `.box` to turn it into a flex container, then set some `flex-wrap` and `flex-line-count` values to make the flex children wrap evenly over a minimum of three flex lines. You can change the values in the live demo. We also set a {{cssxref("flex")}} value of `1 1 150px` on the flex children so they will have a base width of `150px`, with any remaining space distributed evenly between items on the same flex line. + +```css live-sample___the-balance-keyword +.box { + display: flex; + flex-wrap: wrap balance; + flex-line-count: 3; +} + +.box > * { + flex: 1 1 150px; +} +``` + +```css hidden live-sample___the-balance-keyword +.box { + width: 100%; + border: 2px dotted rgb(96 139 168); + gap: 10px; +} + +.box > * { + border: 2px solid rgb(96 139 168); + border-radius: 5px; + background-color: rgb(96 139 168 / 0.2); +} + +* { + box-sizing: border-box; +} + +body { + padding: 10px 30px; +} + +@supports not (flex-wrap: balance) { + body::before { + content: "Your browser does not support flex-wrap: balance."; + background-color: wheat; + text-align: center; + padding: 1rem 0; + + z-index: 1; + position: fixed; + inset: 40% 0 auto; + } +} +``` + +We've hidden the rest of the CSS for brevity. + +```js hidden live-sample___the-balance-keyword +const boxElem = document.querySelector(".box"); +const outputElem = document.querySelector("output"); +const pCodeElem = document.querySelector("p code"); +const reverseInput = document.getElementById("reverse"); +const balanceInput = document.getElementById("balance"); +const lineCountInput = document.getElementById("line-count"); + +let wrapValue = "wrap"; +let lineCountValue = "3"; + +function updateCurrentlySet() { + pCodeElem.textContent = `flex-wrap: ${wrapValue}; flex-line-count: ${lineCountValue};`; +} + +function setFlexWrap() { + wrapValue = ""; + if (reverseInput.checked) { + wrapValue += "wrap-reverse"; + } else { + wrapValue += "wrap"; + } + + if (balanceInput.checked) { + wrapValue += " balance"; + } + + boxElem.style.flexWrap = wrapValue; + updateCurrentlySet(); +} + +function setFlexLineCount() { + lineCountValue = lineCountInput.value; + boxElem.style.flexLineCount = lineCountValue; + outputElem.textContent = lineCountValue; + updateCurrentlySet(); +} + +reverseInput.addEventListener("change", setFlexWrap); +balanceInput.addEventListener("change", setFlexWrap); +lineCountInput.addEventListener("input", setFlexLineCount); +``` + +#### Results + +{{ EmbedLiveSample("the-balance-keyword", "100%", "400") }} + +Change the form control settings to see how they affect the output. Note how: + +- Toggling between `wrap` and `wrap-reverse` changes the direction in which the flex lines are laid out along the cross-axis. +- Setting `balance` causes the flex items to be evenly distributed across the available flex lines. +- Changing the `flex-line-count` value changes the minimum number of lines the items will be distributed across. The `flex-line-count` property, and therefore the slider, has no effect unless `balance` is checked. +- As the flex items are distributed over four flex lines by default, changing the `flex-line-count` to a value of less than `5` has no effect. Values from `5` to `10` add an extra flex line. +- As there are 10 flex items, `flex-line-count` values of `10` or greater will all have the same effect — one item will be placed on each of 10 flex lines. ## Specifications From 65de0b20f182edef16b58da2df80112b39787a04 Mon Sep 17 00:00:00 2001 From: Estelle Weyl Date: Tue, 18 Aug 2026 12:52:21 -0700 Subject: [PATCH 4/4] New pages: rule-break properties (#45095) * New pages: rule-break properties * edits per review * move slider for column to prevent bounce * move slider for column to prevent bounce * relevant rule is darker rule * edits per review (first half) * Apply suggestions from code review Co-authored-by: Chris Mills * edits per review (third half) * Apply suggestions from code review Co-authored-by: Chris Mills * Update files/en-us/web/css/reference/properties/rule-break/index.md * Update files/en-us/web/css/reference/properties/rule-break/index.md --------- Co-authored-by: Chris Mills --- .../properties/column-rule-break/index.md | 510 ++++++++++++++++++ .../properties/row-rule-break/index.md | 506 +++++++++++++++++ .../reference/properties/rule-break/index.md | 483 +++++++++++++++++ 3 files changed, 1499 insertions(+) create mode 100644 files/en-us/web/css/reference/properties/column-rule-break/index.md create mode 100644 files/en-us/web/css/reference/properties/row-rule-break/index.md create mode 100644 files/en-us/web/css/reference/properties/rule-break/index.md diff --git a/files/en-us/web/css/reference/properties/column-rule-break/index.md b/files/en-us/web/css/reference/properties/column-rule-break/index.md new file mode 100644 index 000000000000000..e762af84c46ee61 --- /dev/null +++ b/files/en-us/web/css/reference/properties/column-rule-break/index.md @@ -0,0 +1,510 @@ +--- +title: "`column-rule-break` CSS property" +short-title: column-rule-break +slug: Web/CSS/Reference/Properties/column-rule-break +page-type: css-property +status: + - experimental +browser-compat: css.properties.column-rule-break +sidebar: cssref +--- + +{{SeeCompatTable}} + +The **`column-rule-break`** [CSS](/en-US/docs/Web/CSS) property sets the behavior for breaking column rules into segments wherever column rules intersect row gaps. + +{{InteractiveExample("CSS Demo: rule")}} + +```css interactive-example-choice +column-rule-break: none; +``` + +```css interactive-example-choice +column-rule-break: normal; +``` + +```css interactive-example-choice +column-rule-break: intersection; +``` + +```html interactive-example +
+
+ A + B + C + D + E + F + G + H + I + J + K + L + M + N + O + P + Q + R + S + T + U + V + W + X + Y + Z +
+
+``` + +```css interactive-example +#example-element { + display: grid; + grid-template-columns: repeat(7, 1fr); + column-rule: solid thick orange; + row-rule: solid thick lavender; + gap: 15px; + rule-overlap: column-over-row; +} +#example-element i { + padding: 5px; +} +``` + +## Syntax + +```css +/* Keywords */ +column-rule-break: none; +column-rule-break: normal; +column-rule-break: intersection; + +/* Global values */ +column-rule-break: inherit; +column-rule-break: initial; +column-rule-break: revert; +column-rule-break: revert-layer; +column-rule-break: unset; +``` + +### Values + +This property is specified as a single keyword from the following list: + +- `none` + - : There are no breaks in column rules when they intersect row gaps; rather, a continuous column rule is painted the whole height of the container, from edge to edge. +- `normal` + - : In grid and flex containers, behaves as `none`. In multi-col, behaves as `intersection`. This is the default value. +- `intersection` + - : Column rules always break when they intersect row gaps, with column rule segments starting and ending at container and gap edges. + +## Description + +The `column-rule-break` property specifies whether or not to break column rules into segments when they cross row gaps. + +Column rules are painted within a column gap as one or more segments, with segments occurring between adjacent grid items in separate columns, between flex items or flex lines in flex layouts depending on the `flex-direction`, or between columns in multi-col layouts. + +The `column-rule-break` property only determines if the break occurs. By default, the break between column rule segments is the height of the row gap, as each segment starts and ends at the edge of the gap (or edge of the container). If the row gap is `0`, this break may not be visible. The end positions can be controlled with the {{cssxref("column-rule-inset")}} properties. + +If `column-rule-break` is set to `none`, there are no breaks. In this case, the column rule line is continuous, and any `column-rule-inset` values only affect the left and right edges of the column rule at the container's edge. When there are breaks, the `column-rule-inset` properties affect the start and end of every column rule segment. + +The `column-rule-break` property, along with the {{cssxref("row-rule-break")}} property, can be set using the {{cssxref("rule-break")}} shorthand. + +Whether a column rule is by default composed of a single continuous segment or segments that break when intersecting row gaps depends on the container type. + +### Grid containers + +In grid containers, by default, column rule segments continue through row gap intersections, equivalent to `column-rule-break: none`. Setting `column-rule-break: intersection` forces the segments to break at every row gap they would otherwise cross. + +```html hidden +

Default rule breaks in grid

+
+
+
+
+
+
+
+
+
+

+ +

+``` + +```css hidden +body { + font-family: sans-serif; + text-align: center; +} +h1 { + font-size: 1.25em; +} +h2 { + font-size: 1em; +} + +:has(:checked) .grid { + column-rule-break: intersection; +} +.grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 20px; + rule: 5px solid blue; + row-rule-color: lightblue; + rule-overlap: column-over-row; + width: 100%; +} + +.grid > div { + border: 1px solid green; + background-color: lime; + height: 30px; +} +``` + +{{EmbedLiveSample("grid containers", "", "240")}} + +By default, there are no column rule breaks. Check the checkbox to set the `column-rule-break` to `intersection`, which makes the otherwise continuous rules break at every "cross" intersection. By default, the break between segments is the height of the {{cssxref("row-gap")}}, which was set to `20px` in this case. + +### Flex containers + +In flexbox, whether the column rules break at every row gap by default depends on the `flex-direction`. In horizontal writing modes, when set to `row` or `row-reverse`, the column rule breaks at every row gap, equivalent to `column-rule-break: intersection`. When the `flex-direction` is `column` or `column-reverse`, the column rule is continuous by default, equivalent to `column-rule-break: none`. + +```html hidden +

Default rule breaks in flexbox

+
+
+

flex-direction: row

+
+
+
+
+
+
+
+
+
+
+
+

flex-direction: column

+
+
+
+
+
+
+
+
+
+
+
+

+ +

+``` + +```css hidden +body { + font-family: sans-serif; + text-align: center; +} +h1 { + font-size: 1.25em; +} +h2 { + font-size: 1em; +} + +:has(:checked) .flexbox { + column-rule-break: intersection; +} +article { + display: flex; + gap: 5vw; + rule: 1px solid black; + width: 100vw; +} +section { + flex-basis: 45vw; +} +.flexbox { + display: flex; + flex-flow: balance; + flex-line-count: 3; + gap: 20px; + rule: 5px solid blue; + row-rule-color: lightblue; + width: 100%; +} +.column { + flex-flow: column balance; + gap: 20px; +} + +.flexbox > div { + border: 1px solid green; + background-color: lime; + flex: 1 1 auto; + height: 30px; +} +``` + +{{EmbedLiveSample("Flex containers", "", "300")}} + +In horizontal wrting modes, setting the `column-rule-break` to `intersection` only impacts the column rules in the `column` and `column-reverse` scenarios. + +### Multi-col containers + +In multi-col containers, the default `normal` value behaves the same as `intersection`. While the row decorations are continuous by default, column rules break at every intersection. Column rules break into segments at every row gap, with each segment starting and ending at the edge of the gap. These start and end positions can be changed with the `column-rule-inset` properties. + +```html hidden +

Default rule breaks in multi-col

+
    +
  1. One fish
  2. +
  3. Two fish
  4. +
  5. Red fish
  6. +
  7. Blue fish
  8. +
  9. Black fish
  10. +
  11. Blue fish
  12. +
  13. Old fish
  14. +
  15. New fish.
  16. +
  17. This one has a little star.
  18. +
  19. This one has a little car.
  20. +
  21. Say! What a lot
  22. +
  23. Of fish there are.
  24. +
  25. Yes. Some are blue.
  26. +
  27. And some are blue.
  28. +
  29. Some are old.
  30. +
  31. And some are new.
  32. +
  33. Some are sad.
  34. +
  35. And some are glad.
  36. +
  37. And some are very, very bad.
  38. +
  39. Why are they
  40. +
  41. Sad and glad and bad?
  42. +
  43. I do not know.
  44. +
  45. Go ask your dad.
  46. +
+
+ Set column-rule-break: + + + +
+``` + +```css hidden +body { + font-family: sans-serif; + text-align: center; +} +h1 { + font-size: 1.25em; +} +h2 { + font-size: 1em; +} +ol { + columns: 3 / 4em; + gap: 20px; + rule: 5px solid blue; + row-rule-color: lightblue; + rule-overlap: column-over-row; +} +li { + border: 1px solid green; + background-color: lime; + list-style-type: none; + margin-bottom: 5px; +} +:has([value="normal"]:checked) ol { + column-rule-break: normal; +} +:has([value="intersection"]:checked) ol { + column-rule-break: intersection; +} +:has([value="none"]:checked) ol { + column-rule-break: none; +} +label { + margin-right: 20px; +} +``` + +{{EmbedLiveSample("multi-col containers", "", "540")}} + +If you select `none`, the column rule will no longer break into segments; rather, it will continue from the top of the container, until it reaches the bottom edge. The `column-rule-inset` properties can be used to offset the ends of the column gap decorations. + +## Formal definition + +{{cssinfo}} + +## Formal syntax + +{{csssyntax}} + +## Examples + +### Basic usage + +In this example, we use the `column-rule-break` property to break each rule segment in a grid container so column rule segments are created between row gaps. Changing the `row-gap` property will change the size of the segments. + +#### HTML + +We create a list of 50 items and a slider to select the row gap width. Most of the HTML is hidden for brevity. + +```html +
    +
  • 1
  • +
  • 2
  • + ... +
  • 49
  • +
  • 50
  • +
+``` + +```html hidden live-sample___basic +

+ + +

+
    +
  • 1
  • +
  • 2
  • +
  • 3
  • +
  • 5
  • +
  • 6
  • +
  • 7
  • +
  • 8
  • +
  • 9
  • +
  • 10
  • +
  • 11
  • +
  • 12
  • +
  • 13
  • +
  • 14
  • +
  • 15
  • +
  • 16
  • +
  • 17
  • +
  • 18
  • +
  • 19
  • +
  • 20
  • +
  • 21
  • +
  • 22
  • +
  • 23
  • +
  • 24
  • +
  • 25
  • +
  • 26
  • +
  • 27
  • +
  • 28
  • +
  • 29
  • +
  • 30
  • +
  • 31
  • +
  • 32
  • +
  • 33
  • +
  • 34
  • +
  • 35
  • +
  • 36
  • +
  • 37
  • +
  • 38
  • +
  • 39
  • +
  • 40
  • +
  • 41
  • +
  • 42
  • +
  • 43
  • +
  • 44
  • +
  • 45
  • +
  • 46
  • +
  • 47
  • +
  • 48
  • +
  • 49
  • +
  • 50
  • +
+``` + +#### CSS + +We define the unordered list as a 8-column container, creating rows and columns with the {{cssxref("grid-template-columns")}} property and setting {{cssxref("list-style-type")}} to `none` to remove the bullets. We include a {{cssxref("gap")}} of `20px` to provide enough room between the rows and columns to fit our `20px` solid row and column rules. We include the {{cssxref("rule-overlap")}} property to paint the column decoration on top of any row decorations. Last, we set the column rules to break at every intersection. + +```css live-sample___basic +ul { + display: grid; + grid-template-columns: repeat(8, 1fr); + list-style-type: none; + gap: 20px; + + column-rule: 10px solid olive; + row-rule: 10px solid palegoldenrod; + rule-overlap: column-over-row; + + column-rule-break: intersection; +} +``` + +The rest of the CSS is hidden for brevity. + +```css hidden live-sample___basic +ol { + place-items: center; + width: 95vw; +} +li { + text-align: center; + font-family: sans-serif; + line-height: 50px; +} +``` + +```js hidden live-sample___basic +const gap = document.getElementById("gap"); +const ul = document.getElementById("ul"); +const output = document.getElementById("o"); + +gap.addEventListener("input", () => { + o.innerText = ul.style.rowGap = `${gap.value}px`; +}); +``` + +#### Result + +{{EmbedLiveSample("Basic", "", "600")}} + +Make the row gaps wider and note how the breaks between column segments grow. Bring the row gap width down to `0px`, and notice how the column decoration appears continuous. It isn't! The `0px` gap between segments may not be visible, but the segments still start and end at the gap, so any offsets set with `column-rule-inset` properties will still be applied. + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{cssxref("row-rule-break")}} +- {{cssxref("rule-break")}} shorthand +- {{cssxref("rule-inset")}} shorthand +- {{cssxref("rule-overlap")}} +- {{cssxref("rule-visibility-items")}} +- {{cssxref("rule")}} shorthand +- [CSS gaps](/en-US/docs/Web/CSS/Guides/Gaps) module diff --git a/files/en-us/web/css/reference/properties/row-rule-break/index.md b/files/en-us/web/css/reference/properties/row-rule-break/index.md new file mode 100644 index 000000000000000..5d4fe021e72d510 --- /dev/null +++ b/files/en-us/web/css/reference/properties/row-rule-break/index.md @@ -0,0 +1,506 @@ +--- +title: "`row-rule-break` CSS property" +short-title: row-rule-break +slug: Web/CSS/Reference/Properties/row-rule-break +page-type: css-property +status: + - experimental +browser-compat: css.properties.row-rule-break +sidebar: cssref +--- + +{{SeeCompatTable}} + +The **`row-rule-break`** [CSS](/en-US/docs/Web/CSS) property sets the behavior for breaking row rules into segments where row rules intersect column gaps. + +{{InteractiveExample("CSS Demo: rule")}} + +```css interactive-example-choice +row-rule-break: none; +``` + +```css interactive-example-choice +row-rule-break: normal; +``` + +```css interactive-example-choice +row-rule-break: intersection; +``` + +```html interactive-example +
+
+ A + B + C + D + E + F + G + H + I + J + K + L + M + N + O + P + Q + R + S + T + U + V + W + X + Y + Z +
+
+``` + +```css interactive-example +#example-element { + display: grid; + grid-template-columns: repeat(7, 1fr); + row-rule: solid thick orange; + column-rule: solid thick lavender; + gap: 15px; +} +#example-element i { + padding: 5px; +} +``` + +## Syntax + +```css +/* Keywords */ +row-rule-break: none; +row-rule-break: normal; +row-rule-break: intersection; + +/* Global values */ +row-rule-break: inherit; +row-rule-break: initial; +row-rule-break: revert; +row-rule-break: revert-layer; +row-rule-break: unset; +``` + +### Values + +This property is specified as a single keyword from the following list: + +- `none` + - : There are no breaks in row rules when they intersect column gaps; rather, a continuous row rule is painted the whole width of the container, from edge to edge. +- `normal` + - : In grid and flex containers, behaves as `none`. In multi-col, behaves as `none`. This is the default value. +- `intersection` + - : Row rules always break when they intersect column gaps, with row rule segments starting and ending at container and gap edges. + +## Description + +The `row-rule-break` property specifies whether or not to break row rules into segments when they cross column gaps. + +Row rules are painted within a row gap as one or more segments, with segments occurring between adjacent grid items in separate rows, between flex items or flex lines, depending on the {{cssxref("flex-direction")}} in flex layouts, or in gaps between adjacent rows of columns in multi-col layouts when {{cssxref("column-height")}} creates multiple rows of columns. + +The `row-rule-break` property only determines if the break occurs. By default, the break, or space, between row rule segments is the width of the column gap, as each segments starts and ends at the edge of the gap (or edge of the container). If the gap is `0`, this break may not be visible. The end positions can be controlled with the {{cssxref("row-rule-inset")}} properties. + +If `row-rule-break` is set to `none`, there are no breaks, the row rule line is continuous, and any `row-rule-inset` values only affect the row rule on the left and right edge of the container. When there are breaks, the `row-rule-inset` properties affect the start and end of every row rule segment. + +The `row-rule-break` property, along with the {{cssxref("column-rule-break")}} property, can be set using the {{cssxref("rule-break")}} shorthand. + +Whether a row rule is by default composed of a single continuous segment or segments that break when intersecting column gaps depends on the container type. + +### Grid containers + +In grid containers, by default, row rule segments continue through visible "cross" intersections. Setting `row-rule-break: intersection` will force the segments to break at every column gap, where they would otherwise cross. + +```html hidden +

Default rule breaks in grid

+
+
+
+
+
+
+
+
+
+

+ +

+``` + +```css hidden +body { + font-family: sans-serif; + text-align: center; +} +h1 { + font-size: 1.25em; +} +h2 { + font-size: 1em; +} + +:has(:checked) .grid { + row-rule-break: intersection; +} +.grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 20px; + rule: 5px solid blue; + column-rule-color: lightblue; + width: 100%; +} + +.grid > div { + border: 1px solid green; + background-color: lime; + height: 30px; +} +``` + +{{EmbedLiveSample("grid containers", "", "240")}} + +By default, there are no row rule breaks. Check the checkbox to set `ow-rule-break` to `intersection`, which makes the continuous rules break at every "cross" intersection. By default, the break between segments is the width of the {{cssxref("column-gap")}}. + +### Flex containers + +In flexbox, when the `flex-direction` is `row` or `row-reverse` in horizontal writing modes, the row rule is continuous, with the column segments starting and ending at the at the edge of the row gaps. When the `flex-direction` is `column` or `column-reverse`, the column rule is continuous, with the row segments starting and ending at the at the edge of the column gaps. + +```html hidden +

Default rule breaks in flexbox

+
+
+

flex-direction: row

+
+
+
+
+
+
+
+
+
+
+
+

flex-direction: column

+
+
+
+
+
+
+
+
+
+
+
+

+ +

+``` + +```css hidden +body { + font-family: sans-serif; + text-align: center; +} +h1 { + font-size: 1.25em; +} +h2 { + font-size: 1em; +} + +:has(:checked) .flexbox { + row-rule-break: intersection; +} +article { + display: flex; + gap: 5vw; + rule: 1px solid black; + width: 100vw; +} +section { + flex-basis: 45vw; +} +.flexbox { + display: flex; + flex-flow: balance; + flex-line-count: 3; + gap: 20px; + rule: 5px solid blue; + column-rule-color: lightblue; + width: 100%; +} +.column { + flex-flow: column balance; + gap: 20px; +} + +.flexbox > div { + border: 1px solid green; + background-color: lime; + flex: 1 1 auto; + height: 30px; +} +``` + +{{EmbedLiveSample("Flex containers", "", "300")}} + +In horizontal writing modes, when set to `row` or `row-reverse`, the row rule is continuous by default, where as with `column` or `column-reverse`, the row rule breaks at every column gap. Setting the `row-rule-break` to `intersection` only impacts the row rules in the `row` and `row-reverse` scenarios. + +### Multi-col containers + +In multi-col containers, the default `normal` behavior behaves the same as `none`. + +```html hidden +

Default rule breaks in multi-col

+
    +
  1. One fish
  2. +
  3. Two fish
  4. +
  5. Red fish
  6. +
  7. Blue fish
  8. +
  9. Black fish
  10. +
  11. Blue fish
  12. +
  13. Old fish
  14. +
  15. New fish.
  16. +
  17. This one has a little star.
  18. +
  19. This one has a little car.
  20. +
  21. Say! What a lot
  22. +
  23. Of fish there are.
  24. +
  25. Yes. Some are blue.
  26. +
  27. And some are blue.
  28. +
  29. Some are old.
  30. +
  31. And some are new.
  32. +
  33. Some are sad.
  34. +
  35. And some are glad.
  36. +
  37. And some are very, very bad.
  38. +
  39. Why are they
  40. +
  41. Sad and glad and bad?
  42. +
  43. I do not know.
  44. +
  45. Go ask your dad.
  46. +
+
+ Set row-rule-break: + + + +
+``` + +```css hidden +body { + font-family: sans-serif; + text-align: center; +} +h1 { + font-size: 1.25em; +} +h2 { + font-size: 1em; +} +ol { + columns: 3 / 4em; + gap: 20px; + rule: 5px solid blue; + column-rule-color: lightblue; +} +li { + border: 1px solid green; + background-color: lime; + list-style-type: none; + margin-bottom: 5px; +} +:has([value="normal"]:checked) ol { + row-rule-break: normal; +} +:has([value="intersection"]:checked) ol { + row-rule-break: intersection; +} +:has([value="none"]:checked) ol { + row-rule-break: none; +} +label { + margin-right: 20px; +} +``` + +{{EmbedLiveSample("multi-col containers", "", "540")}} + +If you select `intersection`, the row rule will break into segments whenever it reaches a column gap, with each segment starting and ending at the edge of the gap. The start and end positions can be changed with the `row-rule-inset` properties. + +## Formal definition + +{{cssinfo}} + +## Formal syntax + +{{csssyntax}} + +## Examples + +### Basic usage + +In this example, we use the `row-rule-break` property to break each rule segment in a grid container so row rule segments are created between column gaps. Changing the `column-gap` property will change the size of the segments. + +#### HTML + +We create a list of 50 items and a slider to change the column gap width. Most of the HTML is hidden for brevity. + +```html +
    +
  • 1
  • +
  • 2
  • + ... +
  • 49
  • +
  • 50
  • +
+``` + +```html hidden live-sample___basic +

+ + +

+
    +
  • 1
  • +
  • 2
  • +
  • 3
  • +
  • 5
  • +
  • 6
  • +
  • 7
  • +
  • 8
  • +
  • 9
  • +
  • 10
  • +
  • 11
  • +
  • 12
  • +
  • 13
  • +
  • 14
  • +
  • 15
  • +
  • 16
  • +
  • 17
  • +
  • 18
  • +
  • 19
  • +
  • 20
  • +
  • 21
  • +
  • 22
  • +
  • 23
  • +
  • 24
  • +
  • 25
  • +
  • 26
  • +
  • 27
  • +
  • 28
  • +
  • 29
  • +
  • 30
  • +
  • 31
  • +
  • 32
  • +
  • 33
  • +
  • 34
  • +
  • 35
  • +
  • 36
  • +
  • 37
  • +
  • 38
  • +
  • 39
  • +
  • 40
  • +
  • 41
  • +
  • 42
  • +
  • 43
  • +
  • 44
  • +
  • 45
  • +
  • 46
  • +
  • 47
  • +
  • 48
  • +
  • 49
  • +
  • 50
  • +
+``` + +#### CSS + +We define the unordered list as a 8-column container, creating columns and rows with the {{cssxref("grid-template-columns")}} property and setting {{cssxref("list-style-type")}} to `none` to remove the bullets. We include a {{cssxref("gap")}} of `20px` to provide enough room between the columns and rows to fit our `20px` solid column and row rules. Last, we set the row rules to break into segments at every intersection. + +```css live-sample___basic +ul { + display: grid; + grid-template-columns: repeat(8, 1fr); + list-style-type: none; + gap: 20px; + + row-rule: 10px solid olive; + column-rule: 10px solid palegoldenrod; + + row-rule-break: intersection; +} +``` + +The rest of the CSS is hidden for brevity. + +```css hidden live-sample___basic +ol { + place-items: center; + width: 95vw; +} +li { + text-align: center; + font-family: sans-serif; + line-height: 50px; +} +``` + +```js hidden live-sample___basic +const gap = document.getElementById("gap"); +const ul = document.getElementById("ul"); +const output = document.getElementById("o"); + +gap.addEventListener("input", () => { + o.innerText = ul.style.columnGap = `${gap.value}px`; +}); +``` + +#### Result + +{{EmbedLiveSample("Basic", "", "600")}} + +Make the column gaps wider and note how the breaks between row segments grow. Bring the column gap width down to `0px`, and notice how the row decoration appears continuous. It isn't! The `0px` gap between segments may not be visible, but the segments still start and end at the gap, so any offsets set with `row-rule-inset` properties will still be applied. + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{cssxref("column-rule-break")}} +- {{cssxref("rule-break")}} shorthand +- {{cssxref("rule-inset")}} shorthand +- {{cssxref("rule-overlap")}} +- {{cssxref("rule-visibility-items")}} +- {{cssxref("rule")}} shorthand +- [CSS gaps](/en-US/docs/Web/CSS/Guides/Gaps) module diff --git a/files/en-us/web/css/reference/properties/rule-break/index.md b/files/en-us/web/css/reference/properties/rule-break/index.md new file mode 100644 index 000000000000000..73bd822e3230ba9 --- /dev/null +++ b/files/en-us/web/css/reference/properties/rule-break/index.md @@ -0,0 +1,483 @@ +--- +title: "`rule-break` CSS property" +short-title: rule-break +slug: Web/CSS/Reference/Properties/rule-break +page-type: css-property +status: + - experimental +browser-compat: css.properties.rule-break +sidebar: cssref +--- + +{{SeeCompatTable}} + +The **`rule-break`** [CSS](/en-US/docs/Web/CSS) property sets the behavior for breaking column and row rules into segments where rows and column gaps intersect, setting {{cssxref("column-rule-break")}} and {{cssxref("row-rule-break")}} to the same value. + +{{InteractiveExample("CSS Demo: rule")}} + +```css interactive-example-choice +rule-break: none; +``` + +```css interactive-example-choice +rule-break: normal; +``` + +```css interactive-example-choice +rule-break: intersection; +``` + +```html interactive-example +
+
+ A + B + C + D + E + F + G + H + I + J + K + L + M + N + O + P + Q + R + S + T + U + V + W + X + Y + Z +
+
+``` + +```css interactive-example +#example-element { + display: grid; + grid-template-columns: repeat(7, 1fr); + row-rule: solid thick orange; + column-rule: solid thick purple; + gap: 10px; +} +#example-element i { + padding: 5px; +} +``` + +## Constituent properties + +This property is a shorthand for the following CSS properties: + +- {{cssxref("column-rule-break")}} +- {{cssxref("row-rule-break")}} + +## Syntax + +```css +/* Keywords */ +rule-break: none; +rule-break: normal; +rule-break: intersection; + +/* Global values */ +rule-break: inherit; +rule-break: initial; +rule-break: revert; +rule-break: revert-layer; +rule-break: unset; +``` + +### Values + +This property is specified as a single keyword from the following list: + +- `none` + - : There are no breaks where row and column rules intersect; rather, a single continuous decoration is painted from one end of each gap to the other. +- `normal` + - : In flex and grid containers, behaves as `none`. In multi-col, `column-rule-break` behaves as `intersection` and `row-rule-break` behaves as `none`. This is the default value. +- `intersection` + - : Rules always break when they intersect a gap, with rule segments starting and ending at container and gap edges. + +## Description + +The `rule-break` property is used to set the behavior for breaking rules into segments when they cross gaps. + +Gap decorations are painted within a gap as one or more gap decoration segments, with segments occurring between any two adjacent items. Depending on the container type, by default, these segments may either end at the edge of a gap, or the column and row rule may extend the entire height and width of the container. + +When there is a break in a rule, by default, the segments start and end at the edge of the gaps. If the gap size is `0`, the break may not be visible. The `rule-break` property determines if the break occurs. You can control the size of the break at the end of each segment with the `rule-inset` properties. When there are no breaks, and the line is continuous, `rule-inset` properties only affect the rule at the start and end edges of the container. When there are breaks, the `rule-inset` properties affect the start and end of every rule segment. + +Whether a rule is by default composed of a single continuous segment or segments that break when intersecting gaps depends on the container type. + +### Grid containers + +In grid containers, by default, rule segments continue through visible "cross" intersections. Setting `rule-break: intersection` will force the segments to break where they would otherwise cross. + +```html hidden +

Default rule breaks in grid

+
+
+
+
+
+
+
+
+
+

+ +

+``` + +```css hidden +body { + font-family: sans-serif; + text-align: center; +} +h1 { + font-size: 1.25em; +} +h2 { + font-size: 1em; +} + +:has(:checked) .grid { + rule-break: intersection; +} +.grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 20px; + rule: 5px solid red; + width: 100%; +} + +.grid > div { + border: 1px solid green; + background-color: lime; + height: 30px; +} +``` + +{{EmbedLiveSample("grid containers", "", "240")}} + +Check the checkbox to set the `rule-break` to `intersection`, which makes the continuous rules break at every "cross" intersection. + +### Flex containers + +In flexbox, when the `flex-direction` is `row` or `row-reverse`, the row rule is continuous, with the column segments starting and ending at the edge of the row gaps. When the `flex-direction` is `column` or `column-reverse`, the column rule is continuous, with the row segments starting and ending at the edge of the column gaps. + +```html hidden +

Default rule breaks in flexbox

+
+
+

flex-direction: row

+
+
+
+
+
+
+
+
+
+
+
+

flex-direction: column

+
+
+
+
+
+
+
+
+
+
+
+

+ +

+``` + +```css hidden +body { + font-family: sans-serif; + text-align: center; +} +h1 { + font-size: 1.25em; +} +h2 { + font-size: 1em; +} + +:has(:checked) .flexbox { + rule-break: intersection; +} +article { + display: flex; + gap: 5vw; + rule: 1px solid black; + width: 100vw; +} +section { + flex-basis: 45vw; +} +.flexbox { + display: flex; + flex-flow: balance; + flex-line-count: 3; + gap: 20px; + rule: 5px solid red; + width: 100%; +} +.column { + flex-flow: column balance; + gap: 20px; +} + +.flexbox > div { + border: 1px solid green; + background-color: lime; + flex: 1 1 auto; + height: 30px; +} +``` + +{{EmbedLiveSample("Flex containers", "", "300")}} + +Note how, depending on the `flex-direction`, the column or row rules are continuous by default. If you set the `rule-break` to `intersection`, those continuous rules break at every intersection. + +### Multi-col containers + +In multi-col containers, the default `normal` behavior differs between row rules and column rules. Column rule segments start and end when they intersect a row gap, behaving as `column-rule-break: intersection`, while row rules don't break when they intersect a column gap, behaving as `row-rule-break: none`. + +```html hidden +

Default rule breaks in multi-col

+
    +
  1. One fish
  2. +
  3. Two fish
  4. +
  5. Red fish
  6. +
  7. Blue fish
  8. +
  9. Black fish
  10. +
  11. Blue fish
  12. +
  13. Old fish
  14. +
  15. New fish.
  16. +
  17. This one has a little star.
  18. +
  19. This one has a little car.
  20. +
  21. Say! What a lot
  22. +
  23. Of fish there are.
  24. +
  25. Yes. Some are red.
  26. +
  27. And some are blue.
  28. +
  29. Some are old.
  30. +
  31. And some are new.
  32. +
  33. Some are sad.
  34. +
  35. And some are glad.
  36. +
  37. And some are very, very bad.
  38. +
  39. Why are they
  40. +
  41. Sad and glad and bad?
  42. +
  43. I do not know.
  44. +
  45. Go ask your dad.
  46. +
+
+ Set rule-break: + + + +
+``` + +```css hidden +body { + font-family: sans-serif; + text-align: center; +} +h1 { + font-size: 1.25em; +} +h2 { + font-size: 1em; +} +ol { + columns: 3 / 4em; + gap: 20px; + rule: 5px solid red; +} +li { + border: 1px solid green; + background-color: lime; + list-style-type: none; + margin-bottom: 5px; +} +:has([value="normal"]:checked) ol { + rule-break: normal; +} +:has([value="intersection"]:checked) ol { + rule-break: intersection; +} +:has([value="none"]:checked) ol { + rule-break: none; +} +label { + margin-right: 20px; +} +``` + +{{EmbedLiveSample("multi-col containers", "", "540")}} + +Check the radio buttons for each value to see the value's effect. + +## Formal definition + +{{cssinfo}} + +## Formal syntax + +{{csssyntax}} + +## Examples + +### Basic usage + +In this example, we use the `rule-break` property to break each rule segment in a grid container so no rules intersect. + +#### HTML + +We create a list of 50 items. Most of the HTML is hidden for brevity. + +```html +
    +
  • 1
  • +
  • 2
  • + ... +
  • 49
  • +
  • 50
  • +
+``` + +```html hidden live-sample___basic +
    +
  • 1
  • +
  • 2
  • +
  • 3
  • +
  • 5
  • +
  • 6
  • +
  • 7
  • +
  • 8
  • +
  • 9
  • +
  • 10
  • +
  • 11
  • +
  • 12
  • +
  • 13
  • +
  • 14
  • +
  • 15
  • +
  • 16
  • +
  • 17
  • +
  • 18
  • +
  • 19
  • +
  • 20
  • +
  • 21
  • +
  • 22
  • +
  • 23
  • +
  • 24
  • +
  • 25
  • +
  • 26
  • +
  • 27
  • +
  • 28
  • +
  • 29
  • +
  • 30
  • +
  • 31
  • +
  • 32
  • +
  • 33
  • +
  • 34
  • +
  • 35
  • +
  • 36
  • +
  • 37
  • +
  • 38
  • +
  • 39
  • +
  • 40
  • +
  • 41
  • +
  • 42
  • +
  • 43
  • +
  • 44
  • +
  • 45
  • +
  • 46
  • +
  • 47
  • +
  • 48
  • +
  • 49
  • +
  • 50
  • +
+``` + +#### CSS + +We define the unordered list as a 8-column container, creating columns and rows with the {{cssxref("grid-template-columns")}} property and setting {{cssxref("list-style-type")}} to `none` to remove the bullets. We include a {{cssxref("gap")}} of `20px` to provide enough room between the columns and rows to fit our `20px` solid column and row rules. Last, we set the rule segments to break instead of intersect. + +```css live-sample___basic +ul { + display: grid; + grid-template-columns: repeat(8, 1fr); + list-style-type: none; + gap: 20px; + + row-rule: 20px solid palegoldenrod; + column-rule: 20px solid olive; + + rule-break: intersection; +} +``` + +The rest of the CSS is hidden for brevity. + +```css hidden live-sample___basic +ol { + place-items: center; +} +li { + text-align: center; + aspect-ratio: 1; + font-family: sans-serif; + line-height: 50px; +} +``` + +#### Result + +{{EmbedLiveSample("Basic", "", "640")}} + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{cssxref("rule-inset")}} shorthand +- {{cssxref("rule-overlap")}} +- {{cssxref("rule-visibility-items")}} +- {{cssxref("rule")}} shorthand +- [CSS gaps](/en-US/docs/Web/CSS/Guides/Gaps) module