Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
There Is No "CSS4": CSS Snapshots, Baseline, Interop and What Arrived 2023–2026
CSS has no version number: modules raise their own levels independently, and the W3C's CSS Snapshot 2025 states plainly that there is no CSS Level 4. Whether to use a feature is decided with Baseline (newly and widely available), Interop and @supports; the post builds the 2023–2026 chronology from web-features and compares the browser targets of Angular, Vite and Tailwind on Bookstore.
Anchor Positioning: Tooltips, Dropdowns and Popovers Without JavaScript
Anchor positioning places an element relative to another with CSS; a popover opened by a button takes that button as its anchor, and position-area with flip-block gives a menu and a preview without JavaScript. Its core became Baseline with Firefox 147 in January 2026; web-features shows 'limited' today because the position-visibility values were renamed.
Scroll-Driven Animations and View Transitions
animation-timeline with scroll() and view() takes an animation's progress from the scroll position instead of time and has been Baseline since October 2026; view transitions animate a DOM change between two snapshots. The post adds a reading progress bar, cards that appear as they scroll in, a sorting animation, withViewTransitions() in Angular and cross-document transitions, which Firefox lacks, to Bookstore.
Transitions and Animations: @keyframes, Easing, @starting-style and prefers-reduced-motion
A dialog opening from display: none has no previous style, so @starting-style must give the transition a starting value, and closing needs allow-discrete on display and overlay. The post measures the difference between transitions and animations, easing including linear(), why transform and opacity are cheap, and reducing motion with prefers-reduced-motion on Bookstore's cart dialog.
Native CSS Nesting and @scope: Component Styles Without a Preprocessor
Native CSS nesting makes writing shorter but isolates nothing; @scope makes a rule apply from a scope root down to a limit and keeps user content out with a donut scope. We rewrite the Bookstore card with nesting and prove with a computed-style hash that nothing changed, and measure how & differs from Sass, the specificity coming from :is(), proximity, and a comparison with Angular, ASP.NET Core CSS isolation and Shadow DOM.
Modern Color and CSS Math: oklch(), color-mix(), Relative Color, contrast-color() and Math Functions
oklch() measures lightness the way the human eye perceives it, so a yellow and a blue with the same L look equally bright, while in HSL the contrast of white text ranges from 1.07 to 8.59. We derive shades from Bookstore's category colour with relative colour, color-mix() and alpha(), and measure the limit of contrast-color(), round/mod/rem, progress() and typed arithmetic, and the not-yet-Baseline if(), @function and random().
Custom Properties and Theming: var(), @property and Dark Mode with light-dark()
Custom properties live at run time inside the cascade and inheritance; for a dark theme it is enough to define the colour tokens with light-dark() and switch color-scheme. On Bookstore we measure the var() fallback, the invalid at computed-value time trap, typed and animatable variables with @property, an inline script that remembers the user's choice in localStorage without a flash of the wrong theme, and a category colour coming from the CMS.
Container Queries: Size Queries, Style Queries and Component-Based Responsive Design
A container query lets a component change its layout based on the width of the box it is placed in rather than the viewport; but container-type turns subgrid off, so the two cannot be used on the same element. We show the Bookstore card horizontal in a wide band and vertical in a narrow column, and measure cq units, the name-only and style queries that became Baseline in May 2026, and making an Angular host a container, in Chromium and WebKit.
Responsive Design: Mobile-First, Media Query Range Syntax, Fluid Typography with clamp() and User Preferences
A responsive page is written mobile-first, its breakpoints are chosen from the content in rem, and font sizes go inside clamp() as the sum of a rem and a vw; a heading that uses only vw does not grow at all under zoom. On Bookstore we measure, in Chromium and WebKit, the range syntax, why rem in a media query ignores the page's root font size, zoom, prefers-reduced-motion, prefers-contrast, prefers-color-scheme and hover/pointer.
CSS Grid 2: Subgrid, Alignment and the "Grid or Flexbox?" Decision
Subgrid lets a card borrow its rows from the list instead of working them out itself, so the title, author and price rows of cards with titles of different lengths line up. We move the Bookstore catalog to subgrid, measure the justify/align and place-* properties, choose between Grid and Flexbox with the content-out versus layout-in rule, and look at where grid-lanes stands for masonry in November 2026.
CSS Grid 1: Tracks, fr, repeat(auto-fill, minmax()) and Named Grid Areas
repeat(auto-fill, minmax(14rem, 1fr)) builds a responsive grid without media queries by creating as many columns as fit the container; auto-fit collapses the empty columns to zero and stretches the items. We build Bookstore's catalog grid and page skeleton with Grid, and measure in Chromium and WebKit the difference between fr and minmax(0, 1fr), the implicit grid, named lines, grid-template-areas and how dense breaks the DOM order.
Flexbox: One-Dimensional Layout, flex-grow/shrink/basis and Real-World Scenarios
Flexbox hands out free space by flex-grow and takes away missing space weighted by flex-shrink × flex-basis, so the larger item shrinks more. We lay out Bookstore's header, catalog cards and coupon field with Flexbox, and measure in Chromium and WebKit what the flex shorthands expand to, the min-width: auto trap that pushes a long book title out of its line, and the fact that order does not change the Tab sequence.