Stephen Margheim

Stephen Margheim

@fractaledmind.bsky.social

1.4K followers190 following710 posts

Aaron is one of the best educators I have ever met. I am 100% certain that this will be some of the very best content out there for harnessing AI to build, fast but with quality. I'm pre-purchasing, what about you?

Aaron Francis@aaronfrancis.com

They say AI is the end for developers. They say the job market is gone. They say learning to code is pointless. I don’t buy it. I think we're just getting started.

CSS Anchor Positioning is now baseline. Firefox 147 ships today with full support. Chrome, Edge, Safari — all on board. Position elements relative to other elements. No JavaScript. Here's the 60-second rundown...

View full thread

Best part: automatic fallbacks. .popup { position-area: block-end; position-try: flip-block; } Popup below the anchor. Not enough space? Flip it above. The browser does the math. You write the rules.

CSS Anchor Positioning is now baseline. Firefox 147 ships today with full support. Chrome, Edge, Safari — all on board. Position elements relative to other elements. No JavaScript. Here's the 60-second rundown...

Step 1: Name your anchor .trigger { anchor-name: --menu; } Step 2: Connect and position .popup { position: absolute; position-anchor: --menu; position-area: block-end span-inline-end; } The popup now tracks the trigger.

Building HTML UI forced me to figure out how to write CSS classes that integrate deeply with Tailwind v4. I want 3 things: intellisense, tree shaking, and easy utility overrides. Here’s I make it all work 🧵

View full thread

The ui- prefix matters too. When you see .btn you have no idea what you’re dealing with. Bootstrap? Old semantic class? Random utility? `ui-badge` signals intent: zero-specificity visual pattern designed to compose with utilities.

Building HTML UI forced me to figure out how to write CSS classes that integrate deeply with Tailwind v4. I want 3 things: intellisense, tree shaking, and easy utility overrides. Here’s I make it all work 🧵

Why this is better: • @​utility → tree-shaking + autocomplete • :where() → zero specificity, utilities always win • @​variant → each state gets its own readable block • @​apply → uses the user’s theme, not a parallel system

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.

View full thread

How It Works (2/3) * Trigger: Inside the container (is this ok, I don't know, but it works 🤷🏻), fades/blurs out when :popover-open * Content: Inside the container, fades/blurs in when :popover-open * Height: Animates to auto using interpolate-size: allow-keywords

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.

How It Works (1/3) * Container: The popover is always visible (display: flex), acting as the morphing container * Popover API: popover="auto" for light dismiss — click outside or press Escape to close * Anchor positioning: Container anchors to wrapper using anchor() functions

View full thread

What if you want a file input where the label looks like a button? Or a link that should look like a button? Or a summary element that should look like a button? Forgive me, but this ain't it: <Button render={<a href="/contact" />}>Contact</Button>

Affordances are a natural solution. They give us reusable visual patterns that work with any element, compose cleanly with utilities, and provide a single source of truth for how interactive elements should look.

View full thread

Buttons are those things that afford users the ability to take an action. Selects are those things that afford users the ability to choose an option. Dialogs afford users the ability to double check their intention. Popovers afford seeing contextual information. etc.

Your app should have consistent visual styles for the various UI affordances so that users can build a stable mental model of how to interact with your system. BUT, you might not want or need to use the exact same HTML structure for every UI affordance.

We don't need to go back to trying to come up with a semantic name for every part of our pages to nonetheless benefit from a small collection of well-named classes. Look at the popular component kits. You'll see the same names; there's a shared vocabulary for web apps.

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 ✨

"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

Stephen Margheim@fractaledmind.bsky.social

I just solved the problem of having button's shadow stack include an offset outline that "magically" adapts to any surface color that the button is on 🤯 ``` @​utility bg-* { & .ui-button { --button-surface-color: --value(--color-*, [color]); } } ``` Explanation in 🧵

I just solved the problem of having button's shadow stack include an offset outline that "magically" adapts to any surface color that the button is on 🤯 ``` @​utility bg-* { & .ui-button { --button-surface-color: --value(--color-*, [color]); } } ``` Explanation in 🧵

View full thread

So even if there are many ancestors with different background colors (body, card, section), the button will know its surface because its nearest ancestor gets to set the final value of --button-surface-color seen by .ui-button

I just solved the problem of having button's shadow stack include an offset outline that "magically" adapts to any surface color that the button is on 🤯 ``` @​utility bg-* { & .ui-button { --button-surface-color: --value(--color-*, [color]); } } ``` Explanation in 🧵

View full thread

In this case, we don't need to define styles, just set a CSS property. We want elements with a bg-* background color to pass that value down to their nearest .ui-button descendant. This allows the .ui-button element to know its surface color.

We use a descendant selector `& .ui-button` to ensure that adding a bg-* utility directly to a .ui-button element doesn't override the surface property value. And the way that CSS properties inherit means that this value will be set by the button's nearest ancestor.

I just solved the problem of having button's shadow stack include an offset outline that "magically" adapts to any surface color that the button is on 🤯 ``` @​utility bg-* { & .ui-button { --button-surface-color: --value(--color-*, [color]); } } ``` Explanation in 🧵

You can "hook into" Tailwind's provided utilities by defining your own @​utility definitions that mirror the Tailwind signature. In this case, I define a functional utility for background colors. Tailwind will generate its styles for this utility _as well as_ your styles.

Agents excel in a cohesive system—one that is internally consistent, free minimal external dependencies, and token efficient. Using declarative HTML with a CSS library of affordances built on Tailwind is the *ideal* environment for a Claude Code or Codex or the like.

Who's building a design system or component kit using Tailwind, fully leveraging its features? Others must be doing more than just applying styles. I'm creating custom utilities, modifying built-ins, adding layers, and defining properties. If you’re doing the same, let’s connect.

If you button component styles can't work on input[type=submit] or input[type=reset], where ::before/::after pseudo-elements aren't present, then you have an undercooked component IMO. So, a challenge for HTML UI has been getting the subtle 3d effect I want without pseudos.

View full thread

Since that's all you need, simpler patterns exist: 1. Anchor links + scroll-snap: Just link to sections. CSS handles the rest. 2. <details> elements with [name] attr: Accordion pattern. Native, accessible, less complex. 3. Just… show everything. 4. Just… put it on another page.

Before reaching for a tab library, ask: is this really a tab interface? Or is it content that could just... be on the page or navigated to on another page with shared structure and styling.

The classic tab pattern: - Row of buttons - Click to show/hide panels - ARIA roles (tablist, tab, tabpanel) - Arrow key navigation - Roving tabindex That’s a lot to show one section at a time and let users switch.

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.

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

There are two types of developers: “Least power devs” — What’s the simplest tool that solves my problem today? “Maximum optionality devs” — What tool handles every problem I might have in 5 years? I know which camp I’m in.