(class)less is more

re-thinking the UI Kit we already have

Pixu

Emiliano Pisu

Father of 2 lovely monsters

D&D master, player ... whatever

Senior Design Engineer, Sensei & Co-Host
@ Dev Dojo IT

pixu1980@linkedin linkedin.com/in/pixu1980
pixu1980@github github.com/pixu1980
pixu1980@codepen codepen.io/pixu1980
devdojo@linkedin linkedin.com/company/dev-dojo-it/
devdojo@youtube youtube.com/@devdojo_it
devdojo@twitch twitch.tv/devdojo_it
devdojo@telegram @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"?

DeLorean time-traveling!

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 🚨

Batman slapping Robin, while saying: 'Important doesn't fix your bad CSS'
Let's dive in
Let's dive in Let's dive in Let's dive in Let's dive in Let's dive in

"First you turn the time circuits on..."

MONTH
DAY
YEAR
HOUR
MIN

NOV

05

88

1955

8888

AM
PM

06

88

00

88

MONTH
DAY
YEAR
HOUR
MIN

OCT

21

88

1985

8888

AM
PM

01

88

22

88

MONTH
DAY
YEAR
HOUR
MIN

OCT

21

88

1985

8888

AM
PM

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?

Doc. Emmet L. Brown saying 'Marty, you are not thinking fourth dimensionally!'

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

  1. Removes or reduces accessibility defaults for users who rely on keyboards navigation
  2. Every “zeroed” element must therefore be redefined, adding un-useful redundancy
  3. Technical and Design debt at the same time, by adding third party deps which must be overridden
  4. 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 rhythm

Heading 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 box
A simple list of UI elements
Checkables




Inputs
Selectors

Takeaway

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

CSS Specificity explaination

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

Slides
Slides
Slides Repo on Github
Slides Repo
© 1987-2025 - Warner Bros. Entertainment Inc.
Pixu
Dev Dojo IT Logo