From c31ea3d118281b175f1d42ab0432b593f3e94d11 Mon Sep 17 00:00:00 2001 From: Shardul Chiplunkar Date: Wed, 18 Dec 2024 21:52:10 +0100 Subject: [PATCH] Clarify interaction between collapsing and multi-line containers (#36791) * Clarify interaction between collapsing and multi-line containers * Update files/en-us/web/css/css_flexible_box_layout/mastering_wrapping_of_flex_items/index.md * Update files/en-us/web/css/css_flexible_box_layout/mastering_wrapping_of_flex_items/index.md Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Apply suggestions from code review * Update files/en-us/web/css/css_flexible_box_layout/mastering_wrapping_of_flex_items/index.md Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * add toggle for visibility collapse * toggle button for example * Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update files/en-us/web/css/css_flexible_box_layout/mastering_wrapping_of_flex_items/index.md Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * change class name to collapse --------- Co-authored-by: Estelle Weyl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../mastering_wrapping_of_flex_items/index.md | 57 ++++++++++++++----- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/files/en-us/web/css/css_flexible_box_layout/mastering_wrapping_of_flex_items/index.md b/files/en-us/web/css/css_flexible_box_layout/mastering_wrapping_of_flex_items/index.md index f692ff0e2f5366b..cb0c146f889be07 100644 --- a/files/en-us/web/css/css_flexible_box_layout/mastering_wrapping_of_flex_items/index.md +++ b/files/en-us/web/css/css_flexible_box_layout/mastering_wrapping_of_flex_items/index.md @@ -261,16 +261,24 @@ The flexbox specification details what should happen if a flex item is collapsed This behavior is useful if you want to target flex items using JavaScript to show and hide content for example. The example in the specification demonstrates one such pattern. -In the following live example, I have a non-wrapped flex container. The third item has more content than the others yet is set to `visibility: collapse`; therefore, the flex container is retaining a _strut_ of the height required to display this item. If you remove `visibility: collapse` from the CSS or change the value to `visible`, you will see the item appear, and the space is redistributed between non-collapsed items; the height of the flex container should not change. +In the following live example, the non-wrapping flex container contains a row with three flex items that are set to flex to equal sizes. The third item has multiple lines of content, growing the container. The default for `align-items` is `normal`; for flex items, `normal` behaves as `stretch`, so all the items stretch by default, filling the container's cross-size height. + +The item creating the cross-size is set to `visibility: collapse`, which collapses or hides the flex item, depending on the browser. In either case, the flex container retains a _strut_ of the cross-size even though it is not visible. This way, if the item is made visible, the cross-size of the single-line flex container will not change. If you remove `visibility: collapse` from the CSS or change the value to `visible`, you will see the item appear, and the main-size space is redistributed between non-collapsed items, while the cross-size remains unchanged. > [!NOTE] -> Use Firefox for the below two examples as Chrome and Safari treat collapse as hidden. +> Use Firefox for the example below as other common browsers treat `collapse` as `hidden`. + +```html hidden live-sample___visibility-collapse +

+ +

+``` ```html live-sample___visibility-collapse
One
Two
-
Three
has
extra
text
+
Three
has
extra
text
``` @@ -286,31 +294,45 @@ In the following live example, I have a non-wrapped flex container. The third it border-radius: 5px; background-color: rgb(96 139 168 / 0.2); } -.hide { +.collapse { visibility: collapse; } ``` +```css hidden live-sample___visibility-collapse +p:has(:checked) + div .collapse { + visibility: visible; +} +``` + {{EmbedLiveSample("visibility-collapse")}} -When dealing with multiple-line flex containers however you need to understand that the wrapping is re-done _after_ collapsing. So the browser needs to re-do the wrapping behavior to account for the new space that the collapsed item has left in the inline direction. +The above was a single-line, non-wrapping flex container with a set size of `600px` so whether the item is visible or collapsed, the width is the same. It is important to understand that while the container retains a strut of the collapsed item's cross-size, the main size is not preserved. Multi-line flex containers rewrap their items after removing collapsed items from rendering. The new space that a collapsed item leaves in the main direction may cause non-collapsed items to be placed in a different line than if the item were not collapsed. Because each line is laid out like an independent single-line flex container and its composition may change after collapsing, its cross-axis size may change too. -This means that items might end up on a different line to the one they started on. In the case of an item being shown and hidden it could well cause the items to end up in a different row. +The following example shows this behavior. The third flex item is collapsed, so it occupies zero space along the main axis (the inline-size is `0`). When collapsed, its strut is on the first row after the fourth item, with the first row being tall enough to fit the three lines of text that the third item would have had. Then, if you uncollapse the item (e.g. by removing the `collapse` class), there is no longer enough horizontal space for the fifth item on the first row, and it moves to the second. This causes the second row to grow to fit the two lines of text of its new member, and the last flex item is pushed onto a new row. With a taller second line and a new third line, the flex container is much taller than it was before. -I have created this behavior in the next live example. You can see how the stretching changes row based on the location of the collapsed item. If you add more content to the second item, it changes row once it gets long enough. That top row then only becomes as tall as a single line of text. +> [!NOTE] +> Use Firefox for the example below as other common browsers treat `collapse` as `hidden`. + +```html hidden live-sample___wrapped-visibility-collapse +

+ +

+``` ```html live-sample___wrapped-visibility-collapse
One
-
Add more text to this box to make it grow
-
Three
has
extra
text
+
Two is the width of this sentence.
+
Three
is
five
lines
tall.
Four
-
Five
+
Five
Five
Six
Seven
Eight
Nine
Ten
+
Eleven is longer
``` @@ -327,17 +349,24 @@ I have created this behavior in the next live example. You can see how the stret border-radius: 5px; background-color: rgb(96 139 168 / 0.2); flex: 1 1 auto; + min-width: 50px; } -.hide { +.collapse { visibility: collapse; } ``` -{{EmbedLiveSample("wrapped-visibility-collapse")}} +```css hidden live-sample___wrapped-visibility-collapse +p:has(:checked) + div .collapse { + visibility: visible; +} +``` + +{{EmbedLiveSample("wrapped-visibility-collapse", "", "300")}} -If this causes a problem for your layout it may require a rethinking of the structure, for example putting each row into a separate flex container in order that they can't shift rows. +If this causes a problem for your layout, it may require a rethinking of the structure, for example, putting each row into a separate flex container so that they can't shift rows. ### Using `visibility: hidden` and `display: none` -In previous live example, try using `visibility: hidden` or `display: none` instead of `visibility: collapse`. Using `visibility: hidden`, the item is made invisible but the box is kept in the formatting structure, so it still behaves as if it were part of the layout. +In the previous live examples, try using `visibility: hidden` or `display: none` instead of `visibility: collapse`. Using `visibility: hidden`, the item is made invisible, but the box is kept in the formatting structure, so it still behaves as if it were part of the layout. When you use `display: none`, the item is completely removed from the formatting structure. Not only is it invisible but the structure is removed as well. This means counters ignore it and things like transitions do not run.