Sign in

Stephen Margheim

@fractaledmind.bsky.social
1.4K followers 190 following 710 posts
PostsRepliesMedia
Stephen Margheim @fractaledmind.bsky.social · 10/01/2026
As soon as I saw the Bloom component from Josh Puckett, I knew I had to build it with plain HTML and CSS. This one was tricky, I won't lie, but a lot of fun. May just add this as an affordance to HTML UI, we shall see.
1100
Stephen Margheim @fractaledmind.bsky.social · 08/01/2026
Same olʼ <dialog>, completely new CSS. HTML UI will have dialog sheets inspired by Silk React components. No JS, no swipe gestures, but still gorgeous sheets with elegant animations. Just a <dialog class="ui-sheet"> away ✨
1160
Stephen Margheim @fractaledmind.bsky.social · 06/01/2026
"Why does this matter?" you ask. Because "fancy" focus styles that use both a `ring` and an `outline` with an offset need a way to make the offset region look transparent, and yo can't simply use `transparent`. You need to know the surface color. play.tailwindcss.com/MTO1Wfq8qK
110
Stephen Margheim @fractaledmind.bsky.social · 06/01/2026
play.tailwindcss.com/MTO1Wfq8qK
000
Stephen Margheim @fractaledmind.bsky.social · 05/01/2026
Which of these buttons do you like more, and why? Each has a subtle 3d effect, but done in three different ways. Shown here at 1x, 2x, and 8x.
Three large rounded dark-gray buttons stacked vertically labeled "Button 1", "Button 2", "Button 3" on a charcoal background.Three stacked rounded rectangular buttons labeled Button 1, Button 2, Button 3 with subtle different 3D shading on a dark gray background.Three centered, dark-gray rounded rectangular buttons stacked vertically, each labeled "Button 1", "Button 2", "Button 3" with subtle 3D shading.
600
Stephen Margheim @fractaledmind.bsky.social · 02/01/2026
The pattern is quite flexible as well. Here's I've made a more traditional "tabs" interface, but again with *only* HTML and CSS. Even I get surprised at what is possible today with #StylishHTML
130
Stephen Margheim @fractaledmind.bsky.social · 02/01/2026
I genuinely thought such a component required JS. After a day of tinkering, turns out I was wrong. This is a 100% plain HTML and CSS "card tabs" component built with <details>, container queries, and absolute positioning.
140
Stephen Margheim @fractaledmind.bsky.social · 01/01/2026
These are actual Tailwind v4 utilities built with @utility, so you get tree-shaking and editor auto-complete. Same DX you're used to.
Dark-themed code snippet showing a custom @utility ui-button block with Tailwind-style @apply classes for layout, colors, spacing, hover and focus styles.
110
Stephen Margheim @fractaledmind.bsky.social · 01/01/2026
Instead of this... You write this...
HTML code snippet showing a <button class="inline-flex items-center justify-center rounded-md bg-gray-900 px-3 py-2 text-sm font-semibold text-white">Save changes</button>HTML code snippet showing a button element: <button class="ui-button">Save changes</button>
110
Stephen Margheim @fractaledmind.bsky.social · 01/01/2026
Component libraries bundle JS behavior, CSS styling, and DOM templating. Most of the time I just want one, not all three. Headless libraries solved "behaviors only, no styles." I can't find any "bodiless" libraries offering styles only, no behaviors. So I'm making HTML UI...
2211
Stephen Margheim @fractaledmind.bsky.social · 01/01/2026
Adding margin between stars breaks the hover UX—gaps create "dead zones" where nothing highlights. The fix: expand the label WIDTH while keeping the mask-size fixed. The gap is visual, but the hover target is continuous.
100
Stephen Margheim @fractaledmind.bsky.social · 01/01/2026
Why mask instead of background-image? You can't change SVG fill colors dynamically with background images. But with mask, the SVG acts as a stencil—letting background-color show through. Now hover states are just color changes.
Row of five black star icons for rating, leftmost star highlighted by a mouse cursor indicating selection or hover.
100
Stephen Margheim @fractaledmind.bsky.social · 01/01/2026
For half-stars, I split each star into two <label> elements—left half and right half. Each label uses an SVG mask of a half-star shape. nth-of-type(odd) = right half nth-of-type(even) = left half
Row of six solid black five-point stars evenly spaced on a white background, each star showing full filled shape and uniform size.
100
Stephen Margheim @fractaledmind.bsky.social · 01/01/2026
I researched existing pure-CSS solutions and found several issues. They either didn't support half-stars, depended on FontAwesome, and/or had inconsistent/janky hover behavior. As a result, I created my own solution using only radio inputs, labels, and SVG masks.
110
Stephen Margheim @fractaledmind.bsky.social · 01/01/2026
Stop using rating libraries. I've created a CSS-only star rating component with half-star support in just 60 lines. No JavaScript. Fully accessible. Smooth hover interactions. Here’s how it works: 🧵
Five black star outlines in a row with the leftmost star filled gold and a cursor pointing at it, suggesting a half or single-star rating selection.
3190
Stephen Margheim @fractaledmind.bsky.social · 31/12/2025
Wild looking back at this year. So much has changed, so much has stayed the same. But one of my absolute favorite years ever. fractaledmind.com/2025/12/31/...
Adult hand cradling a newborn's foot and ankle with hospital ID band and soft fabric wrap, tattooed wrist reading "PA-P" visible.
090
Stephen Margheim @fractaledmind.bsky.social · 31/12/2025
Stop using <select multiple> for "select many" UI. It's the worst form control in HTML. Luckily, there is a better pattern, and it isn't difficult or weird...
Rounded dropdown list showing multiple checkbox options like Photography (checked), Design services (highlighted), Web development, Accounting, Legal services, Consulting, Other, with keyboard tips.
191
Stephen Margheim @fractaledmind.bsky.social · 30/12/2025
Plain HTML and CSS can be beautiful. Stay tuned 👀
Bold headline declaring "Plain <html> and .css can be beautiful" on a graph-paper background with supporting text and two blue call-to-action buttons.
6474
Stephen Margheim @fractaledmind.bsky.social · 30/12/2025
Experiment 2: different orientations for SUB-trees. Main tree horizontal, but one branch vertical. <ul class="tree -horizontal"> <li> <ul class="-vertical">...</ul> </li> </ul>
Horizontal tree diagram with root "1", left branch showing vertical subbranch 1.1→1.1.1–1.1.3 and right branch 1.3 with nested nodes down to 1.3.2.2.1
100
Stephen Margheim @fractaledmind.bsky.social · 30/12/2025
Experiment 1: "folder" trees (like file explorers). Key change: `align-items: start` instead of `center` so children align to the TOP of their row, not the middle. Then adjust the sibling connectors to match.
Vertical folder-style tree with node "1" at top and indented child nodes 1.1, 1.2 (with subtree 1.2.1 → 1.2.1.1, 1.2.2, 1.2.3), 1.3, 1.4.
100
Stephen Margheim @fractaledmind.bsky.social · 30/12/2025
First, the full system so far: → .tree.-horizontal ← .tree.-horizontal.-inverse ←→ .tree.-horizontal.-centered ↓ .tree.-vertical ↑ .tree.-vertical.-inverse ↑↓ .tree.-vertical.-centered
Three horizontal diagram rows showing left-to-right and right-to-left tree orientations with single, two-branch, and three-branch node examples.Two schematic tree diagrams showing horizontal and vertical orientations with a central shaded node and branching rectangular nodes above and below.
100
Stephen Margheim @fractaledmind.bsky.social · 29/12/2025
Tournament brackets. Org charts with a CEO in the middle. Decision trees that branch both ways. These need CENTERED trees — children on both sides of the parent. Here's the CSS trick: 🧵
Centered tournament-style tree with a root labeled "1", left and right branches showing nested nodes (1.1, 1.2 with three left children, 1.3 with three right children, 1.4).Centered hierarchical org chart with a root node "1" branching left and right to 1.3 and 1.4; 1.3 further centers three children and top shows 1.1 and centered 1.2 with three subnodes.
161
Stephen Margheim @fractaledmind.bsky.social · 28/12/2025
CSS trees can flow in any direction. Sure, → left-to-right and ↓ top-to-bottom are most common, but a good tree component needs to support ← right-to-left and ↑ bottom-to-top as well Building on our previous foundations, just one property change for each. Here's how: 🧵
Centered horizontal-flow tree diagram showing node "1" with child "1.1" above and "1.2" leading right to three stacked children "1.2.1", "1.2.2", "1.2.3".Centered hierarchical tree diagram with node "1" branching to "1.1" and "1.2"; "1.2" further branches to "1.2.1", "1.2.2", "1.2.3".Centered schematic tree diagram showing node "1" connected to child "1.2" with three stacked children "1.2.1", "1.2.2", "1.2.3" and an upper child "1.1".Centered hierarchical tree diagram: root node "1" connects up to "1.2" and "1.1", with "1.2" branching to three leaf nodes "1.2.1", "1.2.2", "1.2.3".
171
Stephen Margheim @fractaledmind.bsky.social · 27/12/2025
Yesterday I showed how to build horizontal tree structures with just plain HTML and CSS. Today: vertical trees (org charts, family trees, decision diagrams). And the lovely detail is that it only takes one key change to make it all work: 🧵
Left-rooted vertical tree diagram with node "1" branching to "1.1" and "1.2"; "1.2" further branches to three stacked child nodes labeled "1.2.1", "1.2.2", "1.2.3".Centered vertical org chart: root "1" above two children "1.1" and "1.2", with "1.2" branching to three leaves "1.2.1", "1.2.2", "1.2.3".
242
Stephen Margheim @fractaledmind.bsky.social · 26/12/2025
Org charts, file trees, tournament brackets—all with pure CSS. No canvas. No SVG. No JS. Just flexbox and pseudo-elements. Let's break it down, starting with the foundational left-to-right tree, where only a couple dozen lines of CSS can transform this ... into this ... 🧵
Bulleted hierarchical list: top-level "1", nested level with two circular items "1.1" and "1.2", deeper level with three square items "1.2.1", "1.2.2", "1.2.3".A horizontal CSS-style tree diagram showing node "1" branching to "1.1" and "1.2", with "1.2" further branching to "1.2.1", "1.2.2", "1.2.3".
2212
Stephen Margheim @fractaledmind.bsky.social · 23/12/2025
The pattern is quite flexible as well. Here's I've made a more traditional "tabs" interface, but again with *only* HTML and CSS.
110
Stephen Margheim @fractaledmind.bsky.social · 23/12/2025
👀 Sneak peek of a 100% plain HTML and CSS component I'm building for my next project. I'll give a full behind-the-scenes tour of the project to the first person that comments with the correct essential implementation details driving this "card tabs" component.
110
Stephen Margheim @fractaledmind.bsky.social · 23/12/2025
This required some manual tweaking, but only 5 minutes of work.
SVG text snippet showing two tspan elements: "Stylish" at 95px and "HTML" at 115px with classes for sans font and tracking, fill="red" and font-weight=900.
010
Stephen Margheim @fractaledmind.bsky.social · 23/12/2025
You can then tweak the font-size, letter-spacing, and positioning to have it line up as well as possible with the stylized content. For example, the demo above looks like this when the fill is red.
Bold red "Stylish HTML" text with a black drop-shadow layered over a cursive black background word, centered on a white canvas.
120
Stephen Margheim @fractaledmind.bsky.social · 23/12/2025
Have an SVG with stylized text? Want to make the stylized text selectable? Add a <text fill=transparent> node with the corresponding text. We can have nice things that are usable too!
161
Stephen Margheim @fractaledmind.bsky.social · 22/12/2025
Designer-quality dialogs with zero JavaScript 👀 Borrowed the visual design from Campsite, but built with native <dialog> and pure semantic HTML and CSS. Full walkthru at: fractaledmind.com/2025/12/18/... Check it
0162
Stephen Margheim @fractaledmind.bsky.social · 22/12/2025
But, I personally just use an ::after pseudo-element and one line of JS to show the appropriate keyboard shortcut using the `accessKeyLabel` property (not fully baseline yet, but there is a polyfill). This ensures users know there is a shortcut and how to activate it.
Dark-themed code snippet showing an HTML button element with class using ::after content for --accessKeyLabel, attributes commandfor="basic-dialog" command="show-modal" accesskey="O" and label "Open Dialog".Dark-themed code editor showing a short JavaScript snippet that sets a CSS custom property --accessKeyLabel from each element's accessKeyLabel using querySelectorAll.
130
Stephen Margheim @fractaledmind.bsky.social · 22/12/2025
Now, there are caveats. The keyboard shortcut involves modifier keys, which you can’t remove or change. And the modifiers are different across browsers and operating systems.
Dark table comparing browser keyboard shortcuts across Windows, Linux, Mac showing modifier keys like Alt, Shift, Control, Option for Firefox, Chrome, Edge, Safari, Opera.
210
Stephen Margheim @fractaledmind.bsky.social · 22/12/2025
The web platform has supported keyboard shortcuts for over a decade! Say hello to criminally overlooked `accesskey` attribute. Add it to an interactive element like a button, link, or input so users can fire its default action via keyboard shortcut, no JS required!
1231
Stephen Margheim @fractaledmind.bsky.social · 20/12/2025
Breadcrumb nav: <li> <a href="/org/acme">Acme Corp</a> <button popovertarget="org-switcher">▾</button> <nav id="org-switcher" popover> <ul> <li><a href="/org/acme">Acme Co ✓</a></li> <li><a href="/org/globex">Globex Inc</a></li> </ul> </nav> </li>
Dark code editor showing HTML list for organization switcher: anchor "Acme Corp", a button, and a popover nav listing "Acme Co ✓" and "Globex Inc".
100
Stephen Margheim @fractaledmind.bsky.social · 20/12/2025
`popover` & `popovertarget` give you dropdown menus w/ light-dismiss for free. <button popovertarget="menu">Options</button> <nav id="menu" popover> <ul> <li><a href="/settings">Settings</a></li> <li><a href="/profile">Profile</a></li> </ul> </nav> #StylishHTML
1100
Stephen Margheim @fractaledmind.bsky.social · 19/12/2025
I'm crafting a novel tool that uses keyboard usability as the ultimate test for page accessibility, while also diving deep into the a11y tree. Excited seeing it take shape! 👀
Dark-themed accessibility audit panel showing a "MISSING ACCESSIBLE NAME" critical alert for a button element without an accessible name, with remediation tips.Dark accessibility audit UI showing scan metrics (30 stops, 50% pass, 11 critical, 04 serious) and a list of focusable elements with several "(no name)" entries.
140
Stephen Margheim @fractaledmind.bsky.social · 19/12/2025
For icon separators, use a background image instead: li:not(:last-child)::after { content: ""; width: 1em; height: 1em; background: url("data:image/svg+xml,...") center / contain no-repeat; }
Dark-themed code editor showing a CSS rule adding a 1em SVG data-URL background as ::after for li:not(:last-child) to act as icon separators.
100
Stephen Margheim @fractaledmind.bsky.social · 19/12/2025
Want different separators? Just change the `content` value: /* Chevron */ li:not(:last-child)::after { content: " › "; } /* Arrow */ li:not(:last-child)::after { content: " → "; } /* Pipe */ li:not(:last-child)::after { content: " | "; }
Dark code editor showing CSS snippets defining li:not(:last-child)::after with three separator options: chevron (›), arrow (→), pipe (|).
100
Stephen Margheim @fractaledmind.bsky.social · 19/12/2025
Look at this lovely markup: <nav> <ol> <li><a href="/">Home</a></li> <li><a href="/products">Products</a></li> </ol> </nav>
100
Stephen Margheim @fractaledmind.bsky.social · 19/12/2025
Breadcrumb separators belong in CSS, not HTML. Just use the `::after` pseudo-element. nav > ol > li:not(:last-child)::after { content: " / "; color: lightgray; padding: 0 0.5em; } The `:not(:last-child)` ensures no trailing separator after the final item. #StylishHTML
Top breadcrumb row with three labeled chips (Organization, Application, Environment) and an annotated arrow pointing to a CSS code snippet showing nav > ol > li:not(:last-child)::after adding a " / " separator.Dark-themed code snippet showing a CSS rule using nav > ol > li:not(:last-child)::after to add a lightgray "/" separator.
2202
Stephen Margheim @fractaledmind.bsky.social · 18/12/2025
I think @trycampsite had some of the most elegant UI on the web, especially for modal dialogs, but it was all React components rendering <div>s inside <div>s. So I stole their design and rebuilt it with semantic HTML and CSS. 😅 fractaledmind.com/2025/12/18/...
070
Stephen Margheim @fractaledmind.bsky.social · 14/12/2025
I cloned @laravel.com's Cloud breadcrumbs as a simple <nav> with <a> links and [popover]s. If you'd like to see a video walkthru of how exactly I built this, let me know. I've been considered resurrecting my YouTube channel and sharing more videos here. Would you watch? #StylishHTML
5130
Stephen Margheim @fractaledmind.bsky.social · 13/12/2025
This is the page it built base on that simple prompt. Yes, I tailored it with specific inspiration and specific base HTML. But this is so much better than I ever expected. See the full page link in the quoted post.
010
Stephen Margheim @fractaledmind.bsky.social · 13/12/2025
And: ``` dialog::backdrop { background-color: rgb(0 0 0 / 0.5); transition: background-color 0.2s ease-out, overlay 0.2s ease-out allow-discrete, display 0.2s ease-out allow-discrete; @starting-style { background-color: rgb(0 0 0 / 0); } } ```
000
Stephen Margheim @fractaledmind.bsky.social · 13/12/2025
CSS snippet: ``` dialog { opacity: 1; scale: 1; transition: opacity 0.2s ease-out, scale 0.2s ease-out, overlay 0.2s ease-out allow-discrete, display 0.2s ease-out allow-discrete; @starting-style { opacity: 0; scale: 0.95; } } ```
Dark themed code editor showing CSS for a dialog component with opacity and scale transitions, a starting-style block and a :not([open]) rule.
100
Stephen Margheim @fractaledmind.bsky.social · 13/12/2025
To master exit transitions for <dialog>s, turn to `transition-behavior: allow-discrete`. Most CSS transitions are smooth, but `display` toggles abruptly. `allow-discrete` ensures elements stay visible briefly for smoother exits before `display: none`.
160
Stephen Margheim @fractaledmind.bsky.social · 12/12/2025
You can animate the backdrop too 😉 ``` dialog::backdrop { background-color: rgb(0 0 0 / 0.5); transition: background-color 0.2s ease-out; @starting-style { background-color: rgb(0 0 0 / 0); } } ```
Dark code snippet showing CSS for dialog::backdrop with semi-transparent black, transition rules and a @starting-style block setting transparent background.
030
Stephen Margheim @fractaledmind.bsky.social · 12/12/2025
Full CSS snippet: ``` dialog { opacity: 1; scale: 1; transition: opacity 0.2s ease-out, scale 0.2s ease-out; @starting-style { opacity: 0; scale: 0.95; } } ```
Dark code editor showing a CSS snippet defining dialog opacity and scale transitions with a starting-style opacity 0 and scale 0.95.
110
Stephen Margheim @fractaledmind.bsky.social · 11/12/2025
After years and years and years, I *finally* have added a newsletter sign up to my blog! If you love building beautiful and high-leverage things on and for the web, I think we would get along swell. So come join my journey as I chase my own sense of perfection.
Dark personal blog layout with a circular portrait, name "Stephen Margheim," bio about being a full‑stack Ruby on Rails engineer and newsletter signup.
150