Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
How HTML Works: The Living Standard, Document Structure and the Forgiving Parser
HTML has no version: the WHATWG's continuously updated Living Standard is the reference, and Baseline tells you whether you can use a feature. In this post we look at the minimal valid document, the element/attribute/void element/content model concepts and how the parser silently repairs broken markup, with real DOM output from Chromium and WebKit, and catch the errors with the Nu Html Checker.
Semantic HTML and Landmarks: header, nav, main, article, section, aside, footer and search
Semantic elements turn into landmarks in the accessibility tree; but an unnamed section does not become a region, a header inside an article does not become a banner, and an h1 inside a section is still level one. In this post we move Bookstore's book detail page from div soup to a semantic structure, read every step from Chromium's accessibility tree, and settle the section/article/div decision, the search element, the single main rule and heading hierarchy without an outline algorithm.
Text Semantics: Headings, Paragraphs, Lists, Links, Buttons and Inline Elements
Something that takes the user to another address is an a, something that performs an action on the page is a button; href="#" and a clickable div work only partly or not at all with a keyboard. In this post we look at strong/em versus b/i, book details with dl, time, abbr, code/kbd/samp, blockquote/q/cite and figure in Chromium's accessibility tree, measure link versus button with a real keyboard test, and check the implicit noopener behaviour of target="_blank" in two engines.
HTML Forms 1: Input Types, label, fieldset, autocomplete and inputmode
The foundation of an accessible, quickly filled form is a visible label on every field, the right input type and the autocomplete tokens from the spec; type="number" loses the leading zero of a postal code, and a button without a type submits the form. In this post we build Bookstore's checkout form with fieldset/legend, inputmode, enterkeyhint, autocorrect (Baseline 2026-09) and the form attribute, measuring every behaviour with a real test in Chromium.
HTML Forms 2: Native Validation, Constraint Attributes, :user-invalid and the Split with the Server
The browser enforces required, pattern, min/max and input type rules without JavaScript, but this validation is for user experience, not security; for error styling, use :user-invalid, which matches only after the user interacts, instead of :invalid. In this post we measure in Chromium and WebKit that native messages follow the browser's language, formnovalidate, the pattern that rejects "Şule" and the v flag trap, and a textarea that grows with field-sizing.
Native Interactive Elements 1: details/summary, dialog, popover and Invoker Commands
Modals, popovers and accordions are now in HTML: with Invoker Commands (command/commandfor, Baseline 2025-12), dialogs and popovers open and close without a line of JavaScript, and the browser manages focus and inert. In this post we measure Bookstore's "Delete book" confirmation, mini cart and FAQ accordion in Chromium, and cover the returnValue trap, requestClose(), :open, and closedby, popover="hint" and hidden="until-found", which Safari lacks, as progressive enhancement.
Native Interactive Elements 2: select, datalist, Customizable Select and output/progress/meter
Use select for a choice and datalist for suggestions: datalist submits values outside its list, and a required select treats only a first option with value="" as a placeholder. In this post we measure a catalog filter, a customizable select with cover images via appearance: base-select (Chrome 135 and Safari 27, not Firefox) and output/progress/meter in Chromium and WebKit, and show the disabled placeholder trap and the output that is never submitted.
Images and Media: img, picture, srcset/sizes, video, audio, track and iframe
Give every img a width and height, choose alt by the image's job on the page, pair srcset with sizes when the image size changes with the screen, and never put loading="lazy" on an image on the first screen. In this post we measure these rules in Chromium and WebKit: a 0.14 layout shift from an image without dimensions, sizes="auto", AVIF/WebP/JPEG XL order in picture, the half-second delay of a lazy LCP image, subtitles with track and the iframe title.
The head and Meta Tags: charset, viewport, title, description, Open Graph, theme-color and link rels
A good head starts with meta charset, carries a single viewport that does not disable zoom, a page-specific title and one description, and puts Open Graph tags in the HTML from the server. In this post we measure that a page without a charset breaks Turkish characters, that a phone lays out a page without viewport at 980 pixels, that bots miss Open Graph added with JavaScript, color-scheme, and repeated meta tags in a Razor layout, with the Nu Html Checker and axe.
Tables and Tabular Data: caption, thead, th scope, colgroup and Responsive Tables
A data table gets its name from caption and its row and column relationships from th scope; on a narrow screen it goes into a scrollable wrapper with tabindex, role="region" and a name. In this post we read Bookstore's order history in the accessibility tree and measure that text-align on col does nothing, a headers/id bug, WebKit not focusing a plain wrapper, and how an Angular row using a host element instead of tr empties the table.
Accessible Markup Basics and HTML in Frameworks: Native First, the Accessibility Tree, Angular Host Elements and Razor
Accessible markup starts with native elements first, choosing hidden or inert to hide things, avoiding positive tabindex, setting lang and dir correctly, and reading the HTML your framework produces from the browser's output. In this post we measure a focusable button inside aria-hidden, the capital İ that changes with lang="tr", Angular host elements inside ul without list items and Razor Tag Helpers that produce no aria-invalid, and put angular-eslint and the Nu Html Checker into CI.
What Arrived in HTML 2023–2026: search, popover, Invoker Commands, Customizable Select and What's Next
HTML has no versions, only Baseline dates: between 2023 and 2026, search, inert, exclusive details, popover, requestClose, Invoker Commands, :open and autocorrect became Baseline; but because Angular 22 targets widely available, only search and inert work in every browser it supports. In this post we lay out the timeline, the features not yet Baseline, Interop 2026, and a decision table for Bookstore built from web-features data.