Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
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.
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.
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.
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.
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.
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.
TypeScript 7 and Beyond: The Go-Based Compiler and the New Defaults
We look at the Go-based TypeScript 7 compiler, the defaults that came with 6.0, the settings removed in 7.0, isolatedDeclarations, the TC39 Type Annotations proposal and what the 7.1 beta brings.
Migrating from JavaScript to TypeScript: checkJs, JSDoc and Gradual strict
We walk through migrating a JavaScript project to TypeScript gradually: allowJs, checkJs and // @ts-check, writing types with JSDoc, the JSDoc changes in TypeScript 7, gradual strict and @ts-expect-error.
Type-Level Programming in TypeScript: Solving the Easy type-challenges
We solve ten easy type-challenges (MyPick, MyReadonly, TupleToObject, First, Length, MyExclude, MyAwaited, If, Concat, Includes), each checked with type-level tests built on Equal and Expect.
using and await using in TypeScript: Resource Management with Symbol.dispose
We look at the TypeScript side of using and await using from TS 5.2: the Disposable types, the lib setting you need, the compiler's checks, DisposableStack, and what tsc's output means for Node and Safari.
Decorators in TypeScript: Standard TC39 Decorators and the context Object
We look at the standard decorators that arrived in TS 5.0: method, class, field and accessor decorators, the context object, why they aren't erasable and how they differ from the old experimentalDecorators setting.
Branded Types in TypeScript: Keeping CustomerId and OrderId Apart
Where structural typing can't tell apart values with the same shape but different meaning, we use brands, produce them with validation functions and build a sturdier Brand helper with unique symbol.