Mert Özen Further With Every Line

Blog

Mert Özen's blog posts on software development, backend, frontend, and DevOps.

Series
8 posts found
The Utility-First Approach: What Tailwind Solves, What It Costs and When Not to Use It
Frontend PART 01

The Utility-First Approach: What Tailwind Solves, What It Costs and When Not to Use It

Utility-first writes styles inside the component with small, token-bound classes; the CSS grows with the number of distinct classes rather than components, and the price is long class lists and a learning curve. We measure the CSS and HTML cost of both models on three Bookstore components, solve repetition with a Razor partial, and show why @apply is the last resort, what Preflight does to CMS content and why unlayered legacy CSS overrides utilities.

15 Nov 2026 13 min 3
Setting Up Tailwind v4 and CSS-First Configuration: @import "tailwindcss", @source and the Oxide Engine
Frontend PART 02

Setting Up Tailwind v4 and CSS-First Configuration: @import "tailwindcss", @source and the Oxide Engine

In Tailwind v4 the configuration lives in CSS: @import "tailwindcss" puts theme, Preflight and utilities into three layers, and the Oxide engine scans sources as plain text and generates only classes whose full name it sees. We build the input.css → site.css chain in Bookstore.Web with the CLI, --watch and --minify, show why site.css returns 404 after a clean publish with BeforeTargets="Build", how .gitignore affects scanning, @source not/inline, and dynamic colors with --cat-color.

15 Nov 2026 13 min 8
Themes and Design Tokens: @theme Namespaces, Custom Colors/Fonts/Breakpoints and Dark Mode
Frontend PART 03

Themes and Design Tokens: @theme Namespaces, Custom Colors/Fonts/Breakpoints and Dark Mode

Every variable in a @theme block produces both a utility and a CSS variable on :root; the variable's namespace decides which utility appears. In Bookstore.Web we define brand tokens, compare extending the default theme with resetting it via --color-*: initial, measure why @theme inline is needed for per-institution colors and what @theme static does, build flash-free dark mode with semantic variables and a head script, and generate @theme from DTCG tokens with Style Dictionary.

15 Nov 2026 12 min 7
Variants, Custom Utilities and Modern CSS: group/peer, data-*/aria-*, @container, starting:, @utility and @variant
Frontend PART 04

Variants, Custom Utilities and Modern CSS: group/peer, data-*/aria-*, @container, starting:, @utility and @variant

Every Tailwind variant adds a selector or an at-rule; group-hover also reacts to an outer group's hover when groups are nested, which is why named groups like group/card are needed. With Bookstore's filter and card examples we measure peer, has-*, not-*, in-*, headless styling with aria-expanded and data-[state], @container and v4.3's @container-size, a popover animation with starting:, logical and scrollbar utilities, @utility (--default), @variant and @custom-variant in Playwright.

15 Nov 2026 11 min 5
Tailwind with Angular: ng add tailwindcss, @reference in Component Styles, Dynamic Classes and Headless Components
Frontend PART 05

Tailwind with Angular: ng add tailwindcss, @reference in Component Styles, Dynamic Classes and Headless Components

In Angular, Tailwind runs on the global styles.css; component CSS is processed separately, so @apply needs @reference there and carries fallback values and @property blocks into every component. In bookstore-web we show what ng new --style tailwind and ng add do, the bundle and build cost of @reference across 40 components, why Tailwind syntax breaks in SCSS, dynamic classes with full names and signals, and styling an Angular Aria Listbox with aria-selected.

15 Nov 2026 12 min 9
Scale, Maintenance and Versions in Tailwind: Component Patterns, Class Sorting, tailwind-merge and Migrating from v3 to v4
Frontend PART 06

Scale, Maintenance and Versions in Tailwind: Component Patterns, Class Sorting, tailwind-merge and Migrating from v3 to v4

Of two conflicting utilities, the one later in the CSS wins, not the one written later in the class attribute; so components should expose variants through a class map with full names and merge outside classes with tailwind-merge. We build this into bookstore-web's button, show tailwind-merge's custom token pitfall and Prettier sorting, measure with Playwright what npx @tailwindcss/upgrade converts and misses on a v3 page, and lay out the v4.0–v4.3 release map.

15 Nov 2026 12 min 6
Everyday Utility Families 1: Layout, Flex, Grid, Spacing, Sizing and Position Utilities
Frontend PART 07

Everyday Utility Families 1: Layout, Flex, Grid, Spacing, Sizing and Position Utilities

Tailwind's layout utilities map one to one onto CSS, and numeric values derive from a single --spacing variable; the hard part is knowing which CSS to pick. We build Bookstore's catalog grid, book card and two-column cart page both with utilities and with plain CSS, compare the boxes of both pages at three widths in Playwright (0px difference), and measure space-x breaking on wrapping rows, a missing min-w-0 and the difference between auto-fill and auto-fit.

15 Nov 2026 12 min 8
Everyday Utility Families 2: Typography, Color, Border, Shadow, Effect, Transform and Form Utilities, the typography and forms Plugins
Frontend PART 08

Everyday Utility Families 2: Typography, Color, Border, Shadow, Effect, Transform and Form Utilities, the typography and forms Plugins

In Tailwind v4, border and ring default to currentColor, ring is 1px, scale/rotate/translate write to the individual transform properties, and once @tailwindcss/forms is added accent-* no longer paints the checkbox. We measure the hover shadow and cover scale on Bookstore's book card, grayscale for out-of-stock books, native controls versus the forms plugin on the checkout form, and the prose class on a CMS body in Playwright.

15 Nov 2026 13 min 7
Blog Map