Style a Container by Item Count
Build a CSS-only card container that changes layout as its item count changes.
Introduction
30 Second Summary
A layout that feels balanced with three cards can feel cramped after a few more arrive. Most pages need extra logic to notice that change.
In this project, you will build a CSS-only card container that changes its layout based on its item count. You will pass that count from the cards to their parent without JavaScript.
What You'll Build
You will add cards until the container flips from a row into a grid without any JavaScript.
By the end of this project, you'll have:
- A card list whose item widths visibly respond when the number of cards changes.
- A transferred item count that updates the parent's label through sibling-count().
- A responsive parent layout that changes its border colour before switching from a row to a grid.
- Secret Mission: An optional challenge to push your CSS skills further.
Are there any prerequisites?
You need a code editor or CodePen to edit the page. You also need a recent version of Chrome because browser support for sibling-count() is limited.
Before We Start
Experimental CSS needs a controlled test environment. One browser will show the enhanced result. A second browser will reveal the fallback.
You'll prepare the editor where you write the page. Google Chrome will test the recent CSS features.
Firefox Extended Support Release will provide the fallback environment. This comparison lets you see how the same page responds to different levels of browser support.
In this step, get ready to:
- Confirm Chrome is version 138 or higher.
- Open a code editor for the page.
- Prepare Firefox ESR 153 for fallback testing.
Confirm Chrome is ready
Chrome added sibling-count() in version 138. Your Chrome version determines whether the main experiment can run.
- Press Cmd+Space on macOS or the Windows key on Windows to open your search bar.
- Type Chrome into the search bar.
- Open Chrome if it appears in the results.
- Choose the third tab below if Chrome does not appear.
- Select More in the top-right corner if Chrome opens.
- Select Help from the menu.
- Select About Google Chrome.
- Choose the tab below that matches the version shown.
✔️ I see version 138 or higher
- Leave Chrome open on the About Google Chrome page.
Chrome is ready to evaluate sibling-count(). That gives your main experiment a browser with the required CSS support.
ⓧ I see an older version
The About page checks for an available update. Let that check finish before continuing.
- Wait for Chrome to download the available update.
- Select Relaunch when the option appears.
- Return to About Google Chrome after Chrome reopens.
You should now see version 138 or higher.
ⓧ Chrome is not installed
- Open the official Chrome download page in your current browser.
- Select Download Chrome.
- Open the downloaded installation file.
- Follow the instructions shown by the installer.
- Open Chrome through your operating system's search bar.
- Select More in the top-right corner.
- Select Help from the menu.
- Select About Google Chrome.
You should see version 138 or higher.
Chrome won't update or install?
- Close every Chrome window before reopening the installer.
- Check whether your computer requires administrator approval to install applications.
- Use the official download page again if the installation file did not finish downloading.
Still stuck? Help me install or update Chrome for this CSS project.
Open your code editor
A code editor gives you a dedicated place to work with the page source. You can use an installed editor or the browser-based editor named in the project prerequisites.
- Choose the tab that matches the editor available on your computer.
✔️ I have a desktop editor
- Press Cmd+Space on macOS or the Windows key on Windows to open your search bar.
- Type the name of your code editor into the search bar.
- Press Enter to open the editor.
- Leave the editor open on its welcome screen or an empty workspace.
You should see an empty editing workspace ready for the page you create in the next step.
ⓧ I need a browser editor
- Return to Chrome.
- Open a new blank Pen in CodePen.
- Leave the blank editing workspace open.
You should see a workspace where you can enter the page structure plus its styles.
Prepare the fallback browser
A fallback test needs a browser that does not understand sibling-count(). Firefox ESR 153 comes from the release line before Firefox added support in version 154.
- Press Cmd+Space on macOS or the Windows key on Windows to open your search bar.
- Type Firefox into the search bar.
- Open Firefox if it appears in the results.
- Select the Firefox menu in the top-right corner if the browser opens.
- Select Help.
- Select About Firefox.
- Choose the tab below that matches the version shown.
✔️ I see Firefox ESR 153
- Leave Firefox ESR open on the About Firefox window.
Firefox ESR 153 is ready to show how your page behaves without sibling-count() support.
ⓧ I see Firefox 154 or higher
This Firefox version already supports the feature. Firefox ESR 153 provides the earlier browser engine needed for the fallback check.
- Return to Chrome.
- Open Mozilla's official Firefox ESR download page.
- Select Firefox Extended Support Release for your operating system.
- Select your preferred language.
- Download the installer.
- Open the downloaded installation file.
- Follow the instructions shown by the installer.
- Open Firefox ESR through your operating system's search bar.
The About Firefox window should show Firefox ESR 153.
ⓧ Firefox is not installed
- Return to Chrome.
- Open Mozilla's official Firefox ESR download page.
- Select Firefox Extended Support Release for your operating system.
- Select your preferred language.
- Download the installer.
- Open the downloaded installation file.
- Follow the instructions shown by the installer.
- Open Firefox ESR through your operating system's search bar.
The About Firefox window should show Firefox ESR 153.
Why use Firefox ESR?
Firefox ESR receives security updates while keeping the feature set of its major release. Version 153 gives you a maintained browser from before Firefox added sibling-count().
That controlled difference makes the later fallback test meaningful. Both browsers receive the same page while their CSS support produces different outcomes.
Can't find Firefox ESR?
- Confirm that you selected Firefox Extended Support Release on Mozilla's download page.
- Search for Firefox again after the installer finishes.
- Check the About Firefox window to confirm the major version is 153.
Need a hand? Help me install Firefox ESR 153 for fallback testing.
Before the final check, which browser do you expect to show the enhanced layout later in the project?
- Return to the About Google Chrome page.
- Confirm the Chrome major version is 138 or higher.
- Return to the About Firefox window.
- Confirm the Firefox ESR major version is 153.
- Bring your code editor to the foreground.
Your test bench is ready. Chrome can show the recent CSS behavior. Firefox ESR can prove that your fallback remains usable.
Your editor plus both test browsers are ready. Next, you'll build a three-card container and see its starting layout in Chrome.
Build the Card Container
The later item-count behavior needs a clear baseline. Without one, you cannot tell whether a new rule changed the container.
You will create a local HTML page with exactly three cards.
You will give the container a default CSS row layout. Chrome will show the starting point that later steps transform.
In this step, get ready to:
- Create a local page containing exactly three card items.
- Give the container a visible default row layout.
- Load the page in Chrome to confirm the baseline design.
Create the three-card structure
Semantic HTML gives each card its own element inside one shared container. These sibling elements become the input for the count-based work later.
- Use the new-file control in your code editor to create a blank document.
- Save the document as index.html on your Desktop.
Your editor tab now shows index.html. The page has a concrete location for each change you make.
- Build the three-card structure by replacing the empty contents with this code:
<!doctype html>
<html lang="en">
<head>
<!-- Configure the local page for standard browser rendering. -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Item Count Layout</title>
<!-- Reserve a home for the default layout styles. -->
<style>
</style>
</head>
<body>
<!-- Keep the three sibling cards inside one shared container. -->
<main class="card-container">
<article class="card">Card 1</article>
<article class="card">Card 2</article>
<article class="card">Card 3</article>
</main>
</body>
</html>
What does this structure do?
- The main element keeps all three cards inside one shared container.
- Each article element represents one card.
- The matching card classes let one CSS rule style every item consistently.
- Save index.html.
The three-card structure is now stored in your local page.
- Press Cmd+Space on macOS or the Windows key on Windows to open your search bar.
- Type Chrome and press Enter to open it.
Before you load the page, how do you expect three unstyled card elements to appear?
- Drag index.html from your Desktop into the Chrome window.
You will see Card 1, Card 2, and Card 3 as plain text on separate lines. This proves Chrome is loading the correct local file.
Seeing a blank page?
- Confirm the file name ends with .html.
- Check that all three article elements sit between the opening and closing main tags.
- Save index.html again before reloading the page.
Still stuck? Help me find why my local HTML page is blank in Chrome
Add the default row styling
Flexbox places direct children along one axis. Here, it gives the three cards an equal share of one horizontal row.
- In index.html from earlier, find the empty <style> element.
- Create the default row presentation by pasting this code between the opening and closing <style> tags:
/* Center the card demo on the page. */
body { margin: 0; min-height: 100vh; display: grid; place-items: center; font-family: system-ui, sans-serif; background: #f3f4f6; }
/* Display the collection as a horizontal row by default. */
.card-container { display: flex; gap: 1rem; width: min(90%, 900px); padding: 1.5rem; border: 3px solid #4f46e5; border-radius: 1rem; background: #ffffff; box-shadow: 0 1rem 2rem rgba(15, 23, 42, 0.12); }
/* Give every item equal space and a visible card surface. */
.card { flex: 1; padding: 2rem 1rem; border-radius: 0.75rem; color: #ffffff; text-align: center; background: #6366f1; }
What do these styles control?
- The body rule centers the demo against a light page background.
- The .card-container rule creates the horizontal row. Its border and shadow make the parent container easy to see.
- The .card rule gives every item equal space. Its background separates each card from the container.
- Save index.html.
Before you refresh the page, which elements do you expect to share the available width?
- Return to Chrome.
- Refresh the local page.
You will see a white container with a purple border. Inside it, three purple cards share one horizontal row.
You've locked in the baseline: three cards now share a visible default row.
Cards still stacking vertically?
- Confirm the CSS sits inside the opening and closing <style> tags.
- Check that .card-container matches class="card-container" exactly.
- Refresh Chrome after saving the latest changes.
Need another pair of eyes? Help me debug why my three cards are not appearing in one row
✔️ Awesome, I've got everything!
Your saved index.html contains three cards and their default row styles.
ⓧ I'd like to double check the full code
<!doctype html>
<html lang="en">
<head>
<!-- Configure the local page for standard browser rendering. -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Item Count Layout</title>
<!-- Reserve a home for the default layout styles. -->
<style>
/* Center the card demo on the page. */
body { margin: 0; min-height: 100vh; display: grid; place-items: center; font-family: system-ui, sans-serif; background: #f3f4f6; }
/* Display the collection as a horizontal row by default. */
.card-container { display: flex; gap: 1rem; width: min(90%, 900px); padding: 1.5rem; border: 3px solid #4f46e5; border-radius: 1rem; background: #ffffff; box-shadow: 0 1rem 2rem rgba(15, 23, 42, 0.12); }
/* Give every item equal space and a visible card surface. */
.card { flex: 1; padding: 2rem 1rem; border-radius: 0.75rem; color: #ffffff; text-align: center; background: #6366f1; }
</style>
</head>
<body>
<!-- Keep the three sibling cards inside one shared container. -->
<main class="card-container">
<article class="card">Card 1</article>
<article class="card">Card 2</article>
<article class="card">Card 3</article>
</main>
</body>
</html>
What should match?
This reference contains the same three card elements and row styles you added. It contains no item-count logic.
Your card container now has a clear starting layout. Next, you will let each card read the total number of siblings and turn that count into a visible width change.
Size Cards with Sibling Count
Your three-card container is already visible in Chrome. A fixed card width becomes stale whenever the number of cards changes.
The CSS function sibling-count() gives each card the total number of direct child elements that share its parent. You will use that value to divide the available width before adding another card.
In this step, get ready to:
- Calculate each card's width from the current sibling count.
- Add a fourth card to trigger a visible width change.
Make each card read the count
Each card can evaluate sibling-count() for itself. Dividing the container width by that count gives every card an equal share of the row.
- Switch back to the index.html tab in your code editor.
- Find the existing CSS rule that styles each card.
- Add the width calculation inside that rule by copying this declaration:
width: calc(100% / sibling-count());
What Does This Declaration Do?
- The sibling-count() function returns the total number of direct child elements under the same parent. The current card is included in that total.
- The calc() function divides the available width by that total. Three cards therefore receive three equal shares.
- The browser recalculates the value whenever the sibling set changes. One declaration can respond to any card count.
- Save index.html.
- Switch back to the local page in Chrome.
- Refresh the page.
You should see the three cards sharing the horizontal row at equal widths. This confirms that Chrome accepted the count-based calculation.
Cards Keep Their Old Width?
- Confirm that the declaration sits inside the existing rule for each card.
- Check that sibling-count() has empty parentheses.
- Confirm that you refreshed the page in the current Chrome browser from earlier.
Still stuck? Help me debug why sibling-count() is not changing my card widths.
Add a fourth card and compare
The count changes as soon as another direct child joins the container. Every card then recalculates its own share from the new total.
- Switch back to index.html in your code editor.
- Select the complete final card item from its opening tag through its closing tag.
- Copy the selected card with Cmd+C on macOS or Ctrl+C on Windows.
- Place your cursor directly after the final card's closing tag.
- Paste the copied card with Cmd+V on macOS or Ctrl+V on Windows.
- Save index.html.
Before you refresh, which result do you expect? Your prediction will make the width change easier to spot.
- Switch back to the local page in Chrome.
- Refresh the page.
You should see four cards across the same horizontal row. Every card now occupies one quarter of the available width.
That is your first count-driven CSS result. The same card rule adapted to the new sibling total without JavaScript.
Fourth Card Missing or Wrapping?
- Confirm that the copied card sits inside the existing card container.
- Check that you copied the complete card element with both tags.
- Confirm that all four cards are direct children of the same container.
Need another pair of eyes? Help me check why my fourth card is not joining the count-sized row.
✔️ Awesome, I've got everything!
Your saved page now has four cards whose widths respond to their shared sibling count.
ⓧ I'd like to double check the full code
Compare your index.html file with these end-state checks.
- Confirm that the existing card container has exactly four direct card items.
- Confirm that the existing card CSS rule calculates width with sibling-count().
- Confirm that the container still uses its default horizontal row layout.
- Confirm that no scroll-driven animation or parent count label has been added.
Your cards now respond to the size of their sibling group. Next, you will carry that count up to the parent container.
Pass the Count to the Parent
Your four cards can now read their shared total with sibling-count(). That value still lives on each card, so the container cannot use it for its own styles.
In this step, you will encode the total as a tiny width. A scroll-driven animation will convert that width into a custom property on the parent. The container border will make the transfer visible in Chrome.
In this step, get ready to:
- Add an element that measures the number of card siblings.
- Transfer the measured count to the container through a view timeline.
- Confirm the parent border reacts when the card count changes.
Add the count probe
The parent needs a measurable signal from inside the container. An empty helper element provides that signal without displaying another card.
- In index.html, locate the fourth card inside the card container.
- Place this helper immediately after the fourth card:
<!-- Expose the card total to the parent timeline. -->
<n></n>
What Does This Markup Do?
- The empty <n> element becomes the subject that measures the sibling total.
- The helper stays empty because its job is to carry geometry instead of visible content.
- The calculation subtracts this helper later, leaving the total for the four cards.
- Save index.html.
- Switch back to the Chrome page from earlier.
- Press Cmd+Option+I (macOS) or Ctrl+Shift+I (Windows) to open DevTools.
- Confirm the DOM tree shows <n></n> immediately after the fourth card.
Cannot Find the Helper?
- Check that <n></n> sits before the card container's closing tag.
- Make sure the helper is outside every individual card.
Still stuck? Help me place the count helper inside my card container
The helper now needs a width that matches the number of cards. Each card contributes one pixel to that width.
- Return to the <style> block in index.html.
- Add this rule below the existing card styles:
.container > n {
/* Convert the card total into a measurable width. */
position: absolute;
left: 0;
width: calc((sibling-count() - 1) * 1px);
view-timeline: --n x;
}
How Does the Probe Measure Cards?
- The absolute position keeps the helper out of the container's visible row.
- The sibling-count() - 1 calculation removes the helper from its own sibling total.
- The 1px multiplier converts the number into a measurable width.
- The view-timeline declaration exposes that width through the horizontal axis.
- Save index.html.
- Refresh the Chrome page.
- Select the <n> element in the DevTools DOM tree.
- Check its computed width. You should see 4px.
Is the Probe Width Incorrect?
- Confirm the helper is a direct child of the card container.
- Check that the selector matches the container class exactly.
- Confirm the width calculation contains sibling-count() - 1.
Need another pair of eyes? Help me debug the helper width in Chrome DevTools
Connect the timeline to the parent
A View Timeline tracks the probe's position inside its scroll container. The animation maps that position back to the numeric --n property on the parent.
- Add the count-transfer rules below the probe rule in index.html by copying this code:
@property --n {
/* Keep the transferred count numeric during interpolation. */
syntax: "<number>";
inherits: false;
initial-value: 0;
}
.container {
/* Hoist the child's timeline to this parent. */
position: relative;
overflow: auto;
timeline-scope: --n;
animation: --n linear both;
animation-timeline: --n;
animation-range: exit calc(100% - 1000px) exit;
/* Use the transferred count as a visible test signal. */
border-color: hsl(calc(var(--n) * 50) 70% 50%);
}
@keyframes --n {
0% {
--n: 1000;
}
to {
--n: 0;
}
}
How Does the Count Reach the Parent?
- The @property rule registers --n as a number that CSS can interpolate.
- The timeline-scope declaration makes the helper's named timeline available on the container.
- The animation-range declaration maps the probe's pixel width across a maximum range of one thousand items.
- The border hue reads var(--n), turning the transferred number into a visible result.
- Save index.html.
- Switch back to the Chrome page.
- Refresh the page.
You should see a blue border around the container holding the four cards.
Is the Border Still Its Old Colour?
- Confirm the container keeps its existing border width and border style.
- Check that animation-timeline appears after the animation shorthand.
- Make sure view-timeline and timeline-scope both use --n.
Still seeing the original border? Help me debug this scroll-driven count transfer
Test the transfer with one fewer card
The border is now a live signal from the parent. A temporary DOM edit lets you test a different card count without changing the saved file.
Before you remove a card, do you expect the parent border to react without any script counting the cards?
Deleting the card in DevTools only changes the current browser preview. Reloading the page restores the saved four-card version.
- Return to the DOM tree in Chrome DevTools.
- Select the fourth card element.
- Press Delete to remove that element from the rendered page.
You should see three cards. The parent border should shift from blue to green as --n changes from 4 to 3.
- Reload the Chrome page to restore the fourth card.
You should see all four cards again. The container border should return to blue.
That proves the transfer works. The container now reacts to a value calculated inside its children.
Your parent container now has access to the card count through CSS. Next, you will use that value to switch the cards from a row into a grid.
Switch Layouts by Count
Four cards now pass their shared count into the parent through a scroll-driven animation. The changing border proves that the parent can react to the value.
In this step, you will turn that value into a CSS layout decision. The fifth card will cross the threshold and move the container into a two-column CSS Grid.
In this step, get ready to:
- Make the parent choose its layout from the transferred count.
- Add a fifth card to cross the layout threshold.
- Prove that removing or restoring the fifth card switches the layout.
Create the layout condition
The count arrives on the parent as a numeric custom property. The if() function can choose the parent’s display value by checking that property.
How does the layout condition work?
The style() condition reads the count-related custom property on the container. A greater-than comparison checks whether that value has crossed the threshold.
The if() function selects the grid value when the comparison is true. Its alternative keeps the existing horizontal row layout.
- Switch back to index.html in the code editor from earlier.
- Locate the parent container rule whose border colour reads the count-related custom property.
- Find the existing display declaration that creates the horizontal row.
- Keep that declaration as the baseline layout.
- Add a second display declaration directly below the baseline.
- Use if() as the value of the second declaration.
- Configure its style() condition to check whether the existing count property is greater than 4.
- Set grid as the result when the condition is true.
- Set the existing row display value as the alternative result.
Before you refresh, do you expect four cards to remain in a row or switch to a grid?
- Save index.html.
- Return to the page in Chrome from earlier.
- Refresh the page.
You should still see four cards in the horizontal row. This confirms that the alternative branch remains active below the threshold.
Did the four-card layout change?
- Check that the condition uses the same custom property that controls the parent border colour.
- Confirm that the comparison checks for a value greater than 4.
- Make sure the conditional display declaration comes after the baseline declaration.
Still stuck? Help me debug a CSS if() condition that should keep four cards in a row.
Cross the count threshold
Every card receives the updated value from sibling-count(). The existing animation transfers that new value to the parent after the fifth card appears.
- Switch back to index.html in the code editor.
- Locate the fourth card in the existing HTML.
- Duplicate the entire fourth card directly after it.
- Save index.html.
- Return to the page in Chrome.
Before you refresh, do you expect the parent to keep the row or activate the grid?
- Refresh the page.
You should see the five cards leave the horizontal row. The border should also reflect the updated count value.
Why do the cards form one column?
The conditional display value has activated the grid. A grid without explicit column tracks places these cards into a single column.
That vertical layout is useful evidence. It proves that crossing the count threshold changed the parent’s layout mode.
Still seeing the horizontal row?
- Count the card elements inside the container. You should now have five.
- Check that the duplicated card remains inside the same parent container.
- Confirm that the border colour also changed after the new card was added.
Need another pair of eyes? Help me find why my fifth card does not activate the CSS grid.
Shape and test the grid
The parent now enters grid layout at the right count. Two equal tracks give that grid a clear two-column shape.
- Switch back to index.html in the code editor.
- Add a grid-template-columns declaration to the parent container rule.
- Set the declaration to two equal 1fr tracks.
- Save index.html.
- Return to the page in Chrome.
Before you refresh, how do you expect the five cards to fill two equal columns?
- Refresh the page.
You should see five cards arranged across two equal columns. Their widths should respond to the five-card value.
Is the grid still one column?
- Confirm that grid-template-columns is inside the parent container rule.
- Check that the declaration defines exactly two equal tracks.
- Make sure the conditional display declaration still selects grid above the threshold.
Still seeing one column? Help me debug the two-column grid in my count-responsive card container.
Now test the opposite side of the threshold before leaving the page in its finished grid state.
- Switch back to index.html in the code editor.
- Remove the duplicated fifth card.
- Save index.html.
- Return to the page in Chrome.
Before you refresh, which layout should the four-card container choose?
- Refresh the page.
You should see the four cards return to the horizontal row. The border should return to the colour associated with the lower count.
- Switch back to the code editor.
- Press Cmd+Z (macOS) or Ctrl+Z (Windows) to restore the fifth card.
- Save index.html.
- Return to the page in Chrome.
Before the final refresh, do you expect the restored card to reactivate the two-column grid?
- Refresh the page.
You should see five cards in the two-column grid again. The border should show that the transferred parent count also returned to five.
That is the full feedback loop working. The children determine the count while the parent chooses the matching layout without JavaScript.
Your count-responsive layout works in Chrome. Next up, you will check the same page in the second browser and confirm that the fallback remains usable.
Test the Fallback Layout
In Chrome, your container already receives its item count through sibling-count(). The transferred value drives the visual enhancements.
Browser support determines whether this CSS trick can run. This final check proves the page stays usable when the count-driven layer is unavailable.
In this step, get ready to:
- Confirm the enhanced layout in Chrome.
- Load the same page in the unsupported browser.
- Verify every card remains usable in the default row layout.
Confirm the enhanced baseline
The supported result is your control. It shows what the optional count-driven layer adds before you test the same file elsewhere.
- Switch back to the Chrome tab showing index.html from earlier.
- Reload the page using the browser reload control.
You should see the cards in the count-driven grid.
Their widths should reflect the current number of cards. The border should reflect the transferred count.
Good, your supported baseline is confirmed. Chrome is applying the complete count-driven layer.
Load the fallback in the second browser
Browsers fall back to declarations they understand when newer features are unavailable. The base container layout provides the safety net for this page.
Before you load the page, pause on this question: which layout do you expect to control the cards.
- Launch the second browser from earlier through your operating system's app search.
- Switch back to Chrome.
- Copy the full local page address from Chrome's address bar.
- Return to the second browser.
- Paste the copied address into its address bar.
- Press Enter to load index.html.
You'll see every card remain readable in the default row layout.
The count-driven grid switch stays absent. The count-driven border response stays absent too.
That is the final proof: the unsupported browser keeps every card usable in the base row.
Still seeing the enhanced grid?
- Confirm that you used the unsupported browser prepared earlier.
- Compare the local page address in both browsers to confirm they point to the same index.html file.
Still stuck? Help me diagnose why my fallback browser still shows the count-driven grid.
Secret mission
Audit the Layout Boundary
Your layout changes correctly above its configured card-count threshold. Now test the exact boundary in Chrome, compare it with the unsupported browser, and restore the original page after gathering evidence.
Clean Up Your Resources
Clean Up Your Resources
This project runs entirely on your computer with no ongoing costs. Decide whether to keep the demo, pause your testing, or delete the page.
Resources you used:
- Local index.html page containing your count-responsive CSS card demo and its fallback row layout.
Keep everything running
No action is needed. Choose this option if you want the demo available for future experiments.
- Keep index.html in its current location.
- Leave the local page open in Chrome if you want to keep testing the count-driven grid.
- Leave the local page open in the second browser if you want to compare the fallback row layout.
Pause - I'll come back to this later
Pausing frees browser memory while preserving the demo for later.
- Save index.html in the code editor from earlier.
- Close the local page tab in Chrome.
- Close the local page tab in the second browser.
- Close the code editor.
Your local page remains available when you want to continue testing.
Delete - I don't want to use this again
Deleting the local page gives you a clean start.
Permanent deletion can feel severe. It affects only index.html.
Your browsers and code editor stay installed.
macOS
Finder lets you remove the file from the location used by your editor.
- Select index.html in the file sidebar of the code editor from earlier.
- Use the editor's file-reveal action to show the selected file in Finder.
- Move index.html to Trash.
- Open Trash from the Dock.
- Select index.html in Trash.
- Use Finder's permanent deletion action for the selected file.
- Confirm the deletion prompt.
You should no longer see index.html in Trash. The local demo has been removed.
Windows
File Explorer lets you permanently remove the file from the location used by your editor.
- Select index.html in the file sidebar of the code editor from earlier.
- Use the editor's file-reveal action to show the selected file in File Explorer.
- Select index.html in File Explorer.
- Press Shift+Delete.
- Confirm the permanent deletion prompt.
You should no longer see index.html in File Explorer. The local demo has been removed.
Nice Work!
Nice Work!
You did it! You built a CSS-only card container that responds to its item count without JavaScript.
You've learned how to:
- Use sibling-count() inside each card to make card widths respond to the number of sibling items.
- Transfer the sibling-derived count into the parent with a scroll-driven animation. Use that count to change the container border colour.
- Switch the container to a grid layout at the configured threshold. Keep a row layout below the threshold. Confirm that the usable row fallback remains in browsers without sibling-count() support.
- Secret Mission: Complete an optional challenge that pushes your CSS-only layout skills further.
Ready to quiz yourself?