@@ -107,7 +107,7 @@ Strong Containment: the 'contain' property</h2>
107
107
108
108
<pre class='propdef'>
109
109
Name : contain
110
- Value : none | strict | content | [ size || layout || style || paint ]
110
+ Value : none | strict | content | [ [ size | inline-size] || layout || style || paint ]
111
111
Initial : none
112
112
Inherited : no
113
113
Applies to : See <a href="#contain-applies">below</a>
@@ -259,6 +259,34 @@ Strong Containment: the 'contain' property</h2>
259
259
contain-size-grid-stretches-auto-rows.html
260
260
</wpt>
261
261
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
+
262
290
<dt> <dfn>layout</dfn>
263
291
<dd>
264
292
This value turns on <a>layout containment</a> for the element.
@@ -802,6 +830,165 @@ Possible Size-Containment Optimizations</h4>
802
830
if the [=size containment box|containment box=] is off-screen or obscured,
803
831
the layout of its contents (i.e. "[=laying out in-place=] ") can be delayed or done at a lower priority.
804
832
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
+
805
992
<h3 id='containment-layout'>
806
993
Layout Containment</h3>
807
994
@@ -2500,20 +2687,6 @@ Changes from <a href="https://www.w3.org/TR/css-contain-1/">CSS Containment Leve
2500
2687
2501
2688
<!-- catch all for tests only relevant to the css-contain-3, to stop bikeshed from complaining -->
2502
2689
<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
2517
2690
container-queries/animation-container-size.html
2518
2691
container-queries/animation-container-type-dynamic.html
2519
2692
container-queries/animation-nested-animation.html
@@ -2713,7 +2886,5 @@ container-queries/size-container-with-quotes.html
2713
2886
container-queries/style-container-for-shadow-dom.html
2714
2887
container-queries/style-container-invalidation-inheritance.html
2715
2888
container-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
2718
2889
container-type-important.html
2719
2890
</wpt>
0 commit comments