8 ms·
Show HN: Neat – Minimalist CSS Framework
Today I fixed a couple little bugs and released a new version of my minimalist CSS framework. I built this to scratch my own itch and I've been using it for a few years as the starting point for most of my own websites.
I noticed I hadn't shared this with HN for about 18 months (5 or 6 minor version changes) so I thought it might be okay to do that now.
Edit: Err, I missed a post from 7 months ago.
Previous Posts:
https://news.ycombinator.com/item?id=32990838 https://news.ycombinator.com/item?id=32990838
(7 months ago)
https://news.ycombinator.com/item?id=24594381 https://news.ycombinator.com/item?id=24594381 (Sept 25, 2021)
https://news.ycombinator.com/item?id=26308052 https://news.ycombinator.com/item?id=26308052 (March 1, 2021)
https://news.ycombinator.com/item?id=25660317 https://news.ycombinator.com/item?id=25660317 (January 20, 2021)
https://news.ycombinator.com/item?id=23221957 https://news.ycombinator.com/item?id=23221957 (May 28, 2020)
- lloydatkinson 3y agoWhy don't buttons change on hover and/or click, like they do on both native and web usually?
- itake 3y agoI wish CSS tools had unique names https://neat.bourbon.io/ https://neat.bourbon.io/
- ocimbote 3y agoThis is s recurring complaint and I never understood it. Names are made to be memorable, not unique. Our brains are not a hash table, where every entity would have its own unique key and we'd use it to recall the entity.
- parasti 3y agoAren't they, though? My brain seems very much like a hash table. Duplicate names just make the hash key longer, which is not a big deal but harder to remember.
- quickthrower2 3y agoThat would be a hashtable whose values are lists :-). The buckets are for dealing with hash collisions not key collisions.
- user432678 3y ago<putting on “actually” hat> Brains maybe not, but google search will probably return not the things you’re supposed to be looking for if there are names collision.
- ocimbote 3y agoIf, in real life, your searches are just single keywords like "neat", I'd love to have a peer session with you, I'm bringing the popcorn :D I've just searched a more typical (for me) "github neat css" in DDG and the 1st result is just as expected.
- user432678 3y agoIn this current situation I would google “neat css <some rare problem I was not able to resolve myself>” expecting it show me SO answers or reddit discussions. Instead I’ll be getting information about old and deprecated CSS grid library for Ruby on Rails. I am not saying it’s impossible, just added my “two annoying pence nobody was asking for” :)
- itake 3y agoI agree. Our brains segment information by context. In this situation, we have 2 libraries with the same name in the same context. Now for both of these, I have to store additional context alongside each name in my brain.
- dalmo3 3y agoYeah but which one has greater specificity?
- diceduckmonk 3y agoNPM forces package names to be different. But do we really want a registry for CSS?
- illiarian 3y ago> The body max-width is 800px by default. It should be 80ch (or 70ch), not pixels
- pwython 3y agoThanks for sharing, I love minimalist CSS frameworks that are easy to digest. My go-to for the past ~5 years has been https://milligram.io https://milligram.io -- mainly for the grid and basic styling -- although, the author hasn't updated it in a few years. I'm going to give yours a shot!
- swyx 3y agoi collect these for fun! adding to my collection https://github.com/sw-yx/spark-joy/blob/master/README.md#drop-in-css-frameworks https://github.com/sw-yx/spark-joy/blob/master/README.md#dro... more like this: - https://andybrewer.github.io/mvp/ https://andybrewer.github.io/mvp/ mvp.css - https://yegor256.github.io/tacit/ https://yegor256.github.io/tacit/ - https://github.com/alvaromontoro/almond.css https://github.com/alvaromontoro/almond.css has thin fonts - https://picocss.com/ https://picocss.com/ Elegant styles for all natives HTML elements without .classes and dark mode automatically enabled. - https://simplecss.org/demo https://simplecss.org/demo 4kb incl dark mode - https://watercss.kognise.dev/ https://watercss.kognise.dev/ Small size (< 2kb) - https://github.com/xz/new.css https://github.com/xz/new.css (https://newcss.net/ https://newcss.net/) 4.8kb sets some sensible defaults and styles your HTML to look reasonable - https://github.com/oxalorg/sakura https://github.com/oxalorg/sakura supports extremely easy theming using variables for duotone color scheming. It comes with several existing themes - https://github.com/susam/spcss https://github.com/susam/spcss
- oxalorg 3y agoThanks for mentioning Sakura.css! <3
- bronikowski 3y agoSakura is my drop-in "I need a page" CSS file for some years now. Thank you for making it.
- oxalorg 3y agoThanks, super glad you found a use case for it! :)
- swyx 3y agoi just make lists. you made the thing!
- oxalorg 3y ago
- diceduckmonk 3y ago2KB without minification or gzip, almost fits entirely on one screen. Looks great on my iphone, too. Would have gotten the point across better to just inline the CSS source on the landing page, or linking to the CSS file, instead of having to download a ZIP.
- stakhanov 3y ago> Would have gotten the point across better to just inline the CSS source [...] I agree. The way they're presenting this is truly burying the lead. I'd suggest something along the lines of "Here are 135 lines of CSS that we like, and that we feel might be reusable". It took me an inordinate amount of time to figure out that this was what was being presented to me here. Calling it a "Minimalist Framework" certainly pushed some buttons for me, because I'm all for minimalism, but militantly opposed to almost everything that calls itself a "framework", so as soon as I saw this, I had to go on a mission to figure out what this was, and why they put these two words in a sentence, and was then rather underwhelmed.
- divbzero 3y agoYes, especially when the CSS source is already sitting in cache: https://neat.joeldare.com/neat.css https://neat.joeldare.com/neat.css
- codazoda 3y agoYeah, I agree with you. I'm torn if I should use the Github release process or not on this. The "Getting Started" section lists my own preferred way to download these files. Maybe I should just get rid of this zip file. That would simplify my release process anyway, which I realize is far to complex for this little thing. Thanks for the feedback. Edit: I've reworded the page a bit based on this and other feedback too.
- nine_k 3y ago> one of the technologies that has lasted as long as the Internet is HTML Nit: the Internet is a bit older. Internet as we know it started in 1983 when IPv4 was deployed on ARPANET (otherwise it's even older). HTML appeared in 1993, 10 years after.
- w0z_ 3y agoInteresting, a few observations: -It's really just a container, p, img, and button CSS framework (short of CSS's default flexbox) -There are no components (Codeblock, quote, etc.) -There is a semi-obfuscated IP tracker in index.html While I find it noble in some aspects to create a simplistic blog layout, I also find it odd to post this project.
- nodefortytwo 3y ago> -There is a semi-obfuscated IP tracker in index.html you mean that counter script, it wouldn't expose anymore information than a basic access log, I would assume it just makes it marginally easier to see which of his subdomains are popular.
- halicarnassus 3y agoBut even a basic access most likely violates the GDPR and other regulations.
- codazoda 3y agoInteresting that you mentioned my counter. It exists only in the index.html file on the neat site and NOT in the neat.html file that you're supposed to use for your own. It also DOES NOT log your IP address, set any cookies, or do any other tracking of your personal information. You can read more about that counter, which runs on a Raspberry Pi in my bedroom, at the URL below. https://joeldare.com/private-analtyics-and-my-raspberry-pi-400 https://joeldare.com/private-analtyics-and-my-raspberry-pi-4...
- chrismorgan 3y agoAnother minimalist CSS framework, another review from me. :-) > :root { color-scheme: dark light; } The stylesheet is written with light values by default, and dark values in a prefers-color-scheme media query. Therefore, this should be `color-scheme: light dark` instead. As written, if no preference is expressed, your styles will be light, but UA styles will be dark. > * { box-sizing: border-box; } I personally am one of the rare contrarians that prefers content-box for the web (simplifying my position a lot: good responsive design bases sizes and such on content, not layout). But if you’re going to change it to border-box, you might want to consider changing it on pseudoelements (at least ::before and ::after) as well. Then again, you’re not using them. Then too, the whole box-sizing declaration seems no-op. > * { color: var(--dark); } That’s… um… courageous. No, I can’t leave it at that: this is a very bad idea. This will make custom styling painful, may ruin elements that have backgrounds set in the UA stylesheet (e.g. input, mark), and I detest links being the same colour as the surrounding text. > :root { --light: …; --dark: …; } I don’t like how these two variables are used: you’re using them as #defines (to use C preprocessor lingo) rather than what custom properties can be, and end up with significant duplication because of it. Consequently, every time you use --light or --dark, you have a counterpart the other way round in the tail @media (prefers-color-scheme: dark) block (except that input[type=submit]’s counterpart is just input; I’ll remark on that later). Here’s how you should do it: :root { --bg: #fff; --fg: #404040; } @media (prefers-color-scheme: dark) { :root { --bg: #404040; --fg: #fff; } } … and then use --bg and --fg throughout, and need no more dark color scheme media query at the end. You could define two colours and have --bg and --fg use them, but because of how light works, you may not want to just swap the two colours—for example, you might want to darken both --bg and --fg in dark mode (it’s currently fairly bright for a dark mode; something like #eee on #333 would be more common). > html { border-style: solid; border-width: 5px 0 0 0; border-color: var(--dark); } Shorter written in the :root block before it and as `border-top: 5px solid var(--dark)`. As for what it represents, I don’t like it. It’ll tend to be an eyesore, especially on dark. If it was a colour, sure, but just --light or --dark? Nah, don’t like it. > font-family: sans-serif; Thank you for a sensible font-family. > px There’s quite a bit of not-great usage of pixels. Remember that the root em is not necessarily 16 pixels, so for correctness most px things should actually be defined font-relative. As a simple rule of thumb, take any px value, divide by 16 and change the unit to rem. (Single-pixel lines are about the only place I can think of where px is genuinely what you want, though even then it’s still not guaranteed to be a crisp single pixel, due to possible fractional scaling.) > p { margin-bottom: 10px; } This doesn’t do what you probably intended. Indeed, in the sample document, I think it does nothing: remember that most of your flow content elements have 1em block margin, which is (likely) greater than your 10px, and margin collapse applies. > p { line-height: 1.4em; } Dubious: now anything that’s not inside a <p> uses some other line-height. You probably want to specify line-height on the root element. Remember that line-height accepts a unitless value, too, to be calculated relative to each element’s font-size, whereas em fixes it. Me, I’ve actually started experimenting with this, to conveniently reduce otherwise-extravagant leading in headings: * { line-height: calc(1em + 0.5rem); } That is, 1rem (16px) body text gets line-height 1.5 (24px), 2rem (32px) heading gets line-height 1.25 (40px). > img { width: 100%; } This needs `height: auto`, or else <img width=… height=…> (which you should strongly prefer, to avoid layout reflow as the image loads) will get a mangled aspect ratio. Also consider using max-width instead of width. > button, .button, input[type=submit] I’m not fond of various of the styling here. I reckon it could do with a hover/focus-visible colour change, and no `cursor: pointer`, among other things. > button:last-child, .button:last-child { margin-right: 0; } This kind of thing is smelly. > ol { column-count: 2; } This is a phenomenally bad idea. Some opt-in class, maybe. Numbered lists in general, no. > .row .column:not(:last-child) { margin-right: 10px; } Better, provided you’re OK with as low as two years (to the day!) of browser support (https://caniuse.com/flexbox-gap https://caniuse.com/flexbox-gap): `.row { gap: 10px }`. > Put in four columns and you'll get four equally sized columns. Not true, actually; put something too big in one column and it’ll cause the other columns to shrink. That’s what you get for using flexbox! (Grid, by contrast, is… well, more size-is-defined-by-the-parent-and-the-children-are-welcome-to-lump-it.) Really, I don’t like the columns arrangement. I much prefer to use flexbox with flex-wrap and sensibly-chosen flex-{basis/shrink/grow}, so that the content defines when things can fit beside one another or wrap. The current .row and .column arrangement is much too fiddly, specific, and weird. Also the .column class name is superfluous, should have just used `.row > *`. > input I said I’d address this later, but I’ve taken too long on this. Suffice it to say that there are problems with how form elements other than buttons are handled in diverse colouring situations. Either override (nigh-) everything, or nothing. Never override just one of background and foreground colour.
- its_ethan 3y agoNeat.
- red1reaper 3y agoLookin kinda fire! I love those minimalist CSS frameworks, they are perfect for small pages
- reitanuki 3y agoThe buttons and text inputs being virtually indistinguishable are a slight negative for me, but nifty otherwise. (Also the button appears to have no feedback on hover or click, that would suggest it's a button.)
- euroderf 3y agoI get disappointed when a CSS "framework" lacks styling for semantic HTML too (header, nav, section, article, aside, footer).
- ceving 3y agoWhich problem does it solve? Looks like a list of a few tweaks of some browser defaults.
- hoofhearted 3y agoTailwind comes with a pretty nice base stylesheet that includes a number of browser tweaks and fixes. They call it Preflight https://tailwindcss.com/docs/preflight https://tailwindcss.com/docs/preflight
- 8organicbits 3y agoI enjoy these mini frameworks greatly. I've started to prefer minimalist, and sometimes brutalist, web pages. If I visit a page that's too noisy I switch to reader mode, so that feels like the target I'm aiming towards. The CSS I use for my blog[1] is smaller than this, but it's focused on one use case. I actually really like minimal CSS and HTML for authoring blog posts, it gets me out of the headspace of "what about this theme?", or "why is my blog build not working?" and into just writing. There's no build step, deploy is trivial, and if I need to pull in some custom JavaScript I just do it instead of fighting with some framework middleware. HTML works really well for authoring text based content, which shouldn't be a surprise since that's what it was made for. If you've ever written web pages, then you already know the format. I write it a little different from the author and I think it looks OK. p tags ~will self close~ can omit the end tag (thanks!) <p> A paragraph here. One sentence per line. I feels like a slightly more verbose Markdown, except for lists. The best I've got is: <ul> <li>Item one </li> <li>Item two </li> </ul> [1] https://alexsci.com/blog/improve-https-1/ https://alexsci.com/blog/improve-https-1/ as an example post. Try view source.
- hoofhearted 3y agoDrop your list items down. I aim to have one item per line in my frontend code. It makes a codebase much more readable at scale. <ul> <li> Item one </li> <li> Item two </li> </ul>
- chrismorgan 3y agoYou don’t need </li> either: > An li element's end tag can be omitted if the li element is immediately followed by another li element or if there is no more content in the parent element. — https://html.spec.whatwg.org/multipage/grouping-content.html#the-li-element https://html.spec.whatwg.org/multipage/grouping-content.html... (Note also that “self close” is the wrong description; that’s the XML <element-name/> trailing slash feature, which doesn’t work in HTML syntax outside of SVG and MathML. This is end tag omission.)
- codazoda 3y agoThis is interesting and I've seen others use this short syntax, but it's never worked for me. In the case of Neat, one thing I lose is the margin-bottom of my paragraph tags when I don't close. There's lot of great feedback in this thread, however, so maybe if I apply some of that, the margin won't go away. Yeah, I used a mix of px, em, and other oddities, because I'm a bit old school, I suppose.
- zephyr9 3y agoGreat framework. Unfortunately Apple hijack certain arrow shapes (e.g. the home button) and incorrectly display these as emoji. There’s a CSS override you can add to prevent this but I don’t remember off top of my head.
- efields 3y ago> The body max-width is 800px by default. Research has shown that limiting the width can lead to better retention of the content itself, as well as a decrease in eye strain. A thinner column of text is more readable on very large monitors. This is simple to change by editing the max-width of the body element in your custom.css file. No, edit the max-width of your _content container_. Not every pixel of a site is devoted to content worth retaining.
- throwawayjs 3y agoInspires me to make my own as well. Thanks for sharing!
- lofaszvanitt 3y agoCss is like sql. Doesn't need any kind of abstractions.