@@ -107,7 +107,7 @@ Strong Containment: the 'contain' property</h2>
107107
108108 <pre class='propdef'>
109109 Name : contain
110- Value : none | strict | content | [ size || layout || style || paint ]
110+ Value : none | strict | content | [ [ size | inline-size] || layout || style || paint ]
111111 Initial : none
112112 Inherited : no
113113 Applies to : See <a href="#contain-applies">below</a>
@@ -259,6 +259,34 @@ Strong Containment: the 'contain' property</h2>
259259 contain-size-grid-stretches-auto-rows.html
260260 </wpt>
261261
262+ <dt> <dfn>inline-size</dfn>
263+ <dd>
264+ This value turns on [=inline-size containment=] for the element.
265+ This prevents the [=inline-size=] of its [=principal box=]
266+ from directly depending on its contents.
267+
268+ <wpt>
269+ contain-inline-size-bfc-floats-001.html
270+ contain-inline-size-bfc-floats-002.html
271+ contain-inline-size-fieldset.html
272+ contain-inline-size-flex.html
273+ contain-inline-size-flexitem.html
274+ contain-inline-size-grid.html
275+ contain-inline-size-intrinsic.html
276+ contain-inline-size-legend.html
277+ contain-inline-size-multicol.html
278+ contain-inline-size-regular-container.html
279+ contain-inline-size-removed.html
280+ contain-inline-size-replaced.html
281+ contain-inline-size-table.html
282+ contain-inline-size-vertical-rl-.html
283+ contain-inline-size-grid-indefinite-height-min-height-flex-row.html
284+ contain-inline-size-grid-stretches-auto-rows.html
285+ </wpt>
286+
287+ Note: There can still be indirect dependencies,
288+ see [[#containment-inline-size]] .
289+
262290 <dt> <dfn>layout</dfn>
263291 <dd>
264292 This value turns on <a>layout containment</a> for the element.
@@ -802,6 +830,165 @@ Possible Size-Containment Optimizations</h4>
802830 if the [=size containment box|containment box=] is off-screen or obscured,
803831 the layout of its contents (i.e. "[=laying out in-place=] ") can be delayed or done at a lower priority.
804832
833+ <h3 id='containment-inline-size'>
834+ Inline-Size Containment</h3>
835+
836+ Giving an element <dfn export>inline-size containment</dfn>
837+ applies [=size containment=] to the [=inline-axis=] sizing of its [=principal box=] .
838+ This means the [=inline-axis=] [=intrinsic sizes=] of the [=principal box=]
839+ are determined as if the element had no content.
840+ However, content continues to impact the box’s [=block-axis=] [=intrinsic sizes=] as usual,
841+ and the box is allowed to [=fragmentation|fragment=] normally in the [=block axis=] .
842+
843+ <div class=note>
844+ <span class="marker"> Note:</span> In some cases,
845+ a box’s [=block-axis=] [=intrinsic sizes=]
846+ can impact layout in the parent [=formatting context=]
847+ in ways that affect the box’s [=inline size=]
848+ (e.g. by triggering scrollbars on an ancestor element),
849+ creating a dependency of the box’s [=inline size=] on its own content.
850+ If this changed [=inline size=] results in a different [=block size=] ,
851+ that new [=block size=] can loop into further impacting the parent formatting context,
852+ but not in a way that reverts it to the previously-problematic layout.
853+
854+ For example, if scrollbars were introduced,
855+ they are not then removed,
856+ even if the consequent [=block size=] is small enough to not need them;
857+ or if a box’s logical height collides with a lower-placed float and is cleared down
858+ to where it also has more available inline space
859+ and thus becomes short enough to not have collided,
860+ it is not them moved back up to its previous problematic size and position.
861+
862+ Thus, although [=inline-size containment=] prevents
863+ the box’s content from directly affecting its [=inline size=]
864+ through its [=inline-axis=] [=intrinsic sizes=] ,
865+ its [=inline size=] can still indirectly depend on its contents
866+ by their effect on its [=block size=] .
867+ </div>
868+
869+ ISSUE:
870+ In general, the relationship between an element's inline size
871+ and it's block size
872+ is unpredictable and non-monotonic,
873+ with the block size capable of shifting up and down arbitrarily
874+ as the inline size is changed.
875+ Infinite cycles are prevented
876+ by ensuring that layout does not revert to a previous (known-problematic) state,
877+ even if a naive analysis of the constraints would allow for such;
878+ in other words, layout always “moves forward”.
879+ We believe that current CSS layout specifications incorporate such rules,
880+ but to the extent that they don't,
881+ please <a href="https://github.com/w3c/csswg-drafts/issues">inform the CSSWG</a>
882+ so that these errors can be corrected.
883+
884+ <div class=example>
885+ Consider this example,
886+ where float placement creates a dependency of block sizes on inline sizes:
887+
888+ <xmp class=lang-markup>
889+ <section style="width: 200px; border: solid; display: flow-root;">
890+ <!-- floated elements that impact the available space -->
891+ <div style="float: left; width: 50px; height: 80px; background: blue;"></div>
892+ <div style="float: right; width: 50px; height: 80px; background: blue;"></div>
893+ <div style="float: left; width: 160px; height: 80px; background: navy;"></div>
894+
895+ <!-- parent layout, determining context -->
896+ <article style="border: solid orangered; display: flow-root; min-width: min-content">
897+ <div style="background: orange; aspect-ratio: 1/1;">
898+ Article
899+ </div>
900+ </article>
901+ </section>
902+ </xmp>
903+
904+ <figure style="float: left; margin: 1em 0.5em">
905+ <section style="width: 200px; border: solid; display: flow-root;">
906+ <!-- floated elements that impact the available space -->
907+ <div style="float: left; width: 50px; height: 80px; background: blue;"></div>
908+ <div style="float: right; width: 50px; height: 80px; background: blue;"></div>
909+ <div style="float: left; width: 160px; height: 80px; background: navy;"></div>
910+
911+ <!-- parent layout, determining context -->
912+ <article style="border: solid orangered; display: flow-root; min-width: 50px">
913+ <div style="background: orange; aspect-ratio: 1/1;">
914+ Article
915+ </div>
916+ </article>
917+ </section>
918+ </figure>
919+
920+ The block layout algorithm will first place the floating boxes,
921+ with the first two sitting in the left and right corners of the container,
922+ and the third, being too wide to fit between, being pushed below them.
923+
924+ The following <code> article</code> will then be laid out.
925+ Because it is ''display: flow-root'' ,
926+ it cannot intersect any floats,
927+ and thus must take them into account
928+ when figuring out how to size and position itself.
929+
930+ The layout engine first attempts to place the <code> article</code>
931+ flush with the top of the container,
932+ resulting a ''100px'' width,
933+ plenty wide enough to accommodate its [=min-content size=] .
934+ However, due to the 'aspect-ratio' of its child,
935+ this would cause the <code> article</code> to be ''100px'' tall as well,
936+ which would intersect the third float 80px below,
937+ so this layout opportunity is discarded.
938+
939+ It then attempts to position the <code> article</code>
940+ flush with the top of the third float,
941+ in the narrow ''40px'' -wide space to its right.
942+ However, since the <code> article</code> ’s 'min-width' makes it too large
943+ to fit in the 40px-wide space beside the third float,
944+ it shifts below that one as well,
945+ forming a 200px square below all the floated boxes.
946+
947+ <figure style="float: right; margin: 1em 0.5em">
948+ <section style="width: 200px; border: solid; display: flow-root;">
949+ <!-- floated elements that impact the available space -->
950+ <div style="float: left; width: 50px; height: 80px; background: blue;"></div>
951+ <div style="float: right; width: 50px; height: 80px; background: blue;"></div>
952+ <div style="float: left; width: 160px; height: 80px; background: navy;"></div>
953+
954+ <!-- parent layout, determining context -->
955+ <article style="border: solid orangered; display: flow-root;">
956+ <div style="background: orange; aspect-ratio: 1/1;">
957+ Article
958+ </div>
959+ </article>
960+ </section>
961+ </figure>
962+
963+ If the 'min-width' is removed from the <code> article</code> ,
964+ or if [=inline-size containment=] is added to
965+ either the <code> article</code> or <code> header</code>
966+ (causing ''min-width: min-content'' to resolve to zero),
967+ then the <code> article</code> will fit as a 40px square
968+ next to the final floated <code> div</code>
969+ (possibly with some of its content overflowing).
970+
971+ At this point, the width and height of the <code> article</code>
972+ (''40px'' each)
973+ <em> would</em> fit back in the first considered space,
974+ flush with the top of the container.
975+ However, the box is not returned to the previous position,
976+ because the layout engine knows already
977+ that this position would result in an invalid layout.
978+ </div>
979+
980+ Giving an element [=inline-size containment=]
981+ has no effect if any of the following are true:
982+
983+ * if the element does not generate a <a>principal box</a>
984+ (as is the case with ''display: contents'' or ''display: none'' )
985+ * if its [=inner display type=] is ''display/table''
986+ * if its [=principal box=] is
987+ an <a spec="css-display-3">internal table box</a>
988+ * if its [=principal box=] is
989+ an <a spec="css-display-3">internal ruby box</a>
990+ or a <a spec="css-display-3" lt="atomic inline">non-atomic</a> <a spec="css-display-3">inline-level</a> box
991+
805992<h3 id='containment-layout'>
806993Layout Containment</h3>
807994
@@ -2500,20 +2687,6 @@ Changes from <a href="https://www.w3.org/TR/css-contain-1/">CSS Containment Leve
25002687
25012688<!-- catch all for tests only relevant to the css-contain-3, to stop bikeshed from complaining -->
25022689<wpt>
2503- contain-inline-size-bfc-floats-001.html
2504- contain-inline-size-bfc-floats-002.html
2505- contain-inline-size-fieldset.html
2506- contain-inline-size-flex.html
2507- contain-inline-size-flexitem.html
2508- contain-inline-size-grid.html
2509- contain-inline-size-intrinsic.html
2510- contain-inline-size-legend.html
2511- contain-inline-size-multicol.html
2512- contain-inline-size-regular-container.html
2513- contain-inline-size-removed.html
2514- contain-inline-size-replaced.html
2515- contain-inline-size-table.html
2516- contain-inline-size-vertical-rl-.html
25172690container-queries/animation-container-size.html
25182691container-queries/animation-container-type-dynamic.html
25192692container-queries/animation-nested-animation.html
@@ -2713,7 +2886,5 @@ container-queries/size-container-with-quotes.html
27132886container-queries/style-container-for-shadow-dom.html
27142887container-queries/style-container-invalidation-inheritance.html
27152888container-queries/style-query-with-unknown-width.html
2716- contain-inline-size-grid-indefinite-height-min-height-flex-row.html
2717- contain-inline-size-grid-stretches-auto-rows.html
27182889container-type-important.html
27192890</wpt>
0 commit comments