(class)less is more
re-thinking the UI Kit we already have
Emiliano Pisu
Father of 2 lovely monsters
D&D master, player ... whatever
Senior Design Engineer, Sensei & Co-Host
@ Dev Dojo IT
linkedin.com/in/pixu1980
github.com/pixu1980
codepen.io/pixu1980
linkedin.com/company/dev-dojo-it/
youtube.com/@devdojo_it
twitch.tv/devdojo_it
@devdojo_it
Why this talk?
-
We over-engineer UI
with heavy CSS/JS stacks -
Browsers already provide
powerful UI foundations -
Classless CSS shows
how far semantic HTML can go
Sounds like going
back to the past, uh?
Or "Back to the Future"?
In modern web dev, user agents are frontline accessibility framework
If we write semantic HTML, gently extending it with CSS, we inherit decades of research about assistive technologies support
This isn't a fallback,
it's the starting line!
🚨 Keep this in mind 🚨
"First you turn the time circuits on..."
NOV
05
88
1955
8888
06
88
00
88
OCT
21
88
1985
8888
01
88
22
88
OCT
21
88
1985
8888
01
88
20
88
Modern design systems are stunning, sophisticated, scalable... and expensive
Modern CSS resets often
discard browser defaults entirely
Introducing complexity,
inconsistency, and technical debt
In some way we waste out efforts re-building what's already there, just less consistent... and too often less accessible
Does it makes sense resetting CSS in 2025?
Why CSS resets were born?
- Early browsers had inconsistent default styles
- Margins, paddings, font sizes varied wildly
- Resets ensured a clean and predictable baseline
What does a CSS reset?
- Erase all default styles
- Force to re-apply needed styles
- Gain control over layout and spacing
- Ensure consistent rendering across browsers
What are the main concerns with CSS Resets?
Hidden costs of CSS resetting already working stuff
- Removes or reduces accessibility defaults for users who rely on keyboards navigation
- Every “zeroed” element must therefore be redefined, adding un-useful redundancy
- Technical and Design debt at the same time, by adding third party deps which must be overridden
- Loss of useful defaults (e.g. system colors, typography, spacings, focus styles, interaction behavior)
Takeaway
CSS resets were essential in the past, today we have better tools... and better defaults
Maybe the leanest, fastest, most accessible UI kit is already in your browser, it just needs some style!
Semantic HTML is power
- Structure, meaning, and accessibility baked in
- Assistive technologies understands your layout
- HTML is a base component system providing accordions, dialogs, popovers and many more for free, make it yours!
Modern CSS evolving everyday
- Allows layering, nesting, scoping, targeting, transitioning (even between routes)
- User agents are improving at every release, and their default styles are converging over time
- Focus indicators and roles come out of the box, no JS needed for basic interactions
The Browser’s Hidden
Design System
A crude, mostly undocumented,
foundational design system: but real!
System Colors
Natively accessibile color palette derived from OS colors, reactive to system settings, including accent-color- Canvas
- CanvasText
- LinkText
- VisitedText
- ActiveText
- ButtonFace
- ButtonText
- ButtonBorder
- GrayText
- Field
- FieldText
- Highlight
- HighlightText
- Mark
- MarkText
- SelectedItem
- SelectedItemText
- AccentColor
- AccentColorText
- Canvas
- CanvasText
- LinkText
- VisitedText
- ActiveText
- ButtonFace
- ButtonText
- ButtonBorder
- GrayText
- Field
- FieldText
- Highlight
- HighlightText
- Mark
- MarkText
- SelectedItem
- SelectedItemText
- AccentColor
- AccentColorText
Type Scale & Spacings
Heading elements from <h1> to <h6>, paragraphs and all other phrasing elements follow a visual hierarchy, spacings reflect an implied scale and rhythmHeading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
Paragraph
Focus Styles & User Input
Native UI elements that adapt to platform conventions, keyboard-focused elements get visible outlines out of the boxTakeaway
Don’t "fight" the browser anymore, embrace it!
Attributes utilities
Attributes??
instead of Classes??
Modern HTML and CSS gives us the tools to do this elegantly
A class selector and an attribute selector has exactly the same specificity
Why attribute utilities matters?
- Declarative, readable, and native to HTML
- Separate intent from implementation
- Reduce visual noise in markup
- Consistent, scalable UI state and theming
Look... our HTML is already full of attributes, at least... it should be!
So why not use them for CSS selectors?
<html data-theme="dark">
<head></head>
<body>
<button disabled aria-label="Close modal">x</button>
<input type="email" required placeholder="Your email" />
...
</body>
<style>
[data-theme*="dark"] { ... }
[aria-label] { ... }
[type="email"] { ... }
</style>
</html>
CSS attr() function allows to get the value of an HTML attribute as a string
<div title="This is the title"></div>
<style>
div::after {
content: attr(title);
}
</style>
Unfortunately, this was traditionally limited to the CSS content property
Do you know CSS attr() function is about to get a game-changer update?
What's new with attr() function?
<element attr="value"></element>
<style>
element {
property: attr(attr type(<type>), fallback-value);
}
</style>
Example: Grid Control
<div column-start="1" column-end="3">
this is the div content
</div>
<style>
div {
grid-column-start: attr(column-start type(<integer>), 1);
grid-column-end: attr(column-end type(<integer>), -1);
}
</style>
Use attr() to control grid layout via HTML attributes
Example: Dynamic Font Sizes & Colors
<div font-size="5em" text-color="rebeccapurple">
Hello World!
</div>
<style>
div {
font-size: attr(font-size type(<length>), 1em);
color: attr(text-color type(<color>), black);
}
</style>
Set font size, colors (or whatever) dynamically using attributes
Better to use data-* attributes?
- Virtually prevents conflicts with standard attributes
- Provides a clear namespace for custom data
- Accessible via JavaScript through dataset
CSS Custom Properties are supported as well
<button data-color="rebeccapurple">
Click me!
</button>
<style>
button[color] {
--button-color: attr(data-color type(<color>), Canvas);
background-color: var(--button-color);
}
</style>
Pass
attribute values to custom properties for broader usage
Supported types include: angle, color, custom-ident, image, integer, length, length-percentage, number, percentage, resolution, string, time, transform-function...
...unlocking infinite possibilities with typed attributes:
- Content-first web design
- Declarative, readable, scalable
- No spaghetti css classes
- Reduced dependency on JS frameworks
No JS. No classes.
Just semantics and style.
Takeaway
We’re entering an era where HTML attributes will become the new interface for UI logic, and CSS will finally treat them as first-class citizens.
classless CSS
What is classless CSS?
Less complexity, more semantics, no classes, just pure HTML elements and selectors
Leverage browser defaults instead of override their behavior, style is inferred from semantics
Less DOM noise, better scalability, providing accessibility and performance out of the box
Use attributes like helpers and utilities
Popular Classless Frameworks
- Pico.css - beautiful defaults & theming
- Water.css - zero-config elegance
- Almond.css - opinionated and light
Examples
Wrap Up
Benefits of classless web design
- Semantic SEO-ready HTML
- Lower CSS footprint
- Better accessibility by default
- Faster prototyping
- Improved maintainability and debugging
Invite to Action
- Try building a UI without classes
- Experiment with attribute-first styling
- Try Pico.css, Water.css, or build your own
- Start from semantics, enhance progressively
Let's re-code the web, one attribute at a time
Slides Links