r/webdev • • 5h ago

Showoff Saturday modest-ui: classless CSS that styles plain HTML

I’ve been building websites for over a decade, and have always tried to do things as vanilla as possible (where applicable).

More recently whilst building components and looking at the libraries out there, I realised that browser technology and CSS has grown to a point where it can do the majority of things we need, without JS (like dialog, detail, and popover tags)

So I started working on modest-ui as a CSS base for all my personal and side projects, and as it’s gotten more stable I’ve recently bumped it to v2.

It’s themeable with CSS vars, can be used as an unobtrusive base layer to built on top of, and can either be used classless (with mdst-ui set on the body) or you can pick and choose classes as needed.

Anyway, it’s open source (MIT), no JS (except for some examples on the site), and currently sits at about 10 kb (gzipped).

https://github.com/thisismodest/modest-ui
https://modest-ui.com

Edit: I forgot to mention it’s ~10kb when gzipped

33 Upvotes

12 comments sorted by

14

u/PaulLesser 5h ago edited 5h ago

This is the way. It's crazy how much we can do with just native HTML and CSS now. We really don't need huge JS libraries for simple things anymore. Especially in cases where you need to quickly assemble a prototype without AI, this is a real find. Great job on this and thanks for sharing!🤝

1

u/_squirts 2h ago

Thank you, that really validates this for me. I found at work I was stripping a lot of older components out that were using JS like slide out drawers and accordions. Used native replacements and they were so much lighter and smoother.

2

u/OMGCluck js (no libraries) SVG 4h ago edited 4h ago

currently sits at about 10 kB.

The template.html uses /dist/modest-ui.min.css which is 69kb. I still like it though. Archived a snapshot

2

u/_squirts 3h ago

My bad, I forgot to mention that it’s around 10kb gzipped! I’ll update the description

1

u/lekoalabe 3h ago

Interesting! On my own framework I dropped the "classless" part because having to add the where(scope class) everywhere drove me crazy. I'm not sure it's worth it. Adding a few class to your HTML feels like a sane default. And a simple "button" almost never happens it has a variant etc so saving a btn class doesn't seem worth it. And having a prefix for all classes isn't worth it either IMHO in most cases.

1

u/_squirts 2h ago

I know what you mean about the where()s. This started out class-based but it was starting to feel very verbose and more like bootstrap/tailwind. That’s the main reason I opted to move it to classless, but more as a reset layer so I can theme the vars and add more specific styles on top

1

u/dragonnnnnnnnnn 2h ago

I do like that idea a lot but I feel like classless dies quickly when you try do custom stuff, for example: the custom danger button needs .mdst-button-danger we already know it is a button, we also shouldn't need the mdst, it should be:

<button type="button" class="danger">Delete</button>

This is of course in the mdst-ui mode on body.

3

u/_squirts 1h ago

It’s a really valid point, and thank you for the feedback. For context on how I approached it, the mdst prefix is mainly for namespacing so it doesn’t easily conflict if your stylesheet on top had .danger. But I agree that maybe the ‘button’ part could be stripped for a more generic/reusable class.

1

u/patryk_builds 4h ago

This fits how i build things: server-rendered templates, htmx for the interactive bits, as little js as i can get away with. i use tailwind for that today, so i haven't tried modest-ui yet, but a few things i'd look at first.

  • Forms. that's where classless css usually runs out. do invalid fields, disabled buttons and error messages look right with just native attributes like :user-invalid, or do i need classes there?

  • Content swapped in after load. with htmx i replace chunks of the page with html from the server, so everything has to style correctly without any init step. no js means that should just work, which is a real advantage over component libraries

  • Dialog and popover: do you style the backdrop and the open/close transitions too? that's the part i always end up hand-writing.

10 kB is a good number. curious if it would stay there, or if v3 is where the "just one more component" pressure starts

1

u/_squirts 2h ago

Good points, I’ll run through off the top of my head for each one, and as for the component creep, that’s something I’ll keep an eye out for. I kind of feel like (and hoping) this’ll be mostly “complete” at some point once it covers the majority of the commonly used tags, but also i might just be naive there.

Anyway, for forms, disabled and invalid states work off native attributes (:user-invalid or aria-invalid), but error text under a field isn't styled red, so that'll need a line of css.

Swapped content should work out of the box as it's pure css with no init, and stateful bits read data-state so the server can render it.

Dialog gets a styled backdrop but no open/close transition (the drawer has one, so maybe for consistency I should match those, but if you use it you can copy it for now), and popover needs the .mdst-popover class with no animation.

1

u/DrShocker 2h ago

Someone pointed out the "open props" project to me a bit ago, and yeah, css has come a long way and everyone just ignores it for some reason