

Ask HN: Front-end “design patterns”? - blawa

Hello HN, Are there any treatments of the topic of web front-end software design? I&#x27;m looking for something similar to &quot;Design Patterns&quot; (http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Design_Patterns) but for web front-end HTML&#x2F;CSS.<p>I&#x27;ve read Duckett&#x27;s book (Amazon bestseller) and its just syntax. Also, I&#x27;ve read the Atomic CSS design and BEM methodologies, and while those come close to what I want, I&#x27;m looking for a more detailed treatment. 
To give an obvious example of what I&#x27;m looking for- I would say, use margins to separate multiple instances of same components (among other uses). I wonder if there are books that deal with similar, but non-obvious topics.
======
meesterdude
Its not as rigid as software design patterns, and I think that's by design.

I'll try to share some tips - hopefully this is the kinda thing you're after -
i recognize some of it might not be on topic.

* use html partials to reduce complexity

* think about cachability and rendering needs - sometimes a simple display feature can have huge ramifications on code required and complexity

* semantic markup is optional, but definetly helps break up a sea of divs, and is good for people who use screen readers

* decouple your HTML from your CSS - if something is to be blue or big, it should be from the CSS, not because it has a "big" or 'blue" class. (see: csszengarden.com)

* scss & co are really useful, but be careful to not go overboard.

* don't assume what fonts your users have - linux, mac, win all differ. if unsure, check all 3 platforms rendering

* load JS at the bottom of the page to prevent render blocking (vs. in the head)

* always test browser size reflow & zoom rendering

* always test css,html, js validations

* test design in grayscale/color blindness simulations

* be aware of browser compatibility and vendor prefixing needs - its not cookie cutter.

* flexbox is new on the block, but it's dreamy to work with and is great for layout (shoutout to flexboxin5.com for helping me)

* code comments, such as those that highlight return values, or why something is X, are hugely helpful

* check for unused CSS - there are a number of scripts/browser extensions/sites that can tell you what CSS is never used, and help you remove it.

* same for JS - make sure you still need / use it all

* html/css is rarely (for me) polished at first pass. Iteration is instrumental at arriving to clean, maintainable code.

~~~
coldtea
> _semantic markup is optional, but definetly helps break up a sea of divs,
> and is good for people who use screen readers_

Amen for the "optional" part.

Designers who don't really understand programming, reusability etc had this
fad in the mid-2000s were they made "semanticness" some kind of holy grail, as
if an html pages were meant to be data abstraction/interchange formats.

~~~
Loque
I definitely fell victim to this - I would still aim to be as semantic to the
data as possible but don't lose much time/sleep over it - especially when the
last point has been very true in my experience.

------
TheAceOfHearts
Along the same line... Any good resources on building maintainable
applications with user interfaces? It doesn't have to be web applications, it
can be a book focused on building desktop or mobile applications. I'm more
interested in the patterns the follow, as well as what and how they focus on
testing.

I've found TDD pretty much impossible when you're building a user interface.
Even when I test my components (recently using react, prior to that using
angular), it's hard to know _what_ I should be testing for. Testing the
component's logic is a given, and usually very straightforward. But how in
depth should my DOM structure validation be? Should I check that certain
classes and IDs are set correctly and leave it at that? Should I verify the
DOM structure of the component? I've found this extremely difficult because
you'll often find yourself adding or removing classes to restyle components,
or you'll find yourself rewriting the HTML to fit better with a redesign of
some sort.

Along this same line, what about e2e tests? I test core user interactions
(e.g. user can create foo) with e2e tests, and edge-cases with unit tests.
These tests will be clicking around and sending keys to inputs and eventually
reach some state that confirms that the action was successful. Among all the
states that were traversed, how many things will you validate (e.g. check that
the link the user clicks is in a list, check that in the final state he can
view all of foo's information)? And how in depth? (e.g. checking that #foo
contains all of foo's information, or checking that #foo contains .bar, .baz,
.qux, and that each contains part of foo's information)

I've figured out some patterns and guidelines over time, but some of these
tests tend to feel brittle or useless.

~~~
zachrose
Forgive me for being vague and brief, but I've been trying to test my UIs for
the last year or so and this is what I've come up with.

I've found the ideas in Gary Bernhardt's talk, Boundaries (1), to be very
helpful in figuring out how to test interactive web UIs. The basic idea is
that DOM manipulation can be an "imperative shell" with as little logic and as
few conditionals as possible. Derive the state of your UI component with
separate functions and methods that return plain values (a "functional core"),
and write tests for those because testing for values is easy.

So no, don't test for the presence of classes and IDs. Test your imperative
shell once, maybe even manually or with an integration test, and that's
probably enough.

Angular and React both encourage something like this approach, but you don't
need those technologies to do it this way. In Backbone, for instance, just try
to avoid conditionals and logic in your templates and render methods. If you
think your UI piece needs to render with conditionals because it can be in
different states, ask yourself if those states are just appearances that can
be programmed declaratively with classes and CSS.

Also, testing is so much easier when you limit API surface areas. So if you're
using a library like Backbone, where models and views both have many methods
with many ways they can be called and used, don't give them direct references
to each other. I've had some success in having models and views communicate
only with a global event bus, which means my objects don't even know about
each other. This makes them easier to specify, which makes them easier to
test, which usually results in more focused interfaces and responsibilities.

(1)
[https://www.youtube.com/watch?v=yTkzNHF6rMs](https://www.youtube.com/watch?v=yTkzNHF6rMs)

~~~
Chris_Newton
I often plan large-scale UI code as three fundamental levels:

1\. Model data

2\. View data

3\. Rendered data

The model data comes from whatever underlying data store and business rules
you are working with.

The view data contains every value you need to render your UI. This typically
includes a lot of data taken straight from the model. However, it can also
include derived data, perhaps the result of some arithmetic calculation or the
outcome of some conditional logic. This is also the level where any view
metadata that isn’t persisted in the model lives, for example if you need to
keep track of a cursor position, zoom level, contents of a clipboard/kill
ring, etc.

The rendered data level only applies if you’re creating your UI using a
descriptive/declarative system rather than by calling some sort of API. For
example, for a web app, the rendered data would be HTML ready to put into the
DOM. At this level, I try to keep the logic trivial; you might need some basic
conditional or loop logic in the rendering, but the view data is where
anything complicated happens, and the rendering logic in something like an
HTML template shouldn’t be more complicated than “if (simple boolean value
provided by view data) then (version A) else (version B)” or “for each item in
(list provided by view data) do (render individual item)”.

Ideally, the conversions from model data to view data and from view data to
rendered data are pure (as in without side-effects) functions, and therefore
in principle they are amenable to automated testing techniques in isolation.
For example, it is straightforward to add unit tests that calculated view data
do have the expected values for sample model data.

In practice, I find automated testing of the view data to rendered data stage
has very little value, for two reasons. Firstly, if your rendering stage is
basically just filling out templates using view data and the logic is trivial,
errors tend to be obvious: a table has no contents, for example, or an entire
part of the page disappears. Secondly, my experience is that most of the bugs
I find at the rendering level don’t actually originate in the rendering logic.
Rather, they tend to be in some accompanying data, such as a CSS stylesheet
that didn’t include the right prefixes or got the media queries wrong, or as a
bug in the rendering engine itself that is out of your immediate control, such
as a browser layout engine bug.

Edit: Of course, the above only describes data going one way through the
system. Depending on the application, you might also have interactions that
update view meta-data, and in anything beyond pure visualisation code you’ll
surely have interactions that need to update the model data. This is also
amendable to automated testing, as long as you have reasonable separation
between (a) the code that does things like validation, constraint checks and
eventually state modification at the model and view levels, and (b) whatever
event-handling or other code starts the process. In this case, it’s that
event-handling or other trigger code that is the part where bugs tend to be
either obvious or outside of your immediate control, and you can have unit
test suites for everything below. You can also use tools like Selenium to
simulate those initial interactions and test in a more end-to-end fashion in
real browsers.

------
applecore
The most important idea is testing the user experience according to the
following five "laws" of human-computer interaction:

1\. Fitt's Law (of movement to a target area):
[https://en.wikipedia.org/wiki/Fitts%27s_law](https://en.wikipedia.org/wiki/Fitts%27s_law)

2\. Steering Law (of movement through a tunnel):
[https://en.wikipedia.org/wiki/Steering_law](https://en.wikipedia.org/wiki/Steering_law)

3\. Hick's Law (of choices and decision time):
[https://en.wikipedia.org/wiki/Hick%27s_law](https://en.wikipedia.org/wiki/Hick%27s_law)

4\. Miller's Law (of working memory):
[https://en.wikipedia.org/wiki/Miller%27s_law](https://en.wikipedia.org/wiki/Miller%27s_law)

5\. Power Law (of practice and reaction time):
[https://en.wikipedia.org/wiki/Power_law_of_practice](https://en.wikipedia.org/wiki/Power_law_of_practice)

~~~
grandalf
This is awesome. I'm imagining a fluffy UX/design conversation being replaced
by a proof.

~~~
21echoes
In my time working with designers, almost all of them refer constantly to
these rules (esp. Fitt's, Hick's, and Miller's which basically reduce to "big
buttons", "few choices", and "no memory required", respectively).

However, these laws are just constraints and trade-offs -- most of the time
your competing candidate designs will follow them an equivalent amount. At
that point, most designers don't reach for "proof", but rather for "evidence",
e.g. user research studies.

------
philipwalton
This topic interests me as well, and I've written about many of these ideas in
the past. They're not necessarily analogous to the GoF design patterns, but I
think they're similar in spirit. I hope you find them helpful.

CSS Architecture [http://philipwalton.com/articles/css-
architecture/](http://philipwalton.com/articles/css-architecture/)

Side Effects in CSS [http://philipwalton.com/articles/side-effects-in-
css/](http://philipwalton.com/articles/side-effects-in-css/)

Decoupling Your HTML, CSS, and JavaScript
[http://philipwalton.com/articles/decoupling-html-css-and-
jav...](http://philipwalton.com/articles/decoupling-html-css-and-javascript/)

~~~
blawa
Thank you. I read them and they are exactly what I'm looking for. May I ask
how you learnt this so that I can too?

~~~
philipwalton
Honestly, at my previous company I worked as the sole front-end engineer on a
team with mostly classically trained programmer types (all CS majors), and it
started to become very obvious that the "traditional front-end best practices"
for CSS weren't going to cut it for us.

Most of the recommendations I make came from learning things the hard way.

As a concrete example, early in my time at this job I needed to make a small
CSS change in some template. I made the change, checked it in, and then like
50 tests started failing. I found it absolutely crazy that my changing such a
trivial, visual thing would break so many functional tests, so I started
suggesting that we not use the same classes for styling as we did for local
hooks. I didn't know the word for it at the time, but there was clear coupling
between our style and functional classes.

Anyway, it was little things like that, over time, that helped be develop much
of my philosophy on this stuff.

~~~
blawa
Thank you for taking the time to answer.

------
state
I strongly believe that in order to do good interaction work you really just
need to understand typography well. That might not be a popular viewpoint
around here, but I encourage you to consider some of these references.

I recommend Josef Muller-Brockmann's Grid Systems in Graphic Design:
[http://www.amazon.com/Grid-Systems-Graphic-Design-
Communicat...](http://www.amazon.com/Grid-Systems-Graphic-Design-
Communication/dp/3721201450) or Emil Ruder's Typographie:
[http://www.amazon.com/Typographie-Manual-Design-Emil-
Ruder/d...](http://www.amazon.com/Typographie-Manual-Design-Emil-
Ruder/dp/3721200438).

There are many, many other good resources but those are important primary
sources. So is The Elements of Typographic Style, by Robert Bringhurst:
[http://www.amazon.com/gp/product/0881792128/ref=pd_lpo_sbs_d...](http://www.amazon.com/gp/product/0881792128/ref=pd_lpo_sbs_dp_ss_3?pf_rd_p=1944687762&pf_rd_s=lpo-
top-
stripe-1&pf_rd_t=201&pf_rd_i=3721200438&pf_rd_m=ATVPDKIKX0DER&pf_rd_r=038MRVMFF37KXY94ER2F).

~~~
mattmanser
It doesn't sound like you know what software design patterns are. This has
absolutely nothing at all to do with design patterns, which is about software
design and how to manage complexity and nothing else. UX is not code.

~~~
bigtunacan
While I agree that the TC intended software design patterns, I don't think a
WTF is in order for the confused reply.

The term "design patterns" stems from architecture, not computer science, and
is used by designers as well for the common patterns that may be applied for
good UI/UX design.

[http://ui-patterns.com/patterns](http://ui-patterns.com/patterns)

Somebody better let Google know that "design patterns" don't apply to UX.

[https://developer.android.com/design/patterns/index.html](https://developer.android.com/design/patterns/index.html)

[https://developers.google.com/web/fundamentals/layouts/rwd-p...](https://developers.google.com/web/fundamentals/layouts/rwd-
patterns/index?hl=en)

~~~
hamburglar
> The term "design patterns" stems from architecture, not computer science

Do you have any references? I find this fascinating, but googling "design
patterns" and "architecture" together just results in lots of "software
architecture" topics. Who originated the idea?

~~~
Isofarro
[http://en.wikipedia.org/wiki/Software_design_pattern#History](http://en.wikipedia.org/wiki/Software_design_pattern#History)

------
naugtur
It looks like I'm first here. Check out Addy Osmani's book first
[http://www.addyosmani.com/resources/essentialjsdesignpattern...](http://www.addyosmani.com/resources/essentialjsdesignpatterns/book/)

------
BerislavLopac
You can always rely on Martin Fowler:
[http://martinfowler.com/eaaDev/uiArchs.html](http://martinfowler.com/eaaDev/uiArchs.html)

------
e12e
Not quite what you're after, but I went a short talk[1] on constraint's based
GUI programming, with some examples from Adobe -- as best I can tell the
examples were related to Adobe's "Adam and Eve":
[http://stlab.adobe.com/group__asl__overview.html](http://stlab.adobe.com/group__asl__overview.html)

The talk focused on things like a (sane) way to model widget interactions in
complex UIs, in a way that reduced the complexity by ignoring invalid
combinations (stuff like height in pixels being updated, when height in
percent is adjusted, without having a rats nests of event listeners across all
widgets).

Other than that, I'm afraid I can't really think of anything other than the
original MVC-stuff by Reenskaug, and his new DCI-stuff (search [1] for
Reenskaug). Things have certainly evolved/changed, but generally it seems to
be about splitting out layout, and handling events in a sane way.

[1] Jaakko Järvi, Texas A&M;: "Avoiding faulty user interfaces"
[http://bldl.ii.uib.no/2014/seminars-2014.html](http://bldl.ii.uib.no/2014/seminars-2014.html)

Also (linked): [http://bldl.ii.uib.no/2014/14v-bldl_hiday-JaakkoJarvi-
avoidi...](http://bldl.ii.uib.no/2014/14v-bldl_hiday-JaakkoJarvi-
avoiding_faulty_user_interfaces.pdf)

------
akvlad
For CSS architecture I thought SMACSS
[[https://smacss.com/](https://smacss.com/)] by Jonathan Snook has really good
design patterns that have been proven to be good throughout his many projects.

~~~
karlshea
I was also going to mention this. Drupal 8 implemented this for all of the
default CSS:
[https://www.drupal.org/node/1887922](https://www.drupal.org/node/1887922)

------
vonnik
O'Reilly has a book called "Designing Interfaces: Patterns for Effective
Interaction Design" by Jennifer Tidwell. It's a little out of date, but has a
lot of the big ideas and useful bibliographies to dig in deeper.

~~~
yojo
I've read this, and appreciate that it is a useful thing. However, (as the
title suggests), it's about the user level interaction design of components,
not code level patterns that promote reuse and maintainability.

Like the OP, I'd love to find more resources on good programming patterns.

------
lightblade
There are definitely design patterns for frontend. There are just no books
being published on this topic yet.

Most knowledge in this area is scattered is varies blog post, tech talks, and
maybe some framework guides. There are a few published as GitHub gists and
readme. Occasionally, you'll find some comments in framework source code that
reference some reading material

But yes, it would be nice for someone to put together a book.

Some example of frontend pattern: \- promise \- data binding \- FRP event
stream

None of these are exclusively frontend, but you'll see them more often in UI
development.

~~~
rimantas
[http://vault.simplebits.com/publications/bulletproof/](http://vault.simplebits.com/publications/bulletproof/)
comes close, alas it is quite old. OTOH it may be still worth taking a look,
because the same way of thinking still applies. Also, it was written in the
golden age of the web. I'd say in those years the cleaniest code was written.
Later we got one-page-web-sites, javascript-everything, moronic war for the
mobile, and crap like OOCSS and BEM, i. e. went back into the mess. We also
got gazillion of frameworks and node powered tools to produce mess even faster
and in larger quantities. I wonder, will we ever get another 'clean the web'
revolition like one in 200x

------
3oheme
I feel that most of the answers in this thread are wrong.

Design patterns, as the wikipedia says, is "a formal way of documenting a
solution to a design problem in a particular field of expertise".

So, it's a solution for a specific problem.

The main issue with HTML/CSS is that people tend to think that there's a best
approach than can work with every website. But different websites require
different HTML/CSS architectures, because they offer different design
problems! It's not the same to create a corporate website than an application
website (just to name two different problems).

I'll use the layout as an example:

There are different ways to define the layout of a website (call it grid if
you want). If I want to create a secondary column, there's the "explicit" way,
where I specify that my div will take 1/3rds of the main layout with a ".col-
md-4" class (like
[http://getbootstrap.com/css/#grid](http://getbootstrap.com/css/#grid) does).
And there's the "semantic" way, where I create a div with the "sidebar" class,
and my CSS will make the div to take 1/3rds (like
[http://neat.bourbon.io/](http://neat.bourbon.io/) does)

None of this two approaches is the best. Each one is a design pattern. And
each one will be a better solution for a different problem.

~~~
nailer
In the visual classes example, your appearance logic in now in two places:
your HTML with the visual classes, and your CSS. Using only CSS or SASS or
whatever else for appearance allows you to have a single place to modify the
appearance of .sidebar items, which is objectively better.

~~~
3oheme
Hi Nailer!

Good call, although I would disagree with the "objectively better" :-)

I'd recommend using a semantic layout when you have an "application website",
like gmail, github or twitter. The layout is strong, and the content needs to
lay within each layout block. For this specific design problem, I think that
the semantic layout is a good design pattern.

But sometimes the problem is different. Sometimes you have a more "editorial"
approach, where you need some specific layout (this is a good example:
[http://stackoverflow.com/questions/24060704/achieving-a-
comp...](http://stackoverflow.com/questions/24060704/achieving-a-complex-grid-
in-bootstrap)). Trying to define that grid semantically is nearly impossible!
And the problem get worse when that grid doesn't repeat anymore, and the next
one is slightly different :-(. In this circumstances, I'd suggest using an
explicit grid system.

There's a myth in web development that says: "If you have a good semantic
markup, you can achieve any design layout with CSS". This is absolutely false!
This kind of myth usually comes from backend developers after seeing
csszengarden. Sometimes you need to add some html tags like divs (that are
harmless, as they don't have any semantic weight). Don't touching the html
will mean going under a CSS hell with hacks and cross browser issues.

Does this sound like bullshit? What are your thoughts?

Cheers!

~~~
nailer
It doesn't necessarily have to be semantic, but your visual styling should be
in your style sheet. I'd do the following to achieve
[http://i.stack.imgur.com/cuCY0.png](http://i.stack.imgur.com/cuCY0.png)
(assuming box model border box):

.story-large { width: 50%; @include scut-ratio-box; }

.story-small { width: 25%; @include scut-ratio-box; }

etc. I actually did something similar in production creating the Microsoft
Surface 2 launch site in 2013:
[http://mikemaccana.com/images/work/screenshots/uncompromise-...](http://mikemaccana.com/images/work/screenshots/uncompromise-2.png)

------
larrymcp
Oh yes, there are definitely books that deal with this: I highly recommend
"Don't Make Me Think" by Steve Krug. Quite an engaging, useful read, and it is
well-reviewed on Amazon.

[http://www.amazon.com/Dont-Make-Me-Think-
Usability/dp/032134...](http://www.amazon.com/Dont-Make-Me-Think-
Usability/dp/0321344758)

~~~
blawa
While not exactly what I was looking for, this is very useful, thanks!

------
catshirt
a lot of the comments here seem misguided. he is asking about software design
patterns, not graphic design patterns. the wikipedia article and BEM reference
should have cleared that up.

~~~
BrandonM
You might be mistaken:

> _To give an obvious example of what I 'm looking for- I would say, use
> margins to separate multiple instances of same components_

I was surprised, too, because I was expecting to see lots of MVC talk.

------
obeid
I watched this old talk from the YUI Library recently. It's framework-agnostic
and not heavy on code, just a lot of common sense that might not be obvious
for some.

Nicholas Zakas: Scalable JavaScript Application Architecture
[https://www.youtube.com/watch?v=vXjVFPosQHw](https://www.youtube.com/watch?v=vXjVFPosQHw)

------
jongalloway2
Here's a nice pattern catalog [http://ui-patterns.com/](http://ui-
patterns.com/)

------
toomim
There's "The Design of Sites", but it's not really about CSS.
[http://www.amazon.com/The-Design-Sites-Principles-
Customer-C...](http://www.amazon.com/The-Design-Sites-Principles-Customer-
Centered/dp/020172149X)

------
chocopoche
I think it's worth mentioning Material design from Google:
[http://www.google.com/design/spec/material-
design/introducti...](http://www.google.com/design/spec/material-
design/introduction.html)

------
grandalf
I think the choice of pattern depends a lot on what you are building and how
much and how often you will need to change it.

------
jkinz86
I think what you're looking for is Harry Roberts' ITCSS?

www.youtube.com/watch?v=1OKZOV-iLj4

------
blawa
(I'm new to HN so not sure how to edit) Thanks for some excellent answers.

So as to keep the discussion to the question's point for posterity, I think I
wasn't very clear. As some people have poined out- I'm not looking for graphic
design patterns, or design from the user experience perspective. I'm looking
for how to design my components. and what should classify as a component, or
what should be an individual template. What should go as a parent and as a
child in the component. Thanks again!

