In Advanced Tree Counting: Mathematical Layouts With sibling-index() And sibling-count() (2026-05-21), Smashing Magazine explained practical use cases for new CSS functions: sibling-index() (an element's index among siblings) and sibling-count() (the total count of sibling elements). Combining these with calc() allows developers to write declaratively in pure CSS operations previously handled by JS or repetitive hand-written :nth-child(n) rules, such as delay (staggered) animations based on element count or order, progressive shifts in color, size, and rotation, and dynamic calculations for grids or circular layouts. Moreover, layouts adapt automatically whenever items are added or removed.
In client web development, teams have repeatedly run into issues where "staged animations or layout calculations for lists and cards are implemented with JS or an excess of nth-child, breaking every time an element is added or removed, resulting in untouchable, frozen legacy code." From the perspective of supporting client web development, we view this as a design challenge: not focusing on "whether it can be animated flashily," but ensuring we build and deliver robust dynamic layouts that adapt automatically to element counts, eliminate reliance on JS, and work reliably even in unsupported browsers. Connecting this with the strategies for leveraging native features in Using Modern CSS Native Features in Client Projects (GH Media) and the latest specification trends in New CSS Features in Spring 2026 (GH Media), this article organizes "dynamic layout and JS-free animation implementation support" based on sibling-index() and sibling-count() as a custom development package.
Why rebuild dynamic layouts now?
| Dimension | JS / repetitive nth-child rules (conventional) | sibling-index functions (2026) |
|---|---|---|
| Syntax | Hardcoding numerical values per element | Declared in a single line with calc() |
| Count changes | Offsets shift, requiring rework each time | Tracks changes automatically |
| Dependency | Requires JS bundles | Self-contained entirely in CSS |
| Maintenance | Untouchable, frozen shelfware | Update a single formula |
| Performance | Triggers JS execution and recalculation | Browser calculates natively |
| Fallback | Prone to breaking on unsupported browsers | Remains functional even without animations |
In short, merely "animating" is fundamentally different from "remaining unbroken, maintainable, and operable without JS as elements fluctuate." Even in client development, "declaring via mathematical formulas, supplying fallbacks, and delivering with maintenance procedures" has become the quality baseline. This enables teams to guarantee robust layouts that automatically adapt to element counts as a reliable deliverable.
What you can accomplish with sibling-index() / sibling-count()
sibling-index() returns an element's index among siblings, and sibling-count() returns the total count of siblings. Simply passing these into calc() lets you inject values dynamically tailored to an element's position and total count into your styling.
/* 要素の順番に応じてアニメーション開始を 80ms ずつ遅らせる(スタガー) */
.card {
animation: fade-in 0.4s both;
animation-delay: calc(sibling-index() * 80ms);
}
/* 全体数に対する位置の割合(0〜1)で色相を段階変化させる */
.tag {
--ratio: calc(sibling-index() / sibling-count());
background: hsl(calc(var(--ratio) * 360) 70% 55%);
}
1. Staggered animations
Just like animation-delay: calc(sibling-index() * 80ms), simply scaling delays according to order creates an animation where cards or list items smoothly appear from top to bottom. The entire process of running forEach in JS and applying style becomes obsolete.
2. Progressive styling
You can continuously adjust hue, size, rotation, opacity, and more based on position or total count proportions. Tedious gradient-like specifications requiring handwritten sequences from :nth-child(1) to :nth-child(10) are replaced by a single line of calc().
3. Grid and circular layout calculations
By retrieving the total count with sibling-count() and determining each element's angle with calc(360deg / sibling-count() * sibling-index()), you can position elements at equal intervals along a circle's circumference. Dynamic layouts for menus or diagrams automatically recalculate even as item counts change.
Five phases of client dynamic layout and JS-free animation implementation support
Phase 1: Inventory and assessment (1 week)
- Auditing existing JS animations and repetitive
nth-childrules - Listing areas prone to breaking when element counts change
- Confirming browser support scope and fallback requirements
- Deliverables: Current state report + list of replacement candidates
Phase 2: Design (1 week)
- Designing formulas (staggering / progressive styling / layout calculation)
- Defining fallback policies (
@supportsbranching) - Structuring accessibility requirements such as
prefers-reduced-motion - Deliverables: Implementation specification + fallback design
Phase 3: Implementation (1–3 weeks)
- Implementing replacements based on
sibling-index()/sibling-count() - Reducing and eliminating JS animation code
- Fallbacks for unsupported browsers using
@supports - Deliverables: Implemented components
Phase 4: Verification and handover (1 week)
- Element count fluctuation testing (0 items, 1 item, large volume)
- Visual verification across supported and unsupported browsers
- Performance benchmarking and establishing maintenance procedures
- Deliverables: Verification report + maintenance documentation
Phase 5: Continuous maintenance (ongoing)
- Periodic tracking of browser support status
- Evaluating and executing fallback removal
- Standard application to new components
Implementation standards set for custom development
| Application | Recommendation | Avoid |
|---|---|---|
| Staggered animations | calc(sibling-index() * 時間) | Injecting style into each element via JS |
| Progressive styling | Ratio to total count using sibling-index() / sibling-count() | Exhaustive list of :nth-child(n) declarations |
| Circular / grid layouts | calc(360deg / sibling-count()) | Hardcoding manually calculated coordinates |
| Fallback | Branching via @supports | Ignoring unsupported browsers, leading to breakage |
| Motion suppression | Disabling animations with prefers-reduced-motion | Forcing animations on all users |
| Maintenance | Consolidated into a single formula | Values scattered across individual elements |
Which projects need this and which do not
| Projects requiring this | Low-priority projects |
|---|---|
| Lists and grids with dynamically fluctuating item counts | Static items with fixed counts |
| Card listings linked to CMS where item counts are unpredictable | Screens without any animation |
| Projects requiring JS reduction and lighter asset footprints | Legacy browser support is a mandatory requirement |
| Dynamic positioning of menus and diagrams | One-off disposable pages |
| Struggling to maintain animation code | Implementations that are already sufficiently simple |
Six clauses to include in client contracts
| Clause | Details | What the client should verify |
|---|---|---|
| Target scope | Animations and screens to replace | Scope of JS removal |
| Fallback | Appearance in unsupported browsers | Permissible degree of degradation |
| Browser compatibility | Guaranteed scope | Support requirements |
| Accessibility | Handling motion reduction | prefers-reduced-motion |
| Handover | Formula specifications / maintenance procedures | Maintenance framework |
| Ongoing maintenance | Monitoring browser support status | Criteria for removing fallbacks |
Client ROI estimates (assuming CMS-integrated card listings)
| Item | Built with JS / nth-child | Built with sibling-index functions | Difference |
|---|---|---|---|
| JS bundle | Grows with each animation | Virtually unnecessary | Lighter footprint and faster rendering |
| Maintenance workload | Code modifications required each time | Resolved in a single formula | Reduced maintenance costs |
| Resilience to item count fluctuations | Offsets shift, requiring rework | Adapts automatically without modifications | Curtails ongoing revision expenses |
| Animation breakdown | Breaks when item counts change | Adapts automatically to item counts | Prevents quality incidents |
| Annual benefit | — | — | JS reduction + compressed maintenance workload |
Even an initial assessment (starting from 180,000 yen) provides value in itself by visualizing which parts of current animation code break with fluctuating element counts and which parts can be migrated exclusively to CSS. The cost of shelfware code is usually billed all at once during the next major redesign.
Five common pitfalls
Pitfall 1: Animate every element excessively with over-the-top motion
Applying stagger effects to large numbers of elements creates a heavy, distracting experience. Design by constraining motion scope and volume.
Pitfall 2: Deploying to production without measuring performance
Even native calculations can introduce performance overhead depending on element count. Benchmark against realistic item counts before release.
Pitfall 3: Failing to prepare fallbacks
Animations break on unsupported browsers. First construct a baseline layout that works cleanly without motion using @supports.
Pitfall 4: Neglecting accessibility
This imposes a burden on users sensitive to motion. Suppress motion using prefers-reduced-motion.
Pitfall 5: Scattering formulas across individual elements
This slides straight back into unmaintainability. Consolidate formulas into a single location before handover.
90-day action plan
| Week | Action |
|---|---|
| Week 1 | Inventorying JS animations / repetitive nth-child rules |
| Week 2 | Formula design + fallback policy definition |
| Week 3〜5 | Implementing core animation replacements + reducing JS |
| Week 6 | Element count variation and browser verification + establishing maintenance procedures |
| Week 7〜13 | Monitoring browser support + expanding to new components |
Conclusion — Moving from forced JS animations to delivering layouts that automatically track element counts
With the arrival of sibling-index() and sibling-count(), staggered animations, progressive styling, and layout calculations that once depended on JS or heavy nth-child declarations can now be written declaratively in pure CSS. For teams supporting client web development, our Dynamic Layout and JS-Free Animation Implementation Support serves as a core offering to deliver resilient layouts that automatically track element counts by declaring rules mathematically, preparing fallbacks, and handing over projects with maintenance manuals. If you also wish to automate color palettes, please read Automating Accessible Color Palettes with contrast-color() (GH Media).
Please feel free to reach out via our contact form if you want to know whether your current animation code will break when elements expand, how far you can reduce JS dependencies, or how to keep layouts functioning reliably across unsupported browsers.









