MVP.css – Minimalist stylesheet for HTML elements
andybrewer.github.io
andybrewer.github.io
• https://news.ycombinator.com/item?id=25167928 (21 November 2020, 82 comments)
• https://news.ycombinator.com/item?id=22681270 (25 March 2020, 91 comments)
—⁂—
> No class names, no frameworks, just semantic HTML and you're done.
The trouble with this claim is that MVP.css abuses semantic HTML badly, using completely inappropriate elements all over the place (e.g. aside for cards, and b/strong/i/em inside links to make them look like buttons of various kinds), and the author has declined to change these things despite acknowledging that they’re wrong.
I mean, if they already have projects running with this, it makes sense. If I learned one thing in my professional life is that while being a perfectionist already is not the best way to approach the vast majority of the problems, it's especially true when it comes to HTML.
Also, I hate to be that guy, but seriously, this thing seems like one of the easiest open source projects to get into, so why not fork?
On the one hand, in the first instance it seems a lot easier to remember the syntax.
But thinking about it for longer, I realise that actually if I'm having to learn to put an <aside> inside a <section> for a card, but an <aside> inside an <article> becomes a callout, then perhaps it's not quite as intuitive as it seems, and if I have the mental overhead of remembering all that, perhaps I might be saving myself more energy just to write a CSS class.
One framework I've used recently which floats in between these two is Bonsai.css. It does quite a lot 'out-of-the-box' in terms of minimising boilerplate and basic styling, and uses CSS variables as a shorthand for style properties. It's also a bit of mental overhead, but you can of course just write inline styles if you can't be bothered to learn the shorthand.
'hey, maybe you could create a web component <card>? That would be cool. It's a shame you can't create web components without JS, wouldn't it be great just to have an HTML only syntax for creating a web component, like <template tagname="card"> or something?'
Then I realised that I still have to learn something else to write a 'card', so I might as well just keep it simple and use div.card. If I want anything more complex, I can use one of the many component frameworks that exist.
For those interested in the discussions around this, please refer to:
https://github.com/andybrewer/mvp/issues/26
https://github.com/andybrewer/mvp/issues/2
I would concede that the use of ‘a strong’, ‘section aside’, etc. does require some learning and the styling is perhaps unique, but I don’t think it’s invalid in any way.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/st...
> The <strong> HTML element indicates that its contents have strong importance, seriousness, or urgency.
In MVP.css links are already in bold by default, so ‘strong’ text inside a link requires more “urgency” than bold text, which is styled as a button.
Sure, I’ll grant that it’s atypical, but I don’t think it’s obviously wrong in some way.
Same with ‘aside’:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/as...
> The <aside> HTML element represents a portion of a document whose content is only indirectly related to the document's main content. Asides are frequently presented as sidebars or call-out boxes.
I think cards are basically “call-out boxes”.
But at the end of the day, this style sheet doesn’t have to be for everyone and it’s really designed for someone who’s rapid prototyping.
That said, I do think buttons and cards are important to most web page layouts so if there’s a better semantic way to codify those, I’m open to pull requests.
Ultimately a lot of the modern web trends don't fit perfectly into the HTML5 syntax, and cards particularly are one. They're not 'articles' because they're not 'complete, or self-contained, composition[s]'. They're not 'asides' because they're not 'tangentially related' - although callout boxes I agree are. They could potentially be considered 'sections' although I'm not sure you would list individual cards explicitly in a document's outline - plus from a technical perspective how do you differentiate a 'section' card from any other type of section.
I think it's important to understand that there's no way to make everyone happy here, and there simply isn't a good semantic way to create cards using the tags that exist. I think in most cases, cards are a presentation of an item of sorts (perhaps even a 'list' item?) but HTML doesn't have a simple 'item' tag, and the spec warns that although headings are valid inside li tags, it's probably not correct semantically.
Key is, there will be some people this helps. There will be some it doesn't. For every (completely valid) concern that people (including myself) are raising, the only fix is to add more complexity, which makes it less easy to use.
FWIW, I think you've done a great job building something usable and useful, thank you.
However, I think wether `<aside>` is semantic HTML or not is specific to the content inside it.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/as...
> The <aside> HTML element represents a portion of a document whose content is only indirectly related to the document's main content.
There's nothing in the spec saying how that tangentially-related content must be displayed. It simply says it's frequently a sidebar or call-out box.
So, if a user writes semantically correct HTML and writes tangentially related content using an `<aside>` tag, MVP.css then chooses to render that visually as a "card".
So, I think in this respect, it's up to the user to use the tag semantically correct or not. Or am I missing something?
I think it's also semantic HTML to have more than one `<aside>`, unless I missed that rule somewhere as well.
For example, in the "Little Mermaid" example (https://developer.mozilla.org/en-US/docs/Web/HTML/Element/as...) the fact "The movie earned $87 million during its initial release." is written inside an `<aside>`. But wouldn't it also be valid to include a 2nd fact as a 2nd `<aside>` and then have those visually represented as cards or call outs?
I think you’re right, there’s a case that for some situations where a card contains tangentially related information, <aside> is correct, but I think the majority of cases, it won’t fit.
For example, you use cards in two places on https://andybrewer.github.io/mvp/.
I don’t think either of those uses could really be described as “tangential” to the main page content (perhaps you could argue the toss for the form with suggestions).
* I think everything regarding the `aside` elements has already been said in the GitHub issue: It's context specific and you can't determine in advance if a certain (card) element is part of the main content or not. Therefore, `aside` should only be used if needed. (The top three cards on the MVP.css homepage definitely are part of the main content for example.)
* Your `a i` and `a strong` solutions are pretty unusual and they show the limit of what is possible using a classless CSS. I would have preferred staying even more minimalist and simply pass on button-like links.
* You could think about adding the underlining for links in continuous text. See https://www.w3.org/TR/WCAG20-TECHS/F73.html.
I'm not trying to be a dick about it since it's your personal project and I am not forced to use it – but I am not sure why the framework had to be classless and usable for a MVP all at once. I absolutely love classless CSS for simple/personal websites, but I associate MVPs (products) and rapid prototyping with more extensive and interactive interfaces than the typical text-based onepager.
Good point, I agree.
> Your `a i` and `a strong` solutions are pretty unusual and they show the limit of what is possible using a classless CSS
100% agree. This was a loose interpretation of semantic HTML IMO.
> I would have preferred staying even more minimalist and simply pass on button-like links.
Sure, from a purist perspective, but from a productivity one, the vast majority of product / service sites have a button somewhere, so I thought it was important to include it even if I had to abandon a strict-constructionist view of semantic HTML and go with a more progressive, interpretative one.
> You could think about adding the underlining for links in continuous text. See https://www.w3.org/TR/WCAG20-TECHS/F73.html.
I agree. I think it's a strong candidate to implement this in a v2 if that happens down the road.
> I associate MVPs (products) and rapid prototyping with more extensive and interactive interfaces than the typical text-based onepager
Sure, modern day MVPs look far more polished and interactive, but this was kind of in response to that. I was working through YC's Startup School (https://www.startupschool.org/) at the time and they were pushing the definition of an MVP as something that just barely works so you can test out a specific idea. So, while it won't work for an AirTable MVP, I think it should work for an API MVP, or most single-form MVPs. Beyond that, I agree it might not be a great fit for the project.
especially with rapid prototyping, you don't want your stylesheet dictating quirky usage of html.
Besides a few accessibility things to be aware of, like clicks and tabs for example.
The rest has zero impact on the browser and user experience. It was a nice idea but never got off the ground precisely because most of them hardly had any real difference from a simple div.
At the same time if you just take your MVP and copy paste it to production and don't fix it... that's the problem, not what they did for an MVP.
Personally, if I'm hacking out an MVP for something and someone wants to get nit picky ... I'm going to be kinda unhappy. It's an MVP there's going to be A TON to nit pick about, that's the nature of it.
I know that it is called "MVP", but firstly the term viability can mean different things and secondly there's no indication that the markup is implemented incorrectly. I love to check out example/demo pages from CSS frameworks and it's not uncommon to see glaring semantic errors in the HTML. People just copy everything that is presented to them and you should make sure to give them a good introduction.
It seems you are not in a position to be making these claims, since by your own admission you don't even use the project:
Also has a demo page [2] to try it out
My personal favorite is Water.css [1], because it looks good and makes very good use of HTML5 semantics. Tacit [2] is also amazing.
[0]: https://css-tricks.com/no-class-css-frameworks/
Would you consider removing this?
[1]: https://github.com/milligram/milligram/blob/master/src/_Base...
MVP: 8.52K water: 31.61K tacit: 5.49K concrete (from child): 7.15K + 5.99K for normalize.css (13.14K total)
Tacit is most appealing to me to whip something together. Hits the best look/byte ratio for me and seems to be hardly an abuse of HTML at a glance.
I normally use actual semantic HTML with classes as styling hints and minimal CSS/JS. But I don't make anything "real", am definitely not a front-end guy, and my stuff is probably ugly to most.
> <link rel="stylesheet" href="https://unpkg.com/mvp.css">
That’s not a "pro tip"; that’s a very bad advice: you should always use versioned URLs. What if I find this project cool; add this URL in my HTML; and then the author changes things in ways I don’t like? It’ll break my website. If I used something like `https://unpkg.com/mvp/v2.3.45/mvp.css` I’d be sure it wouldn’t happen.
I use this framework a ton and it's great for things like building an API where you need an absolutely minimal frontend. For things like this I'm already writing minimal CSS, this just lets me slap a one liner in the head and make the frontend look marginally nicer. Issues like the version and semantics are not a concern because the "point" is to build the API and the frontend will get tossed (and yes I realize I can use Postman/Hoppscotch, i use those as well).
Fair point. I’ll update the site soon to explicitly use a version.
Thanks for pointing that out!
You can always just copy it yourself.
I'll take a basic tailwind install for this use any day. Not it's not minimal but it is reliable and straightforward for prototyping..
All the supposedly JS-free CSS frameworks use JS for their most basic components.
I bought a template on one of those template sites but it needed like 20 JS scripts just to display the landing page.
I thought of trying the Zengarden stylesheets but they didn't cover the components I needed for a saas website, and they were also way too characterful.
I'm past the MVP stage but I would have paid for this if I had seen it 6 months ago, at least the price of a template: 20-50$.
- Andy Brewer, Author of MVP.css, when talking about MVP.css
Am I missing something?
Source: https://github.com/andybrewer/mvp/issues/76#issuecomment-121...
Dark mode is a really cool CSS feature, but it requires a level of maintenance that goes above and beyond an MVP IMO, so I decided to remove support for it.
I had it included originally, but it meant 2x the QA and 2x the icons in some cases.
If it’s important to you there are other libraries that might be a better fit.
Meanwhile, `a em` is styled as a button.
This is the landing page I built: https://figmage.com
If we're really being pedantic, all uses of <hr> elements on that page are contrary to the spec's desires.
> The hr element represents a paragraph-level thematic break, e.g. a scene change in a story
> There is no need for an hr element between the sections themselves, since the `section` elements and the `h1` elements imply thematic changes themselves
https://html.spec.whatwg.org/multipage/grouping-content.html...
If it isn't clear, I find it a bit silly :)
One pro-tip though — I found that using unpkg slowed down the page a ton sometimes. I serve the file myself and it's been much faster. YMMV but thought y'all should know just in case.
`modern-normalized.css` can be for MVP too. Honestly few < 100 lines on top of normalized one isn't that much work.
Well it’s still a framework. A light one, but still a framework. You still have to learn how it works. For example, `<section><aside>` is interpreted as a card and `<sup>` is a "notification bubble". The worst part is you have no way of disabling this behavior: `42<sup>2</sup>` will always show a "bubble" with `2` next to `42`. What’s "semantic" in that?
"By far the easiest stylesheet I've ever used. It integrates easily into all of my startup projects." MVP.css
- Andy Brewer, Author of MVP.css
I ask, because in the early days of css we also tried to use semantic style and had strange rendering issues on huge data tables and everytime, when the page had a lot of content. After trying a few things we came to the conclusion, that (especially but not only) IE had huge performance issues with semantic style. After switching to classes, everything worked fine. It technically made no sense, but since we did not change anything else, we came to the conclusion, that class based is faster than semantic...
Did anyone ever measure this for modern browsers?
Engines are now good enough you don’t really have to worry about selector performance unless you’re using ridiculously complex selectors, and even then the least efficient part is actually the layout calculation and painting.
This site is super simple and is super laggy on Safari Mac because they use awkward effects and animated gradient backgrounds, for example: https://colorjs.io/
Nowadays you’ll have a thousand problems worth solving before you get to fussing over selectors.
https://frontstuff.io/you-need-to-stop-targeting-tags-in-css...
### Drop-in CSS Frameworks
preview some of these with https://sites.yax.com/
- [Spectre.css](https://picturepan2.github.io/spectre/getting-started/instal...)
- https://gdcss.netlify.app/ (inspired by UK design system)
- https://ajusa.github.io/lit/
- https://andybrewer.github.io/mvp/
- https://github.com/xz/new.css
- https://github.com/oxalorg/sakura
- https://native-elements.dev/
- https://watercss.kognise.dev/
- https://jenil.github.io/chota/
- https://chr15m.github.io/DoodleCSS/ hand drawn look
- https://github.com/susam/spcss
- https://elementcss.neocities.org/
- https://codepen.io/web-dot-dev/pen/abpoXGZ the base classes for web.dev/learn/csss
- https://open-props.style/ css variables framework - "tailwind without tailwind"
- https://github.com/alvaromontoro/almond.css classless css framework. [thin fonts] (https://news.ycombinator.com/item?id=30497165).
- Collections of even more:
- https://github.com/dohliam/dropin-minimal-css
- https://github.com/dbohdan/classless-css
- https://github.com/ubershmekel/cssbed (https://www.cssbed.com/)
- https://thesephist.github.io/paper.css/ and https://thesephist.github.io/blocks.css/
full list here: https://github.com/sw-yx/spark-joy/blob/master/README.md#dro...Just found the stylesheet for my website's redesign, thank you :)
I'm surprised that Tacit is missing from the list though. When it comes to modern design using classless CSS my order of preference is normally water.css, tacit, and then MVP.css. It just looks great and uses the HTML5 semantic elements to their full potential.
I always use this if I need to quickly make some structured info visible on the web. Works on mobile, works in dark mode, looks inoffensive and professional and is super small.
Later on (early 2000s) obviously I'd have to use tables for laying stuff out, then relying on the good work of Jeff Zeldman and the like to beef up CSS knowledge, then finally using stuff like Bootstrap and Tailwind.
In general, I don't think "HTML semantics" are really as stringent as assumed by some commenters. After all, HTML was just intended as a vocabulary for casual academic publishing, but is of course abused for text that could be much, much more simply and adequately described using other, more targeted or customized SGML vocabularies rather than HTML.
[1]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fo...
While it is true that HTML semantics aren't as stringent as often assumed, there certainly are more or less universally accepted best practices. They depend on the complexity of the site itself. (It may also be unclear what a "page header" actually is. It could contain your logo and navigation, but the `<h1>` should rather be in the `<main>` element.)
So this is what my most basic structure inside the `<body>` would look like:
<header></header>
<main></main>
<footer></footer>
If you're doing this with the global page header/footer, there would be no reason to use `<main>` at all: <main>
<header></header>
<footer></footer>
</main>
Also, I can't really reproduce your initial issue regarding the flexibility of page spacing. You are pretty limited when using classless CSS, but where's the problem using the body selector for that?<blockquote><footer> for quote attribution? How does that even make sense?
> Attribution for the quotation, if any, must be placed outside the blockquote element.
… and suggest things like `blockquote + p` and `figure > blockquote + figcaption` instead. I will also note that that use of figure would have been semantically inappropriate a decade ago, when figure was supposed to be something that could reasonably be taken out of the document flow, but now that’s been downgraded to just being a self-contained unit, though it may be able to be taken by itself and it’s generally suggested that you refer to figures by their captions.
I did my best looking at the source in my mobile browser, thinking they’d somehow misused the meta theme-color feature, but they haven’t used that at all. It seems your gripe is that they haven’t provided dark mode styles. Which is a reasonable gripe (and I provide them for my site even though I prefer light mode), but clarity is really helpful especially when criticizing someone’s work in a detailed way.
As far as the blockquote/footer tag combination, it’s definitely not ideal but it is semantically valid.
Anyway, HN has enough people quick to criticize so I’ll leave it at this: you have valid complaints about the submission, but I imagine the authors would be receptive to them as suggestions which take no more effort.
Meta color was new for me -- https://css-tricks.com/meta-theme-color-and-trickery/
But that table. I'm not even sure what to say. How come custom CSS doesn't support semantic HTML? Or makes you use class names? Or is hard to customize? Sure, the last one might be controversial but I'm pretty sure most would agree that the other ones just make no sense.