# Site URL: https://rolandfranke.nl ## roland. URL: https://rolandfranke.nl Roland Franke's personal blog. Discover a creative frontend developer with expertise in HTML, CSS, React, and accessibility, dedicated to build inclusive and innovative web experiences. Explore projects, professional experience, and insights on modern web development. # roland. \[ro.land\]•**frontend developer** _Roland_ is a frontend developer with a passion for creative coding and a sharp focus on CSS, HTML, and accessibility. I thrive on building web experiences that are not only visually appealing but accessible and performant for everyone. --- ## Hi, I'm Roland 👋 URL: https://rolandfranke.nl/about About Roland Franke — frontend developer focused on semantic HTML, modern CSS, accessibility and thoughtful web experiences. # Hi, I'm Roland 👋 Frontend developer. HTML enthusiast. CSS explorer. Accessibility advocate. Curious human. ## I build for humans first. I'm a frontend developer from the Netherlands who loves crafting accessible, performant and expressive interfaces using semantic HTML and modern CSS. I care deeply about how things are built, not just how they look. Structure matters. Details matter. Experience matters. ## What I believe - **Start with HTML.**The web already gives us a powerful foundation. Use it. - **CSS is more than styling.**It is layout, interaction, motion and expression. - **Accessibility is not optional.**If it does not work for everyone, it does not work. - **Clarity beats cleverness.**Simple solutions age better. ## How I approach frontend ### Semantic by default I prefer native HTML over abstraction when possible. The platform is powerful. I lean on it first. ### Modern CSS, used with intention Container queries, logical properties, anchor positioning. I enjoy exploring new CSS capabilities and using them when they truly improve the experience. ### Keep it simple Small, focused solutions. Clean structure. Minimal complexity. Code that still makes sense six months later. ## Why I write On [Frontend Stories](/frontend-stories/) I share experiments, discoveries and practical frontend insights. Writing helps me think clearly. It also helps others explore what is possible with the modern web, especially when it comes to CSS and semantic HTML. ## Outside of code I am endlessly curious about how things work. Interfaces, systems, patterns, people. The web just happens to be my favorite playground. --- ## Frontend Stories URL: https://rolandfranke.nl/frontend-stories Explore CSS, JavaScript, and frontend insights. Tips, techniques, and ideas for building accessible, modern web experiences. # Frontend Stories Explore CSS, JavaScript, and frontend insights. Tips, techniques, and ideas for building accessible, modern web experiences. My personal CSS wishlist for Interop 2027, from scroll-driven interfaces and better layouts to smoother transitions and customizable form controls. Build a CSS-only reading progress indicator that tracks the article itself, not the entire page, using view-timeline and timeline-scope. Learn how CSS field-sizing: content lets inputs and textareas size themselves to their content without JavaScript. How the new CSS scroll-target-group and :target-current let you build a table of contents scroll spy without JavaScript. A practical exploration of CSS Anchor Positioning and the anchor() function to visually connect related elements without extra markup. A simple introduction to the CSS light-dark() function and how it makes light and dark mode styling much easier. Discover the new element in HTML, how it improves semantics and accessibility, and where to use it in your projects. Discover how CSS evolved in 2024 with subgrid, anchor positioning, and more, streamlining layouts and boosting developer ergonomics. Rebeccapurple becomes the official CSS logo color! Explore the new repo for formats and future variants, including CSS4, CSS5, and beyond. 💜 Explore my CSS grid system that's kept layouts flexible and responsive for years, with named columns and custom constraints for consistent design. CSS Masonry should be part of display: grid to streamline layouts, avoid fragmentation, leverage Grid's features, and provide a consistent developer experience. "Snapflyover" describes elements briefly entering but not stopping in the snap zone, providing visual or interactive feedback during scroll snapping. --- ## A CSS Reading Progress Bar That Tracks the Article URL: https://rolandfranke.nl/frontend-stories/a-css-reading-progress-bar-that-tracks-the-article Build a CSS-only reading progress indicator that tracks the article itself, not the entire page, using view-timeline and timeline-scope. # A CSS Reading Progress Bar That Tracks the Article by _Roland_•September 15, 2026 cssexperimental ## Introduction Reading progress indicators are a nice little enhancement for long-form content. The usual CSS-only approach is surprisingly simple. Tie an animation to the document scroll position and scale a bar from `0` to `1` as the user scrolls. The problem is that `scroll()` tracks the scroll progress of the page. But what if the page has a header, a hero, some content before the article, related content after it, and a footer? The progress indicator still represents the entire document. What I wanted was slightly different: > **I want the progress bar to represent the reading progress of the article itself.** And that’s exactly what I’ve implemented on this site. If you’re reading this story on my site, the progress indicator at the top of the page is already using this approach. It tracks the article you’re reading, not the entire document. No JavaScript. No calculations. Just CSS. ## The Usual Reading Progress Bar There are already plenty of examples of CSS-only reading progress indicators using scroll-driven animations. The basic idea is straightforward: connect the animation to the root scroll timeline. For example: ```css .progress { scale: 0 1; transform-origin: left; animation: progress linear both; animation-timeline: scroll(); } @keyframes progress { to { scale: 1 1; } } ``` As the document scrolls from top to bottom, the animation progresses from `0%` to `100%`. This is a great use case for `animation-timeline: scroll()`. But it answers a slightly different question: _How far have I scrolled through the document?_ For a reading progress indicator, the question we really want to answer is: _How far have I scrolled through this article?_ Those aren’t necessarily the same thing. ## The Problem with a Real Article Imagine a page structured like this: ```html
...
...
With a long story you want to track...
``` If the progress bar uses: ```css animation-timeline: scroll(); ``` the animation starts when the document starts scrolling and finishes when the document reaches the bottom. _The header counts._ _The hero counts._ _The article counts._ _The footer counts._ There is a better way. ## Give the Article Its Own Timeline Instead of asking the document scroll position to control the animation, we can create a **view progress timeline for the article**. That’s what `view-timeline` is for. ```css article { view-timeline: --article; } ``` This gives the article a named view timeline called `--article`. A view timeline tracks an element as it moves through its scrollport. Unlike a regular scroll progress timeline, the timeline belongs to the element being observed. Now we have something that represents the article moving through the viewport. But there is one problem. Our progress bar isn’t inside the article. It’s outside of it: ```html
...
``` So how can the progress bar access `--article`? That’s where `timeline-scope` comes in. ## Bringing the Timeline Into Scope First, declare the timeline at the root: ```css :root { timeline-scope: --article; } ``` This makes the named timeline available to descendants of the element where `timeline-scope` is declared. Now the progress indicator can use the article’s timeline: ```css .progress { animation-timeline: --article; } ``` We have effectively connected two otherwise unrelated elements: No JavaScript is involved in moving information between the two elements. The article creates the timeline. The progress indicator consumes it. ## Defining the Reading Range There is one more important piece. A view timeline has several possible ranges describing how an element enters, moves through and leaves the scrollport. For the reading indicator, I want the animation to represent the article from the moment it has entered the viewport until the moment it has completely left it. That’s where `animation-range` comes in: ```css .progress { animation-range-start: entry 100%; animation-range-end: exit 0%; } ``` Together, the relevant CSS looks like this: ```css :root { timeline-scope: --article; } article { view-timeline: --article; } .progress { position: fixed; inset: 0 0 auto; z-index: 1; block-size: 0.5rem; background-color: hotpink; scale: 0 1; transform-origin: left; animation-name: --progress; animation-timing-function: linear; animation-fill-mode: forwards; animation-timeline: --article; animation-range-start: entry 100%; animation-range-end: exit 0%; } @keyframes --progress { to { scale: 1 1; } } ``` And that’s the whole trick. ## What Is Actually Happening? The important part isn’t really the animation. The animation itself is almost trivial: ```css @keyframes --progress { to { scale: 1 1; } } ``` The interesting part is the timeline. The article defines it: ```css article { view-timeline: --article; } ``` The root makes that timeline available: ```css :root { timeline-scope: --article; } ``` And the progress bar consumes it: ```css .progress { animation-timeline: --article; } ``` This means the progress bar isn’t measuring how far the user has travelled through the document. It’s responding to how far the **article has travelled through the scrollport**. That’s a subtle difference, but it makes the result much more useful. ## Why `timeline-scope` Matters Normally, named animation timelines have a limited scope. `timeline-scope` lets you extend that scope so another element can use a named timeline created elsewhere in the document tree. This is useful when the element being tracked and the element being animated aren’t in the same subtree. In this example, that’s exactly what we need. The article owns the timeline. The progress indicator lives somewhere completely different. ```html
...
...
``` There is no need to restructure the HTML just to make the animation work. `timeline-scope` lets the timeline cross that boundary. ## Why Not Just Use `animation-range`? You might wonder whether this could be solved with a normal document scroll timeline and a carefully chosen `animation-range`. To some extent, yes. You could calculate where the article starts and where it ends and use those values to limit the animation. But that couples the animation to the layout. If the hero changes height, the range changes. If the article moves, the range changes. If the layout changes at a breakpoint, the range changes. With a view timeline, the relationship is semantic instead: > Track this element. That is much closer to what we actually mean by reading progress. ## The Nice Part: The Article Can Move Another thing I like about this approach is that the article doesn’t need to be in a particular position on the page. It could be preceded by: - a header - a hero - an introduction - advertisements - related content - anything else The progress timeline still belongs to the article. This makes the technique much more reusable than a progress bar tied to the document’s total scroll range. ## Progressive Enhancement Scroll-driven animations are still not universally available. The individual pieces used here, including `animation-timeline`, `view-timeline` and `timeline-scope`, are still marked as limited availability on MDN. That doesn’t mean the entire experience needs a JavaScript fallback. A reading progress indicator is enhancement rather than essential functionality. The article remains perfectly readable without it. For example, the feature can be isolated behind a feature query: ```css @supports (animation-timeline: --article) and (view-timeline: --article) and (timeline-scope: --article) { :root { timeline-scope: --article; } article { view-timeline: --article; } .progress { animation: --progress linear both; animation-timeline: --article; animation-range: entry 100% exit 0%; } } ``` The browser either gets the enhanced reading indicator or simply gets the article. No JavaScript required. ## What I Like About This This is one of those CSS features where the syntax is probably more complicated than the problem appears to be. But once you understand the relationship between the pieces, it becomes quite elegant: ```text article ↓ view-timeline ↓ named timeline ↓ timeline-scope ↓ progress indicator ``` The browser handles the relationship between the element and the viewport. CSS handles the animation. And the DOM doesn’t need to change just to make those two things communicate. ## Browser Support The features used in this example are still evolving across browsers, so this technique is best treated as progressive enhancement. A reading progress indicator is a good candidate for this. If a browser doesn’t support the required timeline features, the article remains fully usable. The progress indicator simply isn’t shown. As browser support improves, the same HTML can progressively gain the enhanced experience. ## Closing Thoughts A CSS-only reading progress bar isn’t particularly new anymore. The interesting part is deciding **what the progress actually represents**. A document-level scroll timeline tells you how far you’ve travelled through the page. A view timeline lets you track a specific element. Combine that with `timeline-scope`, and the progress indicator can live independently from the article while still being driven by the article’s position in the viewport. That’s the part I find interesting. Not another way to make a bar grow from left to right, but a more precise way to describe **what that progress means**. CSS is getting increasingly good at expressing these relationships declaratively. And sometimes the interesting part isn’t the animation at all. It’s the timeline. --- ## CSS display masonry URL: https://rolandfranke.nl/frontend-stories/css-display-masonry CSS Masonry should be part of display: grid to streamline layouts, avoid fragmentation, leverage Grid's features, and provide a consistent developer experience. # CSS display masonry by _Roland_•October 25, 2024 css ## Why CSS Masonry Should be Part of `display: grid;` The new CSS Masonry layout is an exciting addition that allows elements to be arranged in a more natural and compact way, similar to popular JavaScript-based libraries like Masonry.js. However, there’s an argument to be made that the Masonry layout should be incorporated within the existing `display: grid;` property rather than being introduced as a new display type. Here’s why: ## 1\. Conceptual Alignment with Grid Layout CSS Grid is already the go-to specification for creating two-dimensional layouts, offering extensive control over rows and columns. Masonry can be seen as a natural extension of this, adding a new dimension to the flexibility of `display: grid;`. This would align Masonry conceptually with Grid, where the purpose is to arrange items within a two-dimensional space. ## 2\. Avoiding Unnecessary Fragmentation Adding Masonry as a standalone display property could introduce unnecessary complexity and fragmentation within the CSS layout ecosystem. Developers would need to learn and understand an entirely new syntax and behavior instead of leveraging their existing knowledge of Grid. By keeping it as part of `display: grid;`, developers can achieve a more consistent experience without switching mental models or learning additional properties. ## 3\. Enhanced Developer Experience Incorporating Masonry into Grid makes the developer experience more streamlined. Consider that many projects already use `display: grid;` and would naturally benefit from the addition of a Masonry layout as an option within that context. For example, a developer could quickly switch between regular grid and masonry-like behavior through an optional setting like `grid-template-rows: masonry;` or `grid-auto-rows: masonry;`. This would significantly reduce cognitive load and enhance code readability. ## 4\. Leverage Existing Grid Features CSS Grid already provides numerous features like grid lines, named areas, and explicit sizing control, which could seamlessly integrate with a Masonry approach. For instance, named lines or fractional units (`fr`) could be used alongside a Masonry configuration, offering additional customization options. A new display property would likely require re-implementing many of these features, resulting in redundant or fragmented capabilities. ## 5\. Consistency with Existing Layouts From a design system perspective, the existing separation between Flexbox for one-dimensional layouts and Grid for two-dimensional layouts is intuitive. Introducing a new display property for Masonry would blur this distinction, making it less clear when to use which layout method. Integrating Masonry into `display: grid;` maintains this clear division and reinforces Grid as the go-to tool for two-dimensional layouts. ## 6\. Pragmatic Evolution of Grid CSS is evolving rapidly, and the Grid specification has proven to be both powerful and adaptable. Masonry is an opportunity to enhance Grid’s flexibility further. By incorporating it within `display: grid;`, we acknowledge that the Grid layout is capable of evolving with new features without splintering into separate properties for each new pattern that emerges. --- ## CSS field-sizing: content Is Finally Baseline URL: https://rolandfranke.nl/frontend-stories/css-field-sizing-content Learn how CSS field-sizing: content lets inputs and textareas size themselves to their content without JavaScript. # CSS field-sizing: content Is Finally Baseline by _Roland_•August 26, 2026 cssbaseline ## Introduction Getting a form control to size itself based on its content has traditionally been surprisingly difficult. An `` has a default width. If you want it to grow as the user types, you usually end up measuring the content with JavaScript, listening for input events, or using some clever CSS workaround. That’s no longer necessary. With the `field-sizing` property, CSS can tell form controls to size themselves based on their content. And as of June 2026, `field-sizing` is Baseline Newly Available. ## The Problem Consider a simple input: ```html ``` By default, the input has a predefined size. It doesn’t care whether the user enters: ```text Bob ``` or: ```text John and Jane Doe ``` The control itself stays the same size. You can of course choose a suitable `width`, but that doesn’t make the control adapt to its content. This is where `field-sizing: content` comes in. ## Let CSS Size the Input The CSS is remarkably simple: ```css input { field-sizing: content; } ``` That’s it. The input now sizes itself according to its content. As the user types, the field grows. When the content becomes shorter, it shrinks again. No JavaScript. No measuring text. No event listeners. ### Add Some Limits In practice, you probably don’t want an input growing indefinitely across the page. That’s where `min-inline-size` and `max-inline-size` become useful: ```css input { field-sizing: content; min-inline-size: 10ch; max-inline-size: min(100%, 30ch); } ``` The input now has a sensible minimum size, while still being able to grow with its content. This is an important detail when using `field-sizing: content`: don’t immediately add a fixed `width` to the element, because that defeats much of the content-based sizing behaviour. ## It Works with Textareas Too `field-sizing: content` isn’t limited to single-line inputs. It also works with ` ``` ```css textarea { field-sizing: content; min-inline-size: 20ch; max-inline-size: min(100%, 60ch); min-block-size: 3.5rlh; max-block-size: 10.5rlh; } ``` The textarea can now grow as content is entered, both horizontally and vertically, until it reaches the available or explicitly defined limits. Once it reaches those limits, normal scrolling takes over. This makes `field-sizing: content` particularly interesting for things like comments, messages and other variable-length form fields. ## Why This Matters What I like about `field-sizing` is that it removes an entire category of JavaScript. The browser already knows how large the content is. It also already knows how form controls should behave when their available space is constrained. There shouldn’t really be a reason for application code to duplicate that logic just to make an input grow with its contents. This is a good example of where the platform is catching up with patterns that developers have been implementing themselves for years. ## A Small but Important Detail There is one thing to keep in mind when using `field-sizing: content`. Without a minimum width, an empty input can become extremely small because there is no content to size it around. For example: ```css input { field-sizing: content; } ``` can result in an empty input being roughly the width of the text cursor. Adding a `min-inline-size` is therefore often a good idea: ```css input { field-sizing: content; min-inline-size: 10ch; } ``` This gives the browser control over the intrinsic sizing while still providing a sensible starting point. ## Browser Support `field-sizing` is now Baseline 2026 and is supported in current versions of Chrome, Edge, Firefox and Safari. This means you can start using `field-sizing: content` in production today, without needing a browser-specific workaround for modern browsers. As with any relatively new CSS feature, older browsers may not support it. In those browsers, the form control simply falls back to its default sizing behaviour, making `field-sizing` a good fit for progressive enhancement. ## Closing Thoughts `field-sizing: content` is a small CSS feature, but it’s exactly the kind of feature I like seeing land in the platform. A common UI behaviour that previously required JavaScript can now be expressed declaratively: ```css field-sizing: content; ``` One line replaces a surprising amount of potential application code. CSS keeps getting better at describing not just how things should look, but how they should behave. And I’m very happy to see this one finally become Baseline. --- ## Using the CSS light-dark() Function for Easy Theme Colors URL: https://rolandfranke.nl/frontend-stories/css-light-dark-color-function A simple introduction to the CSS light-dark() function and how it makes light and dark mode styling much easier. # Using the CSS light-dark() Function for Easy Theme Colors by _Roland_•November 15, 2025 css ## A Simpler Way to Handle Light & Dark Mode For years, switching colors between light and dark mode meant writing two sets of variables or using media queries. Modern CSS gives us something much cleaner: the `light-dark()` function. I’ve been using it on my site since day one, and it has made my color setup much easier to maintain. ## What It Does The `light-dark()` function allows you to define a color that automatically adapts based on the user’s preferred color scheme. Instead of writing separate styles for light and dark modes, you can specify both colors in one place. `light-dark()` takes **two colors** as arguments: - The first color is for light mode. - The second color is for dark mode. ## How to Use It Using `light-dark()` is straightforward. You simply call the function with your desired light and dark colors as arguments. Here’s a quick example: ```css body { background-color: light-dark(#ffffff, #121212); color: light-dark(#000000, #ffffff); } ``` In this example, the background color will be white in light mode and dark gray in dark mode, while the text color will switch from black to white accordingly. ## A Real Example From My Site This is what I originally had: ```css :root { --color-neutral-100: hsl(60 22% 85%); --color-neutral-900: hsl(210 31% 11%); --color-primary-400: hsl(338 73% 45%); } [color-scheme='light'] { --text: var(--color-neutral-900); --surface: var(--color-neutral-100); } [color-scheme='dark'] { --text: var(--color-neutral-100); --surface: var(--color-neutral-900); } ``` Now, with `light-dark()`, I can simplify it to this: ```css :root { --color-neutral-100: hsl(60 22% 85%); --color-neutral-900: hsl(210 31% 11%); --color-primary-400: hsl(338 73% 45%); --text: light-dark(var(--color-neutral-900), var(--color-neutral-100)); --surface: light-dark(var(--color-neutral-100), var(--color-neutral-900)); } ``` Much simpler — the light and dark versions are next to each other, and I don’t need two blocks of duplicated variables anymore. ## Controlling the Color Scheme You can control the color scheme using the `color-scheme` property in CSS or by setting it in HTML attributes. The `light-dark()` function will automatically adapt based on the active color scheme. ```css html { color-scheme: dark light; &[color-scheme='light'] { color-scheme: light; } &[color-scheme='dark'] { color-scheme: dark; } } ``` ## Browser Support As of now, the `light-dark()` function is supported in most modern browsers, including Chrome, Edge, and Safari. However, it’s always a good idea to check the latest compatibility tables to ensure it works for your target audience. ## Conclusion The `light-dark()` function is a powerful tool for simplifying theme management in CSS. By allowing you to define light and dark colors in one place, it reduces redundancy and makes your stylesheets easier to maintain. If you’re working on a site that supports both light and dark modes, give it a try! --- ## CSS Unveils Its New Logo URL: https://rolandfranke.nl/frontend-stories/css-unveils-its-new-logo Rebeccapurple becomes the official CSS logo color! Explore the new repo for formats and future variants, including CSS4, CSS5, and beyond. 💜 # CSS Unveils Its New Logo by _Roland_•November 17, 2024 css ## Introduction CSS has officially embraced a new signature color, and the excitement is real! This update celebrates community involvement, honors a meaningful legacy, and sets the stage for the future of CSS branding. ## Rebeccapurple Takes the Spotlight! The wait is over! With a resounding 400 votes, **rebeccapurple** has been crowned the official logo color for CSS. This milestone reflects the collective input, ideas, and enthusiasm of the CSS community. The choice of rebeccapurple is more than a striking color—it’s a heartfelt tribute to Rebecca Meyer, daughter of web standards advocate Eric Meyer. Her memory continues to shine as rebeccapurple has been an official CSS color since 2014. ## New Repository Explore the [shiny new repository](https://github.com/CSS-Next/logo.css) that hosts the official logo, alternative formats, and upcoming [variants for CSS4, CSS5, and beyond](https://github.com/CSS-Next/logo.css/issues/11). ## Thanks to the Community A huge thank you to everyone who contributed feedback and participated in the voting process—this project truly reflects the community’s collaborative spirit. Special recognition goes to the [CSS Next community group members](https://github.com/orgs/CSS-Next/people). Your creativity, patience, and dedication were the driving force behind this achievement. ## Closing Thoughts The journey of CSS continues, and your support makes it brighter every step of the way. Here’s to a more colorful and inspiring future for web development 💜! --- ## CSS Wrapped 2024 URL: https://rolandfranke.nl/frontend-stories/css-wrapped-2024 Discover how CSS evolved in 2024 with subgrid, anchor positioning, and more, streamlining layouts and boosting developer ergonomics. # CSS Wrapped 2024 by _Roland_•December 9, 2024 cssfrontend ## Introduction 2024 pushed CSS forward in a meaningful way. Not with flashy one-off features, but with improvements that make everyday work simpler — layouts, responsiveness, and component design all got easier to reason about. A lot of that progress comes from the work of the Chrome DevRel team, including Adam Argyle, Bramus, Rachel Andrew, Barry Pollard, and Una Kravets. ## The features that defined 2024 ### Subgrid finally delivers Subgrid removes one of the biggest pain points in Grid. Child elements can now align with parent tracks without hacks or duplication. Layouts become more consistent, especially in complex components. ### Anchor positioning changes how we place UI Positioning elements relative to other elements — not just the viewport — unlocks a lot. Tooltips, popovers, and overlays become easier to build. Less JavaScript, more predictable behavior. ### Container queries grow up Container queries were already useful. Now they’re more flexible. With style queries, components can respond not just to size, but also to context. That makes design systems more adaptable without adding complexity. ### Color gets more precise New color spaces like `lch` and `lab`, combined with color-mix functions, give better control over contrast and consistency. Designing accessible color systems becomes easier and more predictable. ### Scoped styles reduce conflicts Scoping brings styles closer to where they’re used. Less leakage, fewer naming conflicts, and more confidence when working in larger codebases. ### CSS nesting becomes practical Nesting is no longer just a preprocessor feature. The syntax is clearer, more consistent, and easier to use without introducing unnecessary complexity. ## Why this matters These changes aren’t isolated. They work together to reduce friction: - fewer layout hacks - less JavaScript for UI behavior - more predictable components - better defaults for accessibility CSS is becoming more capable, but also easier to reason about. ## Explore more Want to go deeper? Check out the official overview from the Chrome team: [https://chrome.dev/css-wrapped-2024/](https://chrome.dev/css-wrapped-2024/) ## Closing thoughts 2024 didn’t reinvent CSS. It refined it. Many long-standing problems now have native solutions. Things that used to require workarounds are becoming straightforward. That’s where real progress happens — not in new APIs alone, but in making the platform easier to use, one step at a time. --- ## Drawing Connections with CSS Anchor Positioning URL: https://rolandfranke.nl/frontend-stories/drawing-connections-with-css-anchor-positioning A practical exploration of CSS Anchor Positioning and the anchor() function to visually connect related elements without extra markup. # Drawing Connections with CSS Anchor Positioning by _Roland_•January 26, 2026 cssexperimental ## Introduction Every now and then, CSS gets a new feature that makes you pause and think: _wait… we can do **that** now?_ That was exactly my reaction after watching a short by Kevin Powell on **CSS Anchor Positioning**. The idea is deceptively simple: let one element position itself relative to another, without JavaScript, without fragile DOM assumptions, and without extra wrapper elements. Naturally, I had to try it myself. What started as a small experiment turned into a neat little demo that visually connects a comment to its reply using nothing but CSS. ## The Problem Visually connecting related UI elements is surprisingly awkward in CSS. Think of: - Comment threads - Tooltips pointing to triggers - Callouts referencing specific content Traditionally, this meant one of three things: 1. Extra markup just to draw a line or arrow 2. JavaScript calculating positions and injecting styles 3. Giving up and settling for “close enough” Anchor positioning changes that equation. ## Enter Anchor Positioning CSS Anchor Positioning lets you **name an element as an anchor** and then reference its geometry elsewhere using the `anchor()` function. At a high level, the flow looks like this: - Give an element an `anchor-name` - Optionally limit its visibility using `anchor-scope` - Use `anchor()` to position another element relative to it No DOM traversal. No layout math. Just relationships. ## Setting Up the Anchors In my demo, I have two key elements: - `.comment` - `.reply` Each becomes an anchor: ```css .comment { anchor-name: --comment; } .reply { anchor-name: --reply; anchor-scope: --reply; } ``` The names (`--comment`, `--reply`) behave a lot like custom properties: they’re identifiers you can reference later. The `anchor-scope` ensures that only descendants of `.reply` can reference the `--reply` anchor, keeping things predictable and contained. ## Drawing the Connection The fun part happens in a pseudo-element. I use `::after` on the reply to draw a subtle connecting line between the comment and the reply. ```css .reply::after { content: ""; position: absolute; inset-block-start: anchor(--comment end); inset-inline-start: calc(anchor(--comment start) + 1.5rem); inset-block-end: anchor(--reply center); inset-inline-end: anchor(--reply start); border: 1px solid var(--text); border-block-start-color: transparent; border-inline-end-color: transparent; border-end-start-radius: 0.75rem; } ``` This is where the `anchor()` function really shines. ### Reading the Code Each `anchor()` call resolves to a **real layout value** taken from another element: - `anchor(--comment end)` → the block-end edge of the comment - `anchor(--comment start)` → the inline-start edge of the comment - `anchor(--reply center)` → the vertical center of the reply By mixing these with logical properties (`inset-block-*`, `inset-inline-*`) the connection adapts automatically to writing mode and layout changes. No magic numbers. No recalculation when content grows. The line simply follows the elements. ## Why This Is Exciting What I love most about anchor positioning is that it feels like **layout-aware CSS**. Some immediate benefits: - No JavaScript for positioning logic - Relationships stay intact when content changes - Fewer wrapper elements and cleaner markup - Much easier to reason about intent This feels especially powerful for UI patterns where _relationships_ matter more than strict placement. ## Browser Support (Reality Check) The `anchor()` function has recently reached Baseline: **Newly available**, which means it’s supported in the latest versions of major browsers. That said, anchor positioning as a whole is still evolving. While `anchor()` itself is available, related anchor positioning features like `anchor-name` and `anchor-scope` may still be behind flags or rolling out gradually, depending on the browser. In practice, this makes anchor positioning a great candidate for: - Progressive enhancement - Experiments and demos - Forward-looking UI patterns Used carefully, you can start exploring this today while keeping fallbacks in place for browsers that haven’t fully caught up yet. ## See It in Action The full demo lives on CodePen: See the Pen [Tether to multiple elements - Anchor Position](https://codepen.io/ROL4ND909/pen/gbMxLdL) byRoland ([@ROL4ND909](https://codepen.io/ROL4ND909)) on [CodePen](https://codepen.io). If you inspect the code, you’ll notice how little CSS is actually required to make this work. Most of the complexity disappears once the relationship is expressed directly. ## Closing Thoughts Anchor positioning feels like a missing puzzle piece. Instead of asking _“where should this element go?”_ we can finally say _“this belongs **there**, relative to that.”_ This opens the door to patterns like tooltips, popovers, annotations, and visual relationships that stay correct without ever reaching for JavaScript. It’s early days, but features like this make me genuinely excited about where CSS is heading. If you enjoy experimenting with new layout primitives, this one is absolutely worth your time. --- ## Redirecting to: /frontend-stories/exploring-the-new-search-element-in-html/ URL: https://rolandfranke.nl/frontend-stories/exploring-the-new--search-element-in-html [Redirecting from `/frontend-stories/exploring-the-new--search-element-in-html/` to `/frontend-stories/exploring-the-new-search-element-in-html/`](/frontend-stories/exploring-the-new-search-element-in-html/) --- ## Exploring the new search element in HTML URL: https://rolandfranke.nl/frontend-stories/exploring-the-new-search-element-in-html Discover the new element in HTML, how it improves semantics and accessibility, and where to use it in your projects. # Exploring the new search element in HTML by _Roland_•March 19, 2025 htmlaccessibility ## Introduction HTML keeps moving toward better semantics. Small additions, but meaningful ones. The `` element is one of those additions. It doesn’t change how things look or behave, but it does make intent clearer — for browsers, assistive tech, and anyone reading your code. So instead of asking _“what does this do?”_, you can start asking _“does this describe what I mean?”_. ## What `` actually does `` is a semantic container for search-related UI. That’s it. It behaves like a `
`, but with meaning attached. It tells user agents: _this section is for search_. That meaning is what makes it useful. ## Why `` is worth using **It makes intent explicit** You no longer rely on structure alone to imply meaning. The element itself communicates purpose. **It improves accessibility by default** Assistive technologies can recognize a search region without needing extra roles like `role="search"`. **It makes code easier to scan** Search areas stand out immediately in the markup, instead of being buried in generic containers. ## How to use `` Use it as a wrapper around a search form: ```html
``` It doesn’t replace `
`. It complements it. Think of it as adding meaning, not changing behavior. ## Browser Support Support is already solid in modern browsers like Chrome, Edge, and Safari. Older browsers will simply treat `` as a generic block element. No breakage, no visual impact. That makes it safe to use today. ## When to use `` Use it when the intent is clearly search: - Site-wide search (header or navigation) - Filtering or searching within an app - Searching within a specific section (like docs or tables) If it’s not search, don’t use it. ## When not to use it `` is not a replacement for ``. It doesn’t submit data. It doesn’t handle input. It only describes the purpose of what’s inside it. ## Closing thoughts `` is a small addition, but that’s the point. Better semantics rarely come from big features. They come from small, deliberate improvements like this. You don’t need to change how you build forms. You just describe them more accurately. And over time, that clarity adds up in accessibility, in maintainability, and in how we understand the web itself. --- ## Mastering Layouts with CSS Grid URL: https://rolandfranke.nl/frontend-stories/mastering-layouts-with-css-grid Explore my CSS grid system that's kept layouts flexible and responsive for years, with named columns and custom constraints for consistent design. # Mastering Layouts with CSS Grid by _Roland_•November 6, 2024 css ## Introduction I still remember the days of tediously adjusting widths, trying to make layouts work across devices, only to have them fall apart on different screen sizes. My approach needed a change, and this led me to dive deep into CSS Grid. Over time, I adopted a system using named grid lines—a technique that became the backbone of my layouts, making them not only responsive but intuitive and easy to manage. ## Discovering the Problem Initially, I used a more basic layout structure with fixed widths and manual breakpoints. However, as projects grew more complex, this approach led to endless tweaks and adjustments. I needed a system that adapted easily across screen sizes without requiring constant micro-adjustments. That’s when I discovered the potential of CSS Grid’s named grid lines to bring precision and clarity to my layouts. ## The Power of Named Grid Lines One of my earliest realizations was that I could define named grid lines within my CSS, turning each layout section into a clearly defined area. Instead of relying on arbitrary pixel values, I could use names like `fullbleed`, `breakout`, `content` to create meaningful, reusable layouts. Here’s a look at the structure I now use: ```css .grid { display: grid; grid-template-columns: [fullbleed-start] minmax(var(--gutter, 1rem), 1fr) [breakout-start] minmax(0, calc((var(--breakout) - var(--content)) / 2)) [content-start] min(50% - var(--gutter, 1rem), (var(--content) / 2)) [midpoint] min(50% - var(--gutter, 1rem), (var(--content) / 2)) [content-end] minmax(0, calc((var(--breakout) - var(--content)) / 2)) [breakout-end] minmax(var(--gutter, 1rem), 1fr) [fullbleed-end]; } ``` In this setup, each named grid line acts as a landmark, allowing me to place elements precisely in the layout. Named lines like breakout-start or content-end serve as intuitive markers that not only give structure but also make future adjustments simpler and quicker. ## Adding Flexibility with Named Columns Named grid lines allow me to control exactly where elements will start and end within the grid. For instance, using `data-column` attributes, I can effortlessly assign content to a column, making my code cleaner and my layout more adaptable: ```html

This content will span the content column.

This container will span the breakout column.
``` ```css [data-column='breakout'] { grid-column: breakout; } ``` With this approach, each section of my layout naturally falls into its place, guided by the named grid lines. The layout remains flexible without requiring hard-coded widths, allowing it to adjust fluidly as screen sizes change. ## Achieving Full-Bleed Layouts One of the most powerful uses of named grid lines has been creating full-bleed sections that span the entire viewport width. By assigning the `data-column='fullbleed'` attribute, I can ensure that specific elements extend beyond the usual column constraints, perfect for hero sections or background images that demand extra visual impact. What’s even more beneficial is that within this full-bleed section, I can apply the same grid structure with named lines, making it a grid within a grid. This means that even in a full-width layout, the internal content can still align to the established grid, giving me control over precise positioning while preserving the visual harmony with the rest of the page. ```css [data-column='fullbleed'] { grid-column: fullbleed; grid-template-columns: subgrid; } ``` Using `subgrid` here lets the full-bleed section inherit the parent grid’s structure, so any elements within it align consistently with the named lines defined in the main layout. This approach ensures that even my full-width elements don’t disrupt the layout flow; they simply extend beyond it while maintaining the familiar structure inside. ### Explore the Complete Grid System in Action See the Pen [CSS Grid with Named Grid Lines](https://codepen.io/ROL4ND909/pen/oNKaywm/852225a5e1bd6e8bd566ecb77093cc8f) byRoland ([@ROL4ND909](https://codepen.io/ROL4ND909)) on [CodePen](https://codepen.io). ## Conclusion Named grid lines have turned CSS Grid into a tool I rely on in every project. They give me control over layout placement, enable intuitive adjustments, and allow each element to “know” its place in the structure. Using this system has saved me hours of trial and error, and it’s become a key part of my development toolkit. I encourage anyone looking to create robust, adaptable layouts to try using named grid lines—they might just change the way you think about layout design. This journey has been a rewarding one, and I hope sharing my experience with named grid lines inspires you to experiment and build something equally adaptable and reliable. --- ## My Interop 2027 CSS Wishlist: 10 Features URL: https://rolandfranke.nl/frontend-stories/my-interop-2027-css-wishlist My personal CSS wishlist for Interop 2027, from scroll-driven interfaces and better layouts to smoother transitions and customizable form controls. # My Interop 2027 CSS Wishlist: 10 Features by _Roland_•October 15, 2026 css ## Intro CSS keeps getting better. Features that once required JavaScript, extra markup, or complicated workarounds are becoming possible with a few lines of CSS. But having a feature in one browser isn’t enough. I want to use modern CSS without constantly checking which browser supports it or building fallbacks for every other engine. With Interop 2027 on the horizon, here are ten CSS features I’d love to see become more interoperable. This is my personal wishlist, ranked by how much I want to use these features in everyday frontend development. ## 1\. [CSS Container Scroll-State Queries](https://github.com/web-platform-tests/interop/issues/1364) Container queries already let us adapt a component to the space available to it. Scroll-state queries take this a step further by allowing styles to respond to the scroll state of a container. For example, imagine a sticky header that changes its appearance once it becomes stuck, or a component that reacts when its scroll container reaches a particular state. ```css .sticky-header { position: sticky; top: 0; container-type: scroll-state; } @container scroll-state(stuck: top) { .sticky-header { box-shadow: 0 2px 8px rgb(0 0 0 / 10%); } } ``` No scroll event listeners. No JavaScript checking positions on every scroll. Just CSS responding to the state of the layout. This is exactly the kind of functionality I want to see working consistently across browsers. ## 2\. [Scroll-Triggered Animations](https://github.com/web-platform-tests/interop/issues/1433) Scroll-driven animations are already an exciting addition to CSS, but I want to see scroll-triggered animations become a dependable part of the platform too. Think about revealing an element when it enters the viewport, animating a section as the reader reaches it, or triggering a visual effect at a specific point in an article. These interactions are common on modern websites, yet they often rely on JavaScript and `IntersectionObserver`. I’d love to build more of these experiences directly in CSS, with predictable behavior across browsers and without having to maintain custom JavaScript for every animation. The goal isn’t to animate everything. It’s to make the animations we do need easier to build and maintain. ## 3\. [CSS Scroll Markers](https://github.com/web-platform-tests/interop/issues/1406) Carousels are everywhere, but their navigation controls can require quite a bit of extra markup and JavaScript. CSS scroll markers offer a more declarative approach. With features such as `::scroll-marker` and `::scroll-marker-group`, we can create navigation markers for items in a scroll container and style them with CSS. Imagine a carousel where the browser handles the relationship between the slides and their navigation markers, including which marker represents the current target. ```css .carousel { overflow-x: auto; scroll-snap-type: x mandatory; } .carousel > * { scroll-snap-align: start; } ``` The example above is already useful on its own. Scroll markers could take it further by providing the navigation UI without requiring us to build and synchronize a separate set of controls. I’d love to see this become a reliable option for accessible, CSS-first carousels. ## 4\. [CSS `line-clamp`](https://github.com/web-platform-tests/interop/issues/1379) Sometimes a card title or description needs to fit within a fixed number of lines. A consistent card layout is difficult to achieve when one description takes up two lines and another takes up six. The `line-clamp` property provides a straightforward way to limit the number of lines displayed. ```css .card-description { line-clamp: 3; } ``` That’s much easier to read than older combinations of properties and browser-specific workarounds. What I want from Interop 2027 is consistent support and behavior, so I can use this property without worrying about differences between browsers. One important detail: clamping should remain a presentation decision. The full content should still be available when users need it, especially when the text contains important information. ## 5\. [CSS Grid Lanes](https://github.com/web-platform-tests/interop/issues/1445) Masonry layouts have been a long-standing challenge for CSS developers. We can approximate them using columns, JavaScript libraries, or carefully designed grid layouts, but each approach comes with trade-offs. CSS Grid Lanes aims to bring masonry-style layouts closer to the native CSS Grid model. This would be particularly useful for card collections, image galleries, and other layouts where items have different heights. Instead of relying on JavaScript to calculate positions or using a layout technique that changes the visual order, I’d like to be able to describe the layout in CSS and let the browser handle the rest. For component libraries and design systems, a native solution would also mean less custom code to maintain. This is one of the features I’m most excited about. A reliable, interoperable masonry solution would be a welcome addition to everyday CSS. ## 6\. [CSS Gap Decorations](https://github.com/web-platform-tests/interop/issues/1374) CSS Grid and Flexbox make it easy to create layouts with gaps between items. But what if I want to draw a line through those gaps? Today, that often means adding borders to individual items, introducing pseudo-elements, or creating additional markup. Those solutions can become complicated when items wrap or the layout changes responsively. Gap decorations aim to make it possible to draw lines directly within the gaps of grid and flex layouts. For example, a grid could have separators between its rows and columns without every individual card needing to manage its own borders. This would be especially useful for data-heavy layouts, navigation, and component libraries where consistent spacing and separators are part of the design system. I’d love to see this become a native styling capability rather than another problem we have to solve separately for every layout. ## 7\. [Transitions for `display` and `content-visibility`](https://github.com/web-platform-tests/interop/issues/1384) Animating an element’s opacity or transform is straightforward. Making an element appear or disappear smoothly is a different story. Properties such as `display` and `content-visibility` have discrete behavior, which means they don’t transition in the same way as properties such as `opacity`. CSS has already made progress here with `transition-behavior: allow-discrete` and `@starting-style`. ```css .dialog { opacity: 0; display: none; transition: opacity 200ms ease, display 200ms allow-discrete; } .dialog.is-open { opacity: 1; display: block; } @starting-style { .dialog.is-open { opacity: 0; } } ``` This makes entry and exit transitions much easier to implement without JavaScript managing animation timing. However, support for transitions involving `display` and `content-visibility` still differs between browser engines. I’d like to see these capabilities become more consistent, so we can build smoother interfaces while keeping the underlying CSS simple. ## 8\. [Custom Properties in Size Container Queries](https://github.com/web-platform-tests/interop/issues/1344) CSS custom properties are incredibly useful for sharing values across components and stylesheets. Unfortunately, they can’t currently be used everywhere we’d like, including as values in size container query conditions. Imagine defining a breakpoint once and reusing it in multiple container queries. ```css :root { --card-breakpoint: 30rem; } @container (width > var(--card-breakpoint)) { .card { display: grid; grid-template-columns: 1fr 2fr; } } ``` The example illustrates the syntax I’d like to be able to use. It isn’t currently valid CSS because `var()` cannot be substituted into a size container query condition. Being able to use custom properties here would make responsive component styles more consistent and easier to maintain. For design systems with multiple components sharing the same responsive rules, this could reduce duplication and make changes much easier to manage. It’s not the flashiest feature on this list, but it’s the kind of improvement that could make a real difference to my daily work. ## 9\. [`flex-wrap: balance`](https://github.com/web-platform-tests/interop/issues/1350) Flexbox is great for arranging items in a row and allowing them to wrap when there isn’t enough space. But the resulting distribution isn’t always what we want. Imagine a group of navigation items, tags, or buttons wrapping onto multiple lines. Depending on the available width, the final line might contain just one item while the previous lines are much more crowded. A balanced wrapping option could help distribute items more evenly across lines. ```css .tag-list { display: flex; flex-wrap: balance; gap: 0.5rem; } ``` This illustrates the behavior I’d like to have available, rather than syntax you can use in browsers today. The idea is simple: let the browser find a more balanced distribution instead of relying on carefully chosen widths or JavaScript to rearrange the items. I’d find this particularly useful for responsive components where the content is dynamic and the number or size of items can change. ## 10\. [Customizable `` to match a design system has traditionally been difficult. That’s why customizable select elements are on my wishlist. The newer CSS capabilities around customizable selects allow developers to take more control over the appearance of the control and its picker while retaining the native HTML element. For example, the newer `appearance: base-select` approach opens up styling possibilities that weren’t previously available with a traditional select. ```css select, ::picker(select) { appearance: base-select; } ``` This is only the starting point. The real appeal is being able to style the button, options, picker, and selected state much more freely. I’d love to see this work consistently across browsers. It could make building accessible form controls that fit a design system considerably easier, without immediately reaching for a custom JavaScript component. Of course, native semantics and keyboard interaction still matter. More styling freedom should make accessible controls easier to build, not easier to break. ## Closing Thoughts My Interop 2027 wishlist is mostly about making CSS more capable and more dependable. I want better control over scroll-driven interfaces, more flexible layouts, simpler transitions, and more styling freedom for everyday elements. Most importantly, I want to use these features without having to wonder whether they’ll behave differently in another browser. Some of these features are already usable in certain browsers, while others still need more work. Interop isn’t necessarily about inventing new CSS. It’s about making existing and emerging features work consistently across browser engines. If even a few of these make meaningful progress in Interop 2027, that would be a win for frontend developers. What CSS feature would make your own wishlist? --- ## Scroll snap api suggestion URL: https://rolandfranke.nl/frontend-stories/scroll-snap-api-suggestion "Snapflyover" describes elements briefly entering but not stopping in the snap zone, providing visual or interactive feedback during scroll snapping. # Scroll snap api suggestion by _Roland_•August 27, 2024 cssjs ## Describing the State This state could be described as a “transitory snap” or “flyover snap.” It’s a state where elements are momentarily in the snap zone but aren’t selected as the final snap target. The key focus is on recognizing that these elements have passed through a significant area that could be important for visual feedback or interaction. ## Naming the Event Given the behavior and the intent, here are some potential names and their reasoning: 1. `snapflyover:` This directly conveys the idea that the element “flies over” the snap zone without being snapped to. It’s descriptive and implies a transient interaction. 2. `snaptransit:` Suggests that the element is in transit across the snap area, signaling that it’s just passing by rather than stopping. 3. `snapcross:` Indicates that the element has crossed into or through the snap area but didn’t settle there. 4. `snaphover:` Evokes the idea of the element hovering or passing over the snap area momentarily. However, this could be confusing with traditional “hover” events in CSS, which are related to pointer events. 5. `snapintersect:` Suggests that the element has intersected the snap area, emphasizing the geometric or positional relationship rather than the action of snapping. ## Is This Still a Snap Event? Yes, it’s still related to snapping, but it’s more of an interim or auxiliary snap event. It adds a finer level of control and feedback in the snapping process, especially for cases where visual or interactive feedback is needed as elements scroll through the snap zone. ## Closing thoughts Out of the options, `snapflyover` seems to be the most intuitive and descriptive for what you’re trying to achieve. It clearly conveys the idea that the element is moving over the snap area without stopping there, which matches your use case well. If you wanted to focus more on the idea of the event being triggered as the element intersects the snap area, then `snapintersect` could be a good alternative. It’s a bit more technical but might resonate well with developers. --- ## Scroll Spy with Pure CSS using scroll-target-group URL: https://rolandfranke.nl/frontend-stories/scroll-spy-with-pure-css How the new CSS scroll-target-group and :target-current let you build a table of contents scroll spy without JavaScript. # Scroll Spy with Pure CSS using scroll-target-group by _Roland_•April 9, 2026 cssexperimental ## Introduction Scroll spy navigation highlighting a table of contents link based on what section is visible has traditionally required JavaScript. You needed scroll listeners or an `IntersectionObserver` to watch positions and update state as the user scrolls. That’s no longer strictly true. With the new CSS `scroll-target-group` property and the `:target-current` pseudo-class, the browser can handle active link tracking _natively_, letting you build scroll spy navigation using only HTML and CSS. I recently applied this on my this site for the TOC ## The Scroll Spy Setup Below is the general pattern I used, inspired by the basic usage examples of `scroll-target-group`. ### HTML Structure Your page has multiple content sections with unique IDs. Your TOC links point to those sections: ```html
…
…
…
``` This markup forms the basis of your scroll-spy. Because each nav link points to a corresponding heading section, the browser can automatically track which section is in view. ### Turn the TOC into a `scroll-target-group` To enable CSS scroll tracking, you mark the container of your navigation links as a _scroll marker group container_: ```css ol { scroll-target-group: auto; } ``` This tells the browser: > “This container holds scroll markers linked to content sections, group them and track which one is active.” Once that’s done, the browser internally watches scroll positions and figures out which target section is “current”. ### Style the Active Link with `:target-current` Native scroll spy magic comes from the `:target-current` pseudo-class. Within your scroll marker group container, the `` link whose section is currently in view gets `:target-current` applied automatically. To highlight it, you just style that state: ```css a:target-current { color: red; font-weight: bold; } ``` There’s no JS toggling classes, no event listeners, and no IntersectionObserver the browser handles it all. ## Why This Matters This is the same basic pattern shown in the MDN example for `scroll-target-group`, where an ordered list of links becomes a scroll marker set and the browser highlights whichever is current as the user scrolls. But by plugging in your own HTML structure your actual TOC and page sections you get a real, production-ready scroll spy. With this setup: - Your TOC highlights the current section automatically - Styling stays fully declarative - You can keep your JavaScript bundle lean ## My Implementation Notes On my own site: - I applied this only on screens wider than 848px, where a persistent TOC makes sense - The feature works in Chromium-based browsers (Chrome, Edge) as progressive enhancement - On unsupported browsers, the TOC is not shown at all, so it doesn’t break the experience This aligns with the current experimental status of `scroll-target-group` it’s available in the latest Chromium engines but not yet in all browsers. ## Progressive Enhancement Since not every browser supports this yet, wrap your styles in a feature query: ```css @supports (scroll-target-group: auto) { ol { scroll-target-group: auto; } a:target-current { color: red; font-weight: bold; } } ``` This ensures older browsers don’t break, while capable ones get the native scroll spy experience. ## Browser Support This means the feature is great for _progressive enhancement_ add it where it’s supported, and fall back where it’s not. ## Closing Thoughts “Scroll spy” used to require a handful of JavaScript and careful scroll tracking logic. Now, you can express it entirely as a relationship between links and sections, and let the browser handle the rest. This move toward _declarative interaction_ in CSS feels like a big step forward for UI patterns that were once inherently imperative. Keep an eye on this as browser support broadens, CSS-only scroll spy might become the default approach for in-page navigation going forward. --- ## Sitemap URL: https://rolandfranke.nl/sitemap Sitemap of Roland Franke's personal website, listing all pages and frontend stories for easy navigation. # Sitemap This sitemap is generated automatically based on the site's structure. It includes all static pages and frontend stories, organized for easy navigation. - [Home](/) - [Frontend Stories](/frontend-stories/) - [My Interop 2027 CSS Wishlist: 10 Features](/frontend-stories/my-interop-2027-css-wishlist/) - [A CSS Reading Progress Bar That Tracks the Article](/frontend-stories/a-css-reading-progress-bar-that-tracks-the-article/) - [CSS field-sizing: content Is Finally Baseline](/frontend-stories/css-field-sizing-content/) - [Scroll Spy with Pure CSS using scroll-target-group](/frontend-stories/scroll-spy-with-pure-css/) - [Drawing Connections with CSS Anchor Positioning](/frontend-stories/drawing-connections-with-css-anchor-positioning/) - [Using the CSS light-dark() Function for Easy Theme Colors](/frontend-stories/css-light-dark-color-function/) - [Exploring the new search element in HTML](/frontend-stories/exploring-the-new-search-element-in-html/) - [CSS Wrapped 2024](/frontend-stories/css-wrapped-2024/) - [CSS Unveils Its New Logo](/frontend-stories/css-unveils-its-new-logo/) - [Mastering Layouts with CSS Grid](/frontend-stories/mastering-layouts-with-css-grid/) - [CSS display masonry](/frontend-stories/css-display-masonry/) - [Scroll snap api suggestion](/frontend-stories/scroll-snap-api-suggestion/) - [About](/about/)