Skip to content

Commit 77efde7

Browse files
authored
1 parent cb9c3e8 commit 77efde7

3 files changed

Lines changed: 262 additions & 0 deletions

File tree

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<!DOCTYPE html>
2+
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#grid-item-sizing">
3+
<link rel="help" href="https://www.w3.org/TR/css-sizing-3/#fit-content-size">
4+
<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com">
5+
<meta name="assert" content="A grid item with an automatic size whose self-alignment is not stretch (and does not behave as stretch) is sized to its fit-content size in that axis, rather than filling its grid area.">
6+
<script src="/resources/testharness.js"></script>
7+
<script src="/resources/testharnessreport.js"></script>
8+
<link rel="stylesheet" href="/fonts/ahem.css">
9+
<style>
10+
/* Ahem at 20px with a line-height of 1 makes every glyph a 20px by 20px box,
11+
so "XXXXX" is 100px wide and one line tall. */
12+
.grid { display: grid; font: 20px/1 Ahem; }
13+
.wide-area { grid-template: 100px / 200px; }
14+
.narrow-area { grid-template: 100px / 60px; }
15+
16+
.item { background: green; }
17+
18+
/* Isolate the axis under test by giving the item a fixed size in the other axis. */
19+
.automatic-width { width: auto; height: 40px; }
20+
.automatic-height { width: 100px; height: auto; }
21+
</style>
22+
<body>
23+
<div id="log"></div>
24+
25+
<!-- Inline axis. The grid area is 200px wide and the item's max-content size is
26+
100px, so a stretched item is 200px wide and a fit-content sized item is
27+
100px wide. -->
28+
<div class="grid wide-area"><div class="item automatic-width" id="stretch-inline" style="justify-self: stretch">XXXXX</div></div>
29+
<div class="grid wide-area"><div class="item automatic-width" id="start-inline" style="justify-self: start">XXXXX</div></div>
30+
<div class="grid wide-area"><div class="item automatic-width" id="center-inline" style="justify-self: center">XXXXX</div></div>
31+
<div class="grid wide-area"><div class="item automatic-width" id="end-inline" style="justify-self: end">XXXXX</div></div>
32+
33+
<!-- The fit-content size is clamped by the stretch-fit size, so an item in a
34+
60px area whose min-content size is 40px and whose max-content size is
35+
100px is 60px wide. -->
36+
<div class="grid narrow-area"><div class="item automatic-width" id="center-inline-clamped" style="justify-self: center">XX XX</div></div>
37+
38+
<!-- Block axis. The grid area is 100px tall and the item's content is one 20px
39+
line tall, so a stretched item is 100px tall and a fit-content sized item
40+
is 20px tall. -->
41+
<div class="grid wide-area"><div class="item automatic-height" id="stretch-block" style="align-self: stretch">XXXXX</div></div>
42+
<div class="grid wide-area"><div class="item automatic-height" id="start-block" style="align-self: start">XXXXX</div></div>
43+
<div class="grid wide-area"><div class="item automatic-height" id="center-block" style="align-self: center">XXXXX</div></div>
44+
<div class="grid wide-area"><div class="item automatic-height" id="end-block" style="align-self: end">XXXXX</div></div>
45+
46+
<script>
47+
function itemMetrics(id) {
48+
const item = document.getElementById(id);
49+
const gridRect = item.parentElement.getBoundingClientRect();
50+
const itemRect = item.getBoundingClientRect();
51+
return {
52+
width: itemRect.width,
53+
height: itemRect.height,
54+
left: itemRect.left - gridRect.left,
55+
top: itemRect.top - gridRect.top,
56+
};
57+
}
58+
59+
test(() => {
60+
const metrics = itemMetrics("stretch-inline");
61+
assert_equals(metrics.width, 200, "used width");
62+
assert_equals(metrics.left, 0, "offset from the grid container's left edge");
63+
}, "justify-self: stretch on an item with an automatic width uses the stretch-fit size");
64+
65+
test(() => {
66+
const metrics = itemMetrics("start-inline");
67+
assert_equals(metrics.width, 100, "used width");
68+
assert_equals(metrics.left, 0, "offset from the grid container's left edge");
69+
}, "justify-self: start on an item with an automatic width uses the fit-content size");
70+
71+
test(() => {
72+
const metrics = itemMetrics("center-inline");
73+
assert_equals(metrics.width, 100, "used width");
74+
assert_equals(metrics.left, 50, "offset from the grid container's left edge");
75+
}, "justify-self: center on an item with an automatic width uses the fit-content size");
76+
77+
test(() => {
78+
const metrics = itemMetrics("end-inline");
79+
assert_equals(metrics.width, 100, "used width");
80+
assert_equals(metrics.left, 100, "offset from the grid container's left edge");
81+
}, "justify-self: end on an item with an automatic width uses the fit-content size");
82+
83+
test(() => {
84+
assert_equals(itemMetrics("center-inline-clamped").width, 60, "used width");
85+
}, "justify-self: center on an item with an automatic width clamps the fit-content size by the stretch-fit size");
86+
87+
test(() => {
88+
const metrics = itemMetrics("stretch-block");
89+
assert_equals(metrics.height, 100, "used height");
90+
assert_equals(metrics.top, 0, "offset from the grid container's top edge");
91+
}, "align-self: stretch on an item with an automatic height uses the stretch-fit size");
92+
93+
test(() => {
94+
const metrics = itemMetrics("start-block");
95+
assert_equals(metrics.height, 20, "used height");
96+
assert_equals(metrics.top, 0, "offset from the grid container's top edge");
97+
}, "align-self: start on an item with an automatic height uses the fit-content size");
98+
99+
test(() => {
100+
const metrics = itemMetrics("center-block");
101+
assert_equals(metrics.height, 20, "used height");
102+
assert_equals(metrics.top, 40, "offset from the grid container's top edge");
103+
}, "align-self: center on an item with an automatic height uses the fit-content size");
104+
105+
test(() => {
106+
const metrics = itemMetrics("end-block");
107+
assert_equals(metrics.height, 20, "used height");
108+
assert_equals(metrics.top, 80, "offset from the grid container's top edge");
109+
}, "align-self: end on an item with an automatic height uses the fit-content size");
110+
</script>
111+
</body>
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<!DOCTYPE html>
2+
<link rel="help" href="https://www.w3.org/TR/css-align-3/#self-alignment">
3+
<link rel="help" href="https://www.w3.org/TR/css-grid-1/#alignment">
4+
<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com">
5+
<meta name="assert" content="Each positional self-alignment value places a grid item's margin box within its grid area, and not within the grid container.">
6+
<script src="/resources/testharness.js"></script>
7+
<script src="/resources/testharnessreport.js"></script>
8+
<style>
9+
/* Every item is placed in the second track so that a start-aligned item is
10+
offset from the grid container's start edge. An offset of 0 therefore
11+
cannot be mistaken for correct alignment. */
12+
.grid { display: grid; }
13+
.three-columns { grid-template: 100px / 100px 100px 100px; }
14+
.three-rows { grid-template: 100px 100px 100px / 100px; }
15+
16+
.item { width: 40px; height: 40px; background: green; }
17+
18+
.column2 { grid-area: 1 / 2 / 2 / 3; }
19+
.row2 { grid-area: 2 / 1 / 3 / 2; }
20+
</style>
21+
<body>
22+
<div id="log"></div>
23+
24+
<!-- Inline axis. The second column's start edge is at 100px and leaves 60px of
25+
free space around the 40px wide item. Both the grid container and the items
26+
are horizontal-tb and ltr, so self-start/flex-start/left behave as start and
27+
self-end/flex-end/right behave as end. -->
28+
<div class="grid three-columns"><div class="item column2" style="justify-self: start" data-expected-left="100" data-expected-top="0"></div></div>
29+
<div class="grid three-columns"><div class="item column2" style="justify-self: center" data-expected-left="130" data-expected-top="0"></div></div>
30+
<div class="grid three-columns"><div class="item column2" style="justify-self: end" data-expected-left="160" data-expected-top="0"></div></div>
31+
<div class="grid three-columns"><div class="item column2" style="justify-self: self-start" data-expected-left="100" data-expected-top="0"></div></div>
32+
<div class="grid three-columns"><div class="item column2" style="justify-self: self-end" data-expected-left="160" data-expected-top="0"></div></div>
33+
<div class="grid three-columns"><div class="item column2" style="justify-self: flex-start" data-expected-left="100" data-expected-top="0"></div></div>
34+
<div class="grid three-columns"><div class="item column2" style="justify-self: flex-end" data-expected-left="160" data-expected-top="0"></div></div>
35+
<div class="grid three-columns"><div class="item column2" style="justify-self: left" data-expected-left="100" data-expected-top="0"></div></div>
36+
<div class="grid three-columns"><div class="item column2" style="justify-self: right" data-expected-left="160" data-expected-top="0"></div></div>
37+
38+
<!-- Block axis. The second row's start edge is at 100px and leaves 60px of free
39+
space around the 40px tall item. left and right are not valid values for
40+
align-self. -->
41+
<div class="grid three-rows"><div class="item row2" style="align-self: start" data-expected-left="0" data-expected-top="100"></div></div>
42+
<div class="grid three-rows"><div class="item row2" style="align-self: center" data-expected-left="0" data-expected-top="130"></div></div>
43+
<div class="grid three-rows"><div class="item row2" style="align-self: end" data-expected-left="0" data-expected-top="160"></div></div>
44+
<div class="grid three-rows"><div class="item row2" style="align-self: self-start" data-expected-left="0" data-expected-top="100"></div></div>
45+
<div class="grid three-rows"><div class="item row2" style="align-self: self-end" data-expected-left="0" data-expected-top="160"></div></div>
46+
<div class="grid three-rows"><div class="item row2" style="align-self: flex-start" data-expected-left="0" data-expected-top="100"></div></div>
47+
<div class="grid three-rows"><div class="item row2" style="align-self: flex-end" data-expected-left="0" data-expected-top="160"></div></div>
48+
49+
<script>
50+
for (const item of document.querySelectorAll(".item")) {
51+
test(() => {
52+
const gridRect = item.parentElement.getBoundingClientRect();
53+
const itemRect = item.getBoundingClientRect();
54+
assert_equals(itemRect.left - gridRect.left, Number(item.dataset.expectedLeft), "offset from the grid container's left edge");
55+
assert_equals(itemRect.top - gridRect.top, Number(item.dataset.expectedTop), "offset from the grid container's top edge");
56+
}, `${item.getAttribute("style")} places the item's margin box within its grid area`);
57+
}
58+
</script>
59+
</body>
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<!DOCTYPE html>
2+
<link rel="help" href="https://www.w3.org/TR/css-align-3/#overflow-values">
3+
<link rel="help" href="https://www.w3.org/TR/css-grid-1/#alignment">
4+
<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com">
5+
<meta name="assert" content="Unsafe alignment, which is the default overflow alignment, lets a grid item larger than its grid area overflow the area's start edge.">
6+
<script src="/resources/testharness.js"></script>
7+
<script src="/resources/testharnessreport.js"></script>
8+
<style>
9+
/* Every item uses explicit grid-area placement (with explicit end lines). */
10+
.grid { display: grid; }
11+
.single { grid-template: 50px / 50px; }
12+
.three-columns { grid-template: 50px / 50px 50px 50px; }
13+
.three-rows { grid-template: 50px 50px 50px / 50px; }
14+
15+
.item { background: green; }
16+
.wide { width: 100px; height: 50px; }
17+
.tall { width: 50px; height: 100px; }
18+
19+
.cell { grid-area: 1 / 1 / 2 / 2; }
20+
.column2 { grid-area: 1 / 2 / 2 / 3; }
21+
.row2 { grid-area: 2 / 1 / 3 / 2; }
22+
</style>
23+
<body>
24+
<div id="log"></div>
25+
26+
<!-- An item larger than a single grid area: the free space is negative, so
27+
unsafe alignment distributes it and the item overflows the area's start
28+
edge. This is the companion of grid-self-alignment-safe-overflow.html,
29+
where the same cases are clamped to the start edge instead. -->
30+
<div class="grid single"><div class="item wide cell" id="justify-center" style="justify-self: center"></div></div>
31+
<div class="grid single"><div class="item wide cell" id="justify-end" style="justify-self: end"></div></div>
32+
<div class="grid single"><div class="item wide cell" id="justify-unsafe-center" style="justify-self: unsafe center"></div></div>
33+
<div class="grid single"><div class="item tall cell" id="align-center" style="align-self: center"></div></div>
34+
<div class="grid single"><div class="item tall cell" id="align-end" style="align-self: end"></div></div>
35+
<div class="grid single"><div class="item tall cell" id="align-unsafe-center" style="align-self: unsafe center"></div></div>
36+
37+
<!-- An item placed in the second track, larger than that track: unsafe
38+
alignment lets it overflow toward the first track. -->
39+
<div class="grid three-columns"><div class="item wide column2" id="justify-center-second-column" style="justify-self: center"></div></div>
40+
<div class="grid three-columns"><div class="item wide column2" id="justify-end-second-column" style="justify-self: end"></div></div>
41+
<div class="grid three-rows"><div class="item tall row2" id="align-center-second-row" style="align-self: center"></div></div>
42+
<div class="grid three-rows"><div class="item tall row2" id="align-end-second-row" style="align-self: end"></div></div>
43+
44+
<script>
45+
function startEdgeOffset(id) {
46+
const item = document.getElementById(id);
47+
const gridRect = item.parentElement.getBoundingClientRect();
48+
const itemRect = item.getBoundingClientRect();
49+
return { left: itemRect.left - gridRect.left, top: itemRect.top - gridRect.top };
50+
}
51+
52+
test(() => {
53+
assert_equals(startEdgeOffset("justify-center").left, -25);
54+
}, "justify-self: center on an item wider than its grid area overflows the start edge");
55+
56+
test(() => {
57+
assert_equals(startEdgeOffset("justify-end").left, -50);
58+
}, "justify-self: end on an item wider than its grid area overflows the start edge");
59+
60+
test(() => {
61+
assert_equals(startEdgeOffset("justify-unsafe-center").left, -25);
62+
}, "justify-self: unsafe center on an item wider than its grid area overflows the start edge");
63+
64+
test(() => {
65+
assert_equals(startEdgeOffset("align-center").top, -25);
66+
}, "align-self: center on an item taller than its grid area overflows the start edge");
67+
68+
test(() => {
69+
assert_equals(startEdgeOffset("align-end").top, -50);
70+
}, "align-self: end on an item taller than its grid area overflows the start edge");
71+
72+
test(() => {
73+
assert_equals(startEdgeOffset("align-unsafe-center").top, -25);
74+
}, "align-self: unsafe center on an item taller than its grid area overflows the start edge");
75+
76+
test(() => {
77+
assert_equals(startEdgeOffset("justify-center-second-column").left, 25);
78+
}, "justify-self: center on an item overflowing the second column overflows toward the first column");
79+
80+
test(() => {
81+
assert_equals(startEdgeOffset("justify-end-second-column").left, 0);
82+
}, "justify-self: end on an item overflowing the second column overflows toward the first column");
83+
84+
test(() => {
85+
assert_equals(startEdgeOffset("align-center-second-row").top, 25);
86+
}, "align-self: center on an item overflowing the second row overflows toward the first row");
87+
88+
test(() => {
89+
assert_equals(startEdgeOffset("align-end-second-row").top, 0);
90+
}, "align-self: end on an item overflowing the second row overflows toward the first row");
91+
</script>
92+
</body>

0 commit comments

Comments
 (0)