
CSS Zen Garden - eniz
http://www.csszengarden.com/
======
ralusek
I always thought this was funny. This was the embodiment of the original CSS
philosophy, which was to "label your html elements semantically with what they
ARE, and then worry about styling those in the CSS." The whole point was to
get anything style related out of the HTML altogether, the HTML would just be
semantic/content related.

But then Bootstrap and other CSS libraries came out, and completely inverted
the philosophy back to what HTML originally looked like pre-CSS, which is that
you had all of these rules you could place directly in the HTML that would
directly control how the element was styled. In CSS Zen era you could look at
my HTML and have no idea how I intended it to LOOK, whereas in the Bootstrap
era you would look at my HTML and see "row" and "col-sm-3" and know exactly
what I was going for visually.

Now people just make components and will maybe use style variables/tokens.
Just funny how things change.

~~~
thomascgalvin
I've seen people seriously recommend marking up your document like this:

    
    
      <div style="display: table;">
        <div style="display: table-row;">
          <div style="display: table-cell;">
          </div>
        </div>
      </div>
    

How in the nine fires of hell is that better than just using a table?

~~~
spdustin
Because assistive technologies (like screen readers) won’t interpret it as a
table, but the browser will, giving you the ease of table-based layouts
without the accessibility hang-ups.

~~~
lisper
The right way to fix that would have been to add a simple annotation that the
purpose of the table was for styling, not semantics, something like:

    
    
      <table type=for-display-only ...>

~~~
goto11
Why do you consider that better? If I understand your suggestion "type=for-
display-only" would semantically turn the <table> into a <div>. Why not just
use a div in the first place?

~~~
lisper
Because it's DRY. With the top-level annotation, the rest of the table spec
remains unchanged, so if you change your mind and decide that you really want
a display table to be a semantic one or vice-versa you only have to change on
thing whereas if you used DIVs you now have to change not only the top level
but also every row and cell.

~~~
goto11
You don't decide on a lark if you want some content to have table semantics or
not! Tags are selected to indicate the semantics of the content. Content don't
change semantics unless you rewrite it to actually be something different.

In any case, you might just as well decide the table was a list item or
headline then, right? So you would need

    
    
       <table what-i-actually-mean="ol">...

~~~
lisper
So two things...

First, one of the reasons HTML has been as successful and widespread as it has
been is that mere mortals are able to use it, not just trained software
engineers and designers. Mere mortals may not make such decisions on a lark,
but they might make the decision incorrectly and have to go back and change it
for that reason. Why make more work for yourself than necessary?

Second, making changes is not the only reason to make code DRY. Re-using TR
and TD tags is analogous to operator overloading. If you want to add two
numbers you want to be able to write x+y and have the compiler figure out
whether that means an integer add, a floating point add, etc. You don't want
to have to write (say) x II+ y if you want to add two integers, x FF+ y to add
two floats, x LL+ y to add two longs, etc. It's the same for table rows and
cells. The mental distance between tables-for-layout and tables-for-structure
is smaller than the mental distance between integers and floats. It's just
annoying to have to keep telling the computer over and over and over again
"this is for layout" or "this is for structure" particularly in a case where
the number of repetitions can be very, very large. There is no value add in
forcing someone to do substantially more typing when the thing being typed
contains no additional information that the system does not already have.

~~~
goto11
> It's just annoying to have to keep telling the computer over and over and
> over again "this is for layout" or "this is for structure" particularly in a
> case where the number of repetitions can be very, very large.

I have a hard time understanding this scenario. What kind of content are you
working with?

~~~
lisper
What difference does that make?

~~~
goto11
I'm trying to understand the scenario you describe in the context of HTML.

~~~
lisper
If I am inside the context of a <table-for-structure> tag and I want to create
a new row then the only kind of row I can create is a <table-row-for-
structure>. It makes no sense to put a <table-row-for-display> inside a
<table-for-structure> so requiring the programmer to specify <table-row-for-
structure> rather than just <table-row> or <tr> is making her do a lot of
extra typing for no value add. A <tr> inside a <table-for-structure> is
necessarily a <table-row-for-structure> and a <tr> inside a <table-for-
display> is necessarily a <table-row-for-display> just as a + operator
operating on two integer values is an integer addition and a + operator
operating on two floats is a floating point addition. There is no need to
force the programmer to do extra typing to specify what is meant by + in a
particular context. Likewise there is no need to force the programmer to do
extra typing (or thinking) to specify what <tr> means inside a particular
context.

~~~
goto11
But...you _do_ only need to type <tr>. The problem you describe only becomes
an issue if you use <table>s for layout in the first place, so just don't do
that. If you want to display something (which isn't semantically a table) in a
grid-like layout, you use display:table or display:grid in CSS, you don't
change the markup. And vice-versa if you have <table> which you _don 't_ want
to display in rows and columns, you can override the default presentation in
CSS without changing the markup.

The hypothetical <table-for-layout> element is just not needed in any
scenario. It would have been useful back in the day before IE supported
display:table, but that is at least a decade ago.

~~~
lisper
> The problem you describe only becomes an issue if you use <table>s for
> layout in the first place, so just don't do that.

I could just as easily say that the "problem of overloaded operators" only
becomes a problem if you try to use + to add anything other than two ints. So
don't do that.

But OK, assuming I accept the premise, what should I do instead? The CSS
community has been dithering about the answer for years. Only very recently
has there been anything even remotely approaching an acceptable solution i.e.
a solution that actually reproduces table layouts without having to pile on a
ton of hacks. In the intervening years, a lot of legacy code was produced that
used <table> for layout because it was the only thing that actually worked.

There also the fact that <display-table><tr><td> or something like that just
looks a lot cleaner and is easier to read than <div class=table-for-
display><div class=table-row-for-display><div class=table-cell-for-display>.
When you make complex table layout you end up with a lot of TR and TD tags, so
it makes sense to keep those short to avoid cluttering things up.

~~~
goto11
If you genuinely want a layout exactly like a html table you use
display:table. You probably don't, but it is there if you want.

You don't really need repeated class=table-row-for-display etc, this can be
achieved by CSS contextual selectors.

But in reality html tables was not designed as an all-round layout tool in the
first place and the layout algorithm was never specified in detail. Flexbox
and flexgrid are typically more appropriate and powerful as layout tools.

~~~
lisper
> display:table

I tried that once many years ago. It didn't work. It might work today but I no
longer care.

> this can be achieved by CSS contextual selectors

That would be true if display:table worked, but it doesn't (or at least it
didn't) and so it doesn't.

And you still need some markup for the contextual selectors to work on. The
obvious choice is <table><tr><td>, or, if it existed, <display-table><tr><td>.
_Maybe_ <grid><gr><gd> but that's not going to happen.

~~~
goto11
> That would be true if display:table worked, but it doesn't (or at least it
> didn't) and so it doesn't.

Can you describe the problem you are having?

~~~
lisper
No. That last time I tried it was many years ago. Maybe it works now. I
neither know nor care.

~~~
goto11
So you are basically just trolling at this point.

~~~
lisper
No, I'm giving you honest answers to your questions. Just because I have not
gone back to explore a broken feature to see if it is no longer broken doesn't
make me a troll.

But my point stands even if display:table works nowadays. The problem is not
_what_ you have to type in order to specify that some piece of markup should
be displayed as a table even though it is not semantically a table. What
matters is _how much_ you have to type, and whether you have to redundantly
specify that a table is for display only on every row and cell. To use
display:table you also have to specify display:table-row and display:table-
cell, and you have to do it again and again and again and again even though
all this information is redundant and only needs to be specified once at the
top level. There is absolutely no rational justification for this. It would be
as if you had to specify the type of a variable in C not just when it was
declared, but again every single time you referenced it.

------
adamwathan
This approach is extremely seductive because on the surface it sounds so
"pure" and "clean" but the reality is that on large projects it leads to some
of the most horrific, hard to maintain CSS you'll ever see, no matter how hard
you try to keep things in good shape. CSS is just inherently more difficult to
maintain than HTML, and choosing a workflow that encourages editing CSS
instead of HTML just makes things harder and harder over time.

Choosing an approach where CSS is treated like a third-party dependency that
is _consumed_ by your HTML ends up being much more practical, maintainable,
and scalable because editing and maintaining HTML is _easy_ — every time you
change a class on an HTML element your changes are local and predictable.

Always thought this article by Nicolas Gallagher did the best job arguing this
point:

[http://nicolasgallagher.com/about-html-semantics-front-
end-a...](http://nicolasgallagher.com/about-html-semantics-front-end-
architecture/)

~~~
andre-lima
But can you do what CSS Zen Garden does only by changing HTML? If you can't,
it means you failed at separating concerns.

Additionally, applications that you need to customize/theme usually makes it
hard for us to edit the HTML. The only option is to edit the CSS. In this
case, you whole argument breaks down.

p.s.: In your case, I believe Tailwind should be pushing more for the use of
@apply, instead of making those god-awful markups :(

~~~
adamwathan
> But can you do what CSS Zen Garden does only by changing HTML?

Yes of course you can, if you can change the HTML you can build an entirely
different website, and you don't have to change the CSS at all because with
something like Tailwind it's a "universal stylesheet".

~~~
andre-lima
You'd still need to write some custom CSS depending on the design you want to
achieve, though. So, you're finally not only changing just the HTML.

~~~
adamwathan
Not true at all. You can build two sites that look completely different
without changing the CSS at all if the API of the CSS framework is low level
enough, like Tailwind, Tachyons, etc.

------
crad
I recently brought this up with my team. As an "old-school" web developer, I
buy in to the whole CSS as design thing, while the front-end engineers @ work
switched to using styled react components. As we look to make substantive
design changes, now we have multiple places to make the CSS changes, only now
it's the SASS project and all of the React components / projects. I must be
missing something about how hip and cool styled components are, but they'll
never be as cool as the CSS Zen Garden :)

~~~
exclipy
I also started coding when CSS Zen Garden was the best thing ever but sorry,
CSS in JS is better.

With classes and a separate stylesheets, there are no statically analyzable
connections between them. You typo a class name? Too bad. You're no longer
using that class anywhere? No compiler will tell you it's dead code. You want
to increase the padding in this one place? There's no way to be confident what
else it will affect.

And all the "benefits" that stylesheets tout are also offered by components.
No one is adding <font> tags on all on all of their headings. With components,
you just set the font once on the heading component.

~~~
e12e
> No one is adding <font> tags on all on all of their headings.

Ok? I'm not sure the official documentation is encouraging factoring out
things like font styles to a central place, so you for example easily change
the look from serif to sans, or adopt a signature font?

Am I missing something?

[https://reactnative.dev/docs/text](https://reactnative.dev/docs/text)

~~~
exclipy
The original argument for CSS from 20 years ago was:

Instead of saying: `<font size="20"><b>Some heading</b></font>` 100 times, CSS
proponents would tell you to just write `<h2>Some heading</h2>` 100 times with
styles defined separately as `h2 { font-size: 20pt; font-weight: bold; }` so
if you need to change it to 22pt, you can make one change instead of 100.

Components give the same benefit. Just write `<Heading>Some Heading</Heading>`
100 times with the definition `function Heading(props) { return <h2
style={{fontSize: 20pt; fontWeight: bold}}>{props.children}</h2>; }`. If you
need to update it to 22pt, it's still just one change; not 100.

* replace `style=` syntax with your CSS-in-JS framework of choice for better performance.

~~~
e12e
Right, but in the example linked from the official docs, the css/style is in
the component. So you need to change all your comp, rather than the body font
style?

(obviously you can mix and match, it just seems that the official
documentation/sentiment is towards self contained components that don't
support page/application level theming/styling)

~~~
exclipy
You're subscribing to the notion that it's _good_ to put all your styles for
all components in one file. Since the invention of variables, that is wrong.

Theming is no longer a valid argument for centralized style sheets. If you
declare one central set of variables for, eg., colours or fonts, then you can
still do "application level theming" (changing those colours/fonts in one
place), without having to mash all the styles for every element in the entire
app together in one file.

The advantage of using JS variables to represent this is you can easily ask
your IDE to "find all references" to that variable. It's much easier for
humans than reasoning about CSS inheritance and the cascade.

------
mythz
CSS Zen Garden was a treasure back in the day, one of the most inspirational
CSS sites showing the power and flexibility that can be achieved with CSS over
semantic HTML.

I still remember the original design from Dave Shea fondly:

[http://www.csszengarden.com/001/](http://www.csszengarden.com/001/)

~~~
klenwell
One of my quixotic personal projects was reproducing this design for my
Myspace profile.

Ha, I found the blog I was keeping:

[http://myspacecivilized.blogspot.com/2006/09/css-moshi-
garde...](http://myspacecivilized.blogspot.com/2006/09/css-moshi-garden.html)

It includes a small screenshot.

------
GavinAnderegg
I remember this blowing my <table>-addled brain in 2003. This site was what
convinced me to really dig into CSS, and not just use a few inline styles as
hacks. This also opened my mind to JavaScript at the same time (as I looked
into "DHTML"). It was a pretty different web back then!

~~~
schoen
I'm amused at how I glanced at your comment and my mind sort of yelled "hey,
that opening tag never gets closed! that's going to invalidate everyone else's
comments below by making them part of that element!".

Maybe I'll say </table> here just in case. :-)

------
omegote
I cannot believe it's been 15 years, literally half my life, since I got my
design accepted at CSSZenGarden:
[http://www.csszengarden.com/185/](http://www.csszengarden.com/185/)

Incredible, I had never thought of how long it's been...

~~~
mikeg8
I remember seeing your design back around 2009 when I was taking my first web
“publishing” courses! What a trip down memory lane

------
austincheney
[http://mailmarkup.org/zen/](http://mailmarkup.org/zen/)

This is my Zen Garden attempt. According to the HTTP headers it is from 20
October 2008.

You can see how font rendering has changed over the years. When I wrote this
all columns were the same height and alignment cross browser.

~~~
bendotero
It looks great. Nice job. I miss the web from this era. Sites looked so much
more unique. People posted to their own sites and syndicated content. Feed
readers were useful. Sigh.

------
wiremine
Wow, what a blast from the past!! This was a great source of inspiration back
in the day.

If you're not familiar with the project, I suggest checking out the Wikipedia
article:

[https://en.wikipedia.org/wiki/CSS_Zen_Garden](https://en.wikipedia.org/wiki/CSS_Zen_Garden)

------
cromulent
Ah so many memories. This was my favorite:

[http://www.csszengarden.com/099/](http://www.csszengarden.com/099/)

Dave Shea mentioned that it was no longer relevant back in 2013.

[https://www.awwwards.com/why-the-web-doesn-t-need-another-
cs...](https://www.awwwards.com/why-the-web-doesn-t-need-another-css-zen-
garden.html)

~~~
teddyh
“This video is unavailable.”

------
fiatjaf
Some time ago I made
[https://github.com/fiatjaf/classless](https://github.com/fiatjaf/classless),
a framework for making themes for simple websites (like blogs) using the same
basic HTML structure.

The idea is: you write HTML that conforms to the structure, then you can reuse
any of the themes by just including a CSS file (and sometimes a JS file) in
your <head>.

Turns out I wasn't the best person indicated to push this, as my design skills
weren't marvelous, but I still think it was a good idea. There are 17 themes
available, mostly ported from other places. A playground where you can see the
themes (and test your own, if you are feeling like building one) is available
at [https://classless.alhur.es/](https://classless.alhur.es/)

------
theandrewbailey
I wrote my blog's HTML[0] semantically, and I'm glad I did. I have a different
style when someone fires up a new instance. I was already going for a retro
"vaporwave" aesthetic there, and that recent Windows 93 post[2] pushed me over
the edge. I apply those styles to my main site as an Easter egg when you view
it in the Japanese locale.[1]

[0] [https://theandrewbailey.com/](https://theandrewbailey.com/)

[1]
[https://theandrewbailey.com/?lang=ja](https://theandrewbailey.com/?lang=ja)

[2]
[https://news.ycombinator.com/item?id=22463415](https://news.ycombinator.com/item?id=22463415)

~~~
saagarjha
Semantic HTML also happens to work quite well on even the most anemic
browsers! I am somewhat proud that a non-HTTPS version of my website (which is
designed for modern browsers) is navigable and fairly usable on the original
WorldWideWeb, aside from some of the <head> content poking through.

------
RyanOD
Dave Shea (CSS Zen Garden), Eric Meyer, Jeffrey Zeldman (A List Apart), Jeremy
Keith (DOM Scripting), and others who escape me provided the foundation for
the CS classes I taught 15 years ago. Thanks guys!

------
coreyp_1
Honestly, these designs are so refreshing. There is no place for ads. No
popups asking to subscribe to their newsletter. No breaking because I have
Javascript disabled.

Looking through some of the designs made me happy... and a bit nostalgic. :)

------
antirez
Good memories from 10 years ago (the site looks practically unchanged since
then). Incredibly how the frontend nonsense of recent years allowed us to go
backward. Same result but slower and more complex without any good reason.

------
andre-lima
I truly believe this is still the way to go if you want to have any hopes of
keeping your HTML/CSS maintainable and easily customizable.

------
piinbinary
Seeing this page brings back memories:
[http://www.csszengarden.com/001/](http://www.csszengarden.com/001/)

I'm happy that this is still online.

------
TiredGuy
Separation of html and css can still be a useful paradigm and does not have to
be incompatible with separating your code into components.

For medium-sized projects, I have found it useful to have general (or "base"
and "cosmetic" a la MCSS) styling in a central place with all my variables.
For my components, I strive to balance the "structure-" and "container-" -like
(similar to OOCS) styling they need while not trying to make them so general
that they are over-engineered. To that end, I am comfortable enough using the
central variables within my components and even some central classes,
recognizing that when I do want to re-use my components across projects there
is occasionally ad-hoc refactoring/customization.

Also, Css in JS is only one way of building components. You can keep your
component-specific css separate from the rest without using JS.

------
gijoeyguerra
Cool. XML, by way of HTML was always designed to be layered. As in, a layer
for a different use case. At the lowest layer, is the data. Each layer used to
decorate the layer below it enables using it for different use cases. CSS is
just another decoration to create another layer used for another use case
(styling the data for the rendering in a browser use case). While keeping the
underlying data still usable for a totally different use case. CSS Zen Garden
is such a fantastic showcase of that layering architecture of HTML.

Regarding Javascript applications, I consider it just another case where we're
using the design of the web for something it's inventors could never foresee.
Well, they did foresee "apps", but I'm just not sure React, Angular, Ember,
etc. apps was what they were imagining.

------
subless
I see a lot of people bickering here in the comments about what's better and
why, but does it really matter? I mean I don't care if you like to wear rain
boots when it's sunny or flip flops when it's raining, as long as you have
some footwear on.

There's many ways a webpage could be programmed/designed/developed/styled but
the only thing that really matters is that it's usable and visible to the end-
user. No programmer likes every other programmers code when they have to work
with it and we all know there's ten different ways to solve the same problem
so just let people do it the way they know how as long as you can use/view it
with no major issues who cares.

------
djsumdog
I use to own this physical book!!! .. years and years ago (I think around 2008
or 2009). I cite it as my inspiration for a lot of my early designs:

[https://battlepenguin.com/tech/a-history-of-personal-and-
pro...](https://battlepenguin.com/tech/a-history-of-personal-and-professional-
websites/)

It might seem dated, but the ideas of using images and flowing layout shaped
that era, and the simplicity can still be applied today (although we can make
it look a lot better and cleaner thanks to CSS grid, flexboxes and other new
tech that's now available in most browsers).

There's a lot of good nostalgia here if you go through their older designs.

------
uk_programmer
I really like CSS Zen Garden and it had a profound impact of how I think about
front-end work. I see a lot of back-end developers trying to force the markup
and their styling to conform to what they want.

If you understand how the document flows, separate your CSS from your markup,
write clean and valid markup and keep everything as minimal as possible. There
is really a "zen" like element to it which I think is kinda lost today.

However when it comes to code I am a minimalist and tend to do as much as
possible with Vanilla JS.

------
cousin_it
Encoding page layout in text is a bad idea, and CSS is a bad implementation of
that idea.

What could be better, you ask? Open up Google Slides. You can make a slide
that looks the way you want it. The learning curve is nonexistent. Then you
can share it online and it will look okay to anyone on any size screen.
There's no reason why building websites should be a hundred times harder than
that.

~~~
bmn__
This does not come close to the Web's design goals.

------
basseq
I was a huge fan of the CSS Zen Garden, and was so excited to have my
submission accepted back in 2006 (#106!) when I was first starting out.

Generally, it was a great demonstration of CSS at a time when CSS was rather
novel, and the "separation of content and presentation" sticks with me today,
and forms a good foundation for things like built-once responsive web design.

For me personally, I met a lot of interesting people through CSSZG, including
Bill Zeller (RIP[1]) and others.

[1]
[https://news.ycombinator.com/item?id=2074109](https://news.ycombinator.com/item?id=2074109)

------
dullroar
Still love the retro theater design - so fun:
[http://www.csszengarden.com/202/](http://www.csszengarden.com/202/)

------
TekMol
Would be nice if the designs would display the date when they were created.

Digging around in the source code and on the sites of the designers, it seems
they have stopped adding entries around 2013.

I wonder why.

------
dang
Related from 2013:
[https://news.ycombinator.com/item?id=6076163](https://news.ycombinator.com/item?id=6076163)

[https://news.ycombinator.com/item?id=5669601](https://news.ycombinator.com/item?id=5669601)

A bit from 2009:
[https://news.ycombinator.com/item?id=811468](https://news.ycombinator.com/item?id=811468)

------
hackbinary
From Dave's current site:

[http://daveshea.com/projects/zen/](http://daveshea.com/projects/zen/)

------
m23khan
Hehe, I remember impressing my Web Development Professor 11-12 years ago by
using CSS designs based off this website.

I am still impressed by the beauty of some of the designs.

------
talkingtab
My immediate response, as someone who does not know css that well and is
trying to learn, is to open developer tools, choose responsive design mode and
then iPhone 6. Only looking at the top four, none of these are that great.
Where is a way to navigate? They don't seem to be using vw which I expected.
Are there good examples that work well with responsive, provide navigation and
don't use horizontal scrolling.

~~~
randomdude402
The site predates smartphones by maybe five years. Mobile friendly wasn't a
thing yet.

------
purmac
I enjoyed browsing CSS Zen Garden and read Eric Meyer's CSS articles when I
was still in school 15 years ago. Time flies and so as Front-end stack.

------
swyx
oh nice to see this on the web again! i recently remade this with modern web
technologies - Svelte, Monaco, and serverless functions to pull things from
GitHub Gists: [https://github.com/sw-yx/svelte-zen-
garden](https://github.com/sw-yx/svelte-zen-garden)

------
edem
I love this site. I used this site back then to learn all about HTML and CSS
and the fact that it still works with those age-old designs is a testament to
the original CSS philosophy.

------
120photo
I love this site and visit from time to time. It reminds me of a time when you
thought of web design as art. Now it feels like playing with building blocks.

------
ChrisMarshallNY
I've always enjoyed this site. I see that they post updates here fairly
regularly.

------
Tade0
All those who repainted their pages in dark mode should take lessons from
"Steel".

Not all fonts are readable when displayed white-on-black, and some seem to
forget about that.

Also this is something that's being slowly undone by ideas like Styled
Components and Tailwind. My take is that those two are a step back.

------
dbtc
The zenist of css designs for this web page is:

body { max-width: 800px; }

Done. Now go do nothing.

------
olivermarks
this era broke me as a web designer. Dom walking etc. i need to get back into
current trends so this discussion is useful.

------
resters
A story like this being at the top of HN is how we know covid-19 is serious.

------
maverick74
aaaahhh good old and amazing CSS Zen Garden!!!

------
greggturkington
Why is this the top post of the front page? Is there a front-end dev that
didn't see this when they were 15? Sure it's a nice demonstration of CSS
but...

~~~
dsego
This gets posted every few months and the HN crowd loves it. Somehow all the
technical geniuses here are still mesmerized by CSS from 20 years ago.
Learning all the nuances of the Rust borrow checker doesn't leave any room for
much else, except for HTML tables, that stuff got embedded too deep. Set a
reminder, it's an easy way to reap the sweet karma.

~~~
greggturkington
Well said. I just wish the Zen Garden would put a big banner at the top that
says "the cascade turned out to be a terrible idea, now all CSS is JS, and
it's scoped to the component using exclusively single-class-selectors with
non-deterministic names."

I see quaint selectors like `#main aside .wrapper .design-selection` and just
hope jr devs aren't trying to emulate them.

