Both cards were mine
A client asked whether the price on the product cards could be bigger, so I opened the stylesheet and found two of them.
.product-card and .tile. Same idea, near enough the same markup, different padding and a border radius off by a couple of pixels. One of them draws the category pages, the other draws the search results and the “you might also like” row at the bottom of a product. The first went in around the spring and the second in the summer, and both commits have my name on them.
Two other projects happened in between. I came back to this one needing a card on a template that didn’t have one, went looking where I’d have looked on the other project I’d been in most recently, found nothing, and wrote a card. Half an hour, looked right, went out with everything else that week. Nothing anywhere told me the site already had one.
So the bigger price turned out to be a change in two files. I only knew about the second one because I’d happened to be in the search template a few days earlier. If they’d asked in May I’d have fixed one card, told them it was done, and gone home happy.
A committee of one
There’s a lot of good writing about design systems right now and I’ve read most of it, Atomic Design included. It’s genuinely useful and I’ve taken something from all of it.
It is also, almost without exception, written by people at organizations that employ more designers than my agency employs people. The case studies are a bank, a phone company, a government. The problem being solved is a coordination problem, 60 people spread across half a dozen product areas and how to keep them from diverging, and the answers are a contribution model, a governance document, a versioned package. Same schtick every time.
I have a six-week storefront build for a company that sells industrial fasteners, and realistically I am the only person who will ever open that stylesheet.
So the question was never whether any of it applies. It’s which half.
A big team needs a system because people diverge from each other. Two designers, two buttons, and by month four there are nine buttons and nobody can say which one is right. Everything in the literature about governance and contribution and a single source of truth is aimed squarely at that, and aimed well.
I don’t have that problem. There is one of me. I’ve got the same problem turned on its side, because I diverge from myself about four months at a time, and the developer who wrote the first card is not available for comment.
Which means the habits carry over and the apparatus mostly doesn’t. The apparatus is built for people who have to agree with each other. My problem is a person who can’t remember.
Six numbers for margins
Three things survive at any size, including one, and not one of them needs a tool.
A scale for spacing and type, decided once. Per minute spent, this is the highest-value thing I know how to do on a project. It isn’t a system, it’s a short list of numbers, and the moment it exists, “how much space goes here” stops being a judgment call you make dozens of times a build. It becomes a choice between four options, and the site comes out visibly more coherent without anybody having done anything difficult. It’s also the list I generate the spacing utilities from, which is a separate argument I had with myself over the summer and lost.
$space: (0: 0, 1: 0.25rem, 2: 0.5rem, 3: 1rem, 4: 2rem, 5: 4rem);
$type: (small: 0.875rem, base: 1rem, lead: 1.25rem, h2: 1.5rem, h1: 2.25rem);
:root {
--space-3: #{map-get($space, 3)};
--space-4: #{map-get($space, 4)};
}
Both halves are in there for a reason I only figured out last fall. The map is for build-time math and generating utilities, and the custom properties are for anything that has to change per breakpoint or per theme once the CSS has already loaded. Same numbers, two lifetimes.
Named colors, and never a raw hex inside a component. Same argument. If every rule says var(--brand) then the client’s inevitable “can we try it in the darker green” is one line, and if 30 rules say #2f6f4e then it’s a find-and-replace and you will miss the one sitting inside an inline SVG.
One place per component. Not a package and not a repo. The card lives in one file, every template includes that file. There is nowhere else on the project that card markup can be. The discipline is that the moment you catch yourself copying markup you stop and make it a partial, right then, even though it’s 20 minutes you didn’t plan for and you’re busy.
The first two of those were already true on the fasteners site the day I wrote the second card. The scale is most of why the two of them look so similar. So the numbers were fine. The third habit is the one I broke, without ever knowing there was anything there to break.
The page that can’t disagree with the site
Last year I built a real style guide for a client site and wrote a fairly bleak post about nobody opening it. Most of that was distribution, which I still think is the main failure. Underneath it there was a second problem though, which is that the guide was a separate artifact somebody had to maintain, so within a few months it described a site that no longer existed.
Instead I now do something small enough to feel like a cheat. Make a page in the real site, at a real URL, that includes the same partials the real pages include, with sample content in them.
<h2>Product card</h2>
{% include card.html title="A short title" meta="Fasteners" %}
{% include card.html title="A title long enough to wrap onto three lines, because sooner or later somebody types one" %}
{% include card.html title="This one has no image" image=false %}
<h2>Spacing scale</h2>
{% for step in (0..5) %}<div class="swatch swatch--{{ step }}">{{ step }}</div>{% endfor %}
That one’s a Jekyll site because it’s the example I can paste without redacting anything. On the stores it’s a phtml template and the idea survives the translation intact.
Because the page is built out of the same includes, it cannot disagree with the site. Change the card and the page changes. Delete the card and the page breaks the build, which I have come around to liking.
The second thing it gives you, which I didn’t anticipate and now rely on, is somewhere to put the ugly cases. The title that wraps onto three lines, the card with no image, the button with a word in it longer than the button itself. Those are the states that break in production two months after launch, and having them all on one screen means I meet them while I’m building instead of when a client sends a screenshot.
And the third thing is the one this whole post is about, which is that it’s a single screen with every component on it. Coming back to a project cold, that page is 20 seconds of scrolling, and it answers the question I didn’t know I had, which is whether the thing I’m about to build already exists.
What I skip
A separate style guide tool. There are a few good ones now and I’ve tried two of them. For a team they look like a nice way to work. For me they’re a second build, a second set of dependencies to keep current, and a second thing that goes stale the week a project goes quiet, and the cost of all that lands on whoever picks up the maintenance ticket in month nine, which is me.
Publishing anything as a package. Versioning is how people who release on different schedules stay out of each other’s way. I release on one schedule.
Writing down principles. I did this once, a few paragraphs about clarity and restraint. I have never read them again and neither has anybody else. The scale is the principles. It just happens to be executable.
Two jobs, one phrase
My sense is that “design system” is doing two jobs in the way people use it. There’s a set of habits about deciding things once and not repeating yourself, which is free and works at any size, including one. And there’s an apparatus for keeping a large group of people in step, which is expensive and solves a problem I haven’t got.
Most of what gets written is about the second, because the second is where the hard and interesting problems live, and because nobody writes a conference talk called “we agreed six numbers for margins.”
The two cards are one card now. It took an afternoon, most of which was figuring out which templates used which, and the price the client actually asked about was five minutes at the end of it. I don’t think a governance document would have saved me from any of that. A page I have to walk past before I build anything new mostly does.