Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions css/css-grid/alignment/grid-self-alignment-fit-content-001.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<!DOCTYPE html>
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#grid-item-sizing">
<link rel="help" href="https://www.w3.org/TR/css-sizing-3/#fit-content-size">
<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com">
<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.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<link rel="stylesheet" href="/fonts/ahem.css">
<style>
/* Ahem at 20px with a line-height of 1 makes every glyph a 20px by 20px box,
so "XXXXX" is 100px wide and one line tall. */
.grid { display: grid; font: 20px/1 Ahem; }
.wide-area { grid-template: 100px / 200px; }
.narrow-area { grid-template: 100px / 60px; }

.item { background: green; }

/* Isolate the axis under test by giving the item a fixed size in the other axis. */
.automatic-width { width: auto; height: 40px; }
.automatic-height { width: 100px; height: auto; }
</style>
<body>
<div id="log"></div>

<!-- Inline axis. The grid area is 200px wide and the item's max-content size is
100px, so a stretched item is 200px wide and a fit-content sized item is
100px wide. -->
<div class="grid wide-area"><div class="item automatic-width" id="stretch-inline" style="justify-self: stretch">XXXXX</div></div>
<div class="grid wide-area"><div class="item automatic-width" id="start-inline" style="justify-self: start">XXXXX</div></div>
<div class="grid wide-area"><div class="item automatic-width" id="center-inline" style="justify-self: center">XXXXX</div></div>
<div class="grid wide-area"><div class="item automatic-width" id="end-inline" style="justify-self: end">XXXXX</div></div>

<!-- The fit-content size is clamped by the stretch-fit size, so an item in a
60px area whose min-content size is 40px and whose max-content size is
100px is 60px wide. -->
<div class="grid narrow-area"><div class="item automatic-width" id="center-inline-clamped" style="justify-self: center">XX XX</div></div>

<!-- Block axis. The grid area is 100px tall and the item's content is one 20px
line tall, so a stretched item is 100px tall and a fit-content sized item
is 20px tall. -->
<div class="grid wide-area"><div class="item automatic-height" id="stretch-block" style="align-self: stretch">XXXXX</div></div>
<div class="grid wide-area"><div class="item automatic-height" id="start-block" style="align-self: start">XXXXX</div></div>
<div class="grid wide-area"><div class="item automatic-height" id="center-block" style="align-self: center">XXXXX</div></div>
<div class="grid wide-area"><div class="item automatic-height" id="end-block" style="align-self: end">XXXXX</div></div>

<script>
function itemMetrics(id) {
const item = document.getElementById(id);
const gridRect = item.parentElement.getBoundingClientRect();
const itemRect = item.getBoundingClientRect();
return {
width: itemRect.width,
height: itemRect.height,
left: itemRect.left - gridRect.left,
top: itemRect.top - gridRect.top,
};
}

test(() => {
const metrics = itemMetrics("stretch-inline");
assert_equals(metrics.width, 200, "used width");
assert_equals(metrics.left, 0, "offset from the grid container's left edge");
}, "justify-self: stretch on an item with an automatic width uses the stretch-fit size");

test(() => {
const metrics = itemMetrics("start-inline");
assert_equals(metrics.width, 100, "used width");
assert_equals(metrics.left, 0, "offset from the grid container's left edge");
}, "justify-self: start on an item with an automatic width uses the fit-content size");

test(() => {
const metrics = itemMetrics("center-inline");
assert_equals(metrics.width, 100, "used width");
assert_equals(metrics.left, 50, "offset from the grid container's left edge");
}, "justify-self: center on an item with an automatic width uses the fit-content size");

test(() => {
const metrics = itemMetrics("end-inline");
assert_equals(metrics.width, 100, "used width");
assert_equals(metrics.left, 100, "offset from the grid container's left edge");
}, "justify-self: end on an item with an automatic width uses the fit-content size");

test(() => {
assert_equals(itemMetrics("center-inline-clamped").width, 60, "used width");
}, "justify-self: center on an item with an automatic width clamps the fit-content size by the stretch-fit size");

test(() => {
const metrics = itemMetrics("stretch-block");
assert_equals(metrics.height, 100, "used height");
assert_equals(metrics.top, 0, "offset from the grid container's top edge");
}, "align-self: stretch on an item with an automatic height uses the stretch-fit size");

test(() => {
const metrics = itemMetrics("start-block");
assert_equals(metrics.height, 20, "used height");
assert_equals(metrics.top, 0, "offset from the grid container's top edge");
}, "align-self: start on an item with an automatic height uses the fit-content size");

test(() => {
const metrics = itemMetrics("center-block");
assert_equals(metrics.height, 20, "used height");
assert_equals(metrics.top, 40, "offset from the grid container's top edge");
}, "align-self: center on an item with an automatic height uses the fit-content size");

test(() => {
const metrics = itemMetrics("end-block");
assert_equals(metrics.height, 20, "used height");
assert_equals(metrics.top, 80, "offset from the grid container's top edge");
}, "align-self: end on an item with an automatic height uses the fit-content size");
</script>
</body>
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<!DOCTYPE html>
<link rel="help" href="https://www.w3.org/TR/css-align-3/#self-alignment">
<link rel="help" href="https://www.w3.org/TR/css-grid-1/#alignment">
<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com">
<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.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
/* Every item is placed in the second track so that a start-aligned item is
offset from the grid container's start edge. An offset of 0 therefore
cannot be mistaken for correct alignment. */
.grid { display: grid; }
.three-columns { grid-template: 100px / 100px 100px 100px; }
.three-rows { grid-template: 100px 100px 100px / 100px; }

.item { width: 40px; height: 40px; background: green; }

.column2 { grid-area: 1 / 2 / 2 / 3; }
.row2 { grid-area: 2 / 1 / 3 / 2; }
</style>
<body>
<div id="log"></div>

<!-- Inline axis. The second column's start edge is at 100px and leaves 60px of
free space around the 40px wide item. Both the grid container and the items
are horizontal-tb and ltr, so self-start/flex-start/left behave as start and
self-end/flex-end/right behave as end. -->
<div class="grid three-columns"><div class="item column2" style="justify-self: start" data-expected-left="100" data-expected-top="0"></div></div>
<div class="grid three-columns"><div class="item column2" style="justify-self: center" data-expected-left="130" data-expected-top="0"></div></div>
<div class="grid three-columns"><div class="item column2" style="justify-self: end" data-expected-left="160" data-expected-top="0"></div></div>
<div class="grid three-columns"><div class="item column2" style="justify-self: self-start" data-expected-left="100" data-expected-top="0"></div></div>
<div class="grid three-columns"><div class="item column2" style="justify-self: self-end" data-expected-left="160" data-expected-top="0"></div></div>
<div class="grid three-columns"><div class="item column2" style="justify-self: flex-start" data-expected-left="100" data-expected-top="0"></div></div>
<div class="grid three-columns"><div class="item column2" style="justify-self: flex-end" data-expected-left="160" data-expected-top="0"></div></div>
<div class="grid three-columns"><div class="item column2" style="justify-self: left" data-expected-left="100" data-expected-top="0"></div></div>
<div class="grid three-columns"><div class="item column2" style="justify-self: right" data-expected-left="160" data-expected-top="0"></div></div>

<!-- Block axis. The second row's start edge is at 100px and leaves 60px of free
space around the 40px tall item. left and right are not valid values for
align-self. -->
<div class="grid three-rows"><div class="item row2" style="align-self: start" data-expected-left="0" data-expected-top="100"></div></div>
<div class="grid three-rows"><div class="item row2" style="align-self: center" data-expected-left="0" data-expected-top="130"></div></div>
<div class="grid three-rows"><div class="item row2" style="align-self: end" data-expected-left="0" data-expected-top="160"></div></div>
<div class="grid three-rows"><div class="item row2" style="align-self: self-start" data-expected-left="0" data-expected-top="100"></div></div>
<div class="grid three-rows"><div class="item row2" style="align-self: self-end" data-expected-left="0" data-expected-top="160"></div></div>
<div class="grid three-rows"><div class="item row2" style="align-self: flex-start" data-expected-left="0" data-expected-top="100"></div></div>
<div class="grid three-rows"><div class="item row2" style="align-self: flex-end" data-expected-left="0" data-expected-top="160"></div></div>

<script>
for (const item of document.querySelectorAll(".item")) {
test(() => {
const gridRect = item.parentElement.getBoundingClientRect();
const itemRect = item.getBoundingClientRect();
assert_equals(itemRect.left - gridRect.left, Number(item.dataset.expectedLeft), "offset from the grid container's left edge");
assert_equals(itemRect.top - gridRect.top, Number(item.dataset.expectedTop), "offset from the grid container's top edge");
}, `${item.getAttribute("style")} places the item's margin box within its grid area`);
}
</script>
</body>
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<!DOCTYPE html>
<link rel="help" href="https://www.w3.org/TR/css-align-3/#overflow-values">
<link rel="help" href="https://www.w3.org/TR/css-grid-1/#alignment">
<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com">
<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.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
/* Every item uses explicit grid-area placement (with explicit end lines). */
.grid { display: grid; }
.single { grid-template: 50px / 50px; }
.three-columns { grid-template: 50px / 50px 50px 50px; }
.three-rows { grid-template: 50px 50px 50px / 50px; }

.item { background: green; }
.wide { width: 100px; height: 50px; }
.tall { width: 50px; height: 100px; }

.cell { grid-area: 1 / 1 / 2 / 2; }
.column2 { grid-area: 1 / 2 / 2 / 3; }
.row2 { grid-area: 2 / 1 / 3 / 2; }
</style>
<body>
<div id="log"></div>

<!-- An item larger than a single grid area: the free space is negative, so
unsafe alignment distributes it and the item overflows the area's start
edge. This is the companion of grid-self-alignment-safe-overflow.html,
where the same cases are clamped to the start edge instead. -->
<div class="grid single"><div class="item wide cell" id="justify-center" style="justify-self: center"></div></div>
<div class="grid single"><div class="item wide cell" id="justify-end" style="justify-self: end"></div></div>
<div class="grid single"><div class="item wide cell" id="justify-unsafe-center" style="justify-self: unsafe center"></div></div>
<div class="grid single"><div class="item tall cell" id="align-center" style="align-self: center"></div></div>
<div class="grid single"><div class="item tall cell" id="align-end" style="align-self: end"></div></div>
<div class="grid single"><div class="item tall cell" id="align-unsafe-center" style="align-self: unsafe center"></div></div>

<!-- An item placed in the second track, larger than that track: unsafe
alignment lets it overflow toward the first track. -->
<div class="grid three-columns"><div class="item wide column2" id="justify-center-second-column" style="justify-self: center"></div></div>
<div class="grid three-columns"><div class="item wide column2" id="justify-end-second-column" style="justify-self: end"></div></div>
<div class="grid three-rows"><div class="item tall row2" id="align-center-second-row" style="align-self: center"></div></div>
<div class="grid three-rows"><div class="item tall row2" id="align-end-second-row" style="align-self: end"></div></div>

<script>
function startEdgeOffset(id) {
const item = document.getElementById(id);
const gridRect = item.parentElement.getBoundingClientRect();
const itemRect = item.getBoundingClientRect();
return { left: itemRect.left - gridRect.left, top: itemRect.top - gridRect.top };
}

test(() => {
assert_equals(startEdgeOffset("justify-center").left, -25);
}, "justify-self: center on an item wider than its grid area overflows the start edge");

test(() => {
assert_equals(startEdgeOffset("justify-end").left, -50);
}, "justify-self: end on an item wider than its grid area overflows the start edge");

test(() => {
assert_equals(startEdgeOffset("justify-unsafe-center").left, -25);
}, "justify-self: unsafe center on an item wider than its grid area overflows the start edge");

test(() => {
assert_equals(startEdgeOffset("align-center").top, -25);
}, "align-self: center on an item taller than its grid area overflows the start edge");

test(() => {
assert_equals(startEdgeOffset("align-end").top, -50);
}, "align-self: end on an item taller than its grid area overflows the start edge");

test(() => {
assert_equals(startEdgeOffset("align-unsafe-center").top, -25);
}, "align-self: unsafe center on an item taller than its grid area overflows the start edge");

test(() => {
assert_equals(startEdgeOffset("justify-center-second-column").left, 25);
}, "justify-self: center on an item overflowing the second column overflows toward the first column");

test(() => {
assert_equals(startEdgeOffset("justify-end-second-column").left, 0);
}, "justify-self: end on an item overflowing the second column overflows toward the first column");

test(() => {
assert_equals(startEdgeOffset("align-center-second-row").top, 25);
}, "align-self: center on an item overflowing the second row overflows toward the first row");

test(() => {
assert_equals(startEdgeOffset("align-end-second-row").top, 0);
}, "align-self: end on an item overflowing the second row overflows toward the first row");
</script>
</body>
Loading