Ask HN: Front-end “design patterns”?
I've read Duckett's book (Amazon bestseller) and its just syntax. Also, I've read the Atomic CSS design and BEM methodologies, and while those come close to what I want, I'm looking for a more detailed treatment. To give an obvious example of what I'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|11 years ago|reply
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|11 years ago|reply
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.
[+] [-] blawa|11 years ago|reply
[+] [-] TheAceOfHearts|11 years ago|reply
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.
[+] [-] jdlshore|11 years ago|reply
So if your production JavaScript code sets a class based on some piece of business logic, your test checks that it sets that class in that situation. That may mean doing some DOM element creation in your test setup.
Testing HTML and CSS is a bit trickier. I'm developing a tool called Quixote [2] that enables TDD of this sort of code. It lets you do things like say "the login button needs to be 20px to the right of the nav bar." Same deal: you think about what you want your CSS to do, write the test, then write the CSS, then improve it.
Regardless, these are unit tests (or unit-like tests; I don't want to argue semantics), not end-to-end tests. Each one is focused on testing a specific thing, stay inside the browser process, and you use them to drive development. The key is to use good tools; I like Karma [3] because it allows me to run my tests against multiple browsers simultaneously, including mobile devices.
And, with apologies to @Anchor, you should absolutely test using real browsers. There are meaningful differences between browsers and you want your tests to catch those differences. Speed is not a problem if you use good test design and tooling; my Quixote tests use Karma, run against ten browsers, and execute 200 tests / sec.
[1] http://www.letscodejavascript.com
[2] https://github.com/jamesshore/quixote
[3] http://karma-runner.github.io/0.12/index.html
[+] [-] zachrose|11 years ago|reply
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
[+] [-] Anchor|11 years ago|reply
Much of this comes down to decoupling different aspects of the system: persistence (DB), domain logic (business rules), delivery mechanism (web, REST), presentation format, UI layout, etc. This aggressive decoupling enables one to isolate and test these different facets of the system individually. Of course, building this decoupling requires some effort, and one has to be careful not to over-engineer. As with many things, it is a balancing act.
And yes, you can do TDD with the UI; separate the UI logic (user actions, UI state, input validation, etc.) from the layout system (and don't try to test the latter automatically). The fun thing is that when the system is decoupled, you can test the user interface of a JavaScript web application without ever starting a real* browser, running a web server or spinning up a database. It is an interesting system design challenge to be able to run even your UI tests at a rate of 100 tests/second.
*A headless browser is not a real browser in this sense
[+] [-] daniel_puterman|11 years ago|reply
The questions "which elements to check?" and "how many things to validate?" are exactly the questions for which there's a really good and simple answer: use visual testing and validate everything with a single call. Got a signup page with multiple options and inputs? awesome. use visual testing on the page and voila, all the elements and data in the page are validated, no element-specific validation code required. In fact, you can flow through your application, use visual test on every page (or major event), and boom! You got dozens if not hundreds or more elements validated in a single swoop.
Applitools ( https://www.applitools.com ) does an extremely good work in making visual testing trivial, so you can have full blown E2E validation on your website/webapp with almost no validation code actually written. It's worth trying us out. We allow for a free account, and our SDKs are open source.
[+] [-] theyouker|11 years ago|reply
[+] [-] applecore|11 years ago|reply
1. Fitt's Law (of movement to a target area): https://en.wikipedia.org/wiki/Fitts%27s_law
2. Steering Law (of movement through a tunnel): https://en.wikipedia.org/wiki/Steering_law
3. Hick's Law (of choices and decision time): https://en.wikipedia.org/wiki/Hick%27s_law
4. Miller's Law (of working memory): 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
[+] [-] applecore|11 years ago|reply
[+] [-] grandalf|11 years ago|reply
[+] [-] pritambarhate|11 years ago|reply
[+] [-] philipwalton|11 years ago|reply
CSS Architecture http://philipwalton.com/articles/css-architecture/
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...
[+] [-] alanfalcon|11 years ago|reply
[+] [-] airblade|11 years ago|reply
[+] [-] blawa|11 years ago|reply
[+] [-] state|11 years ago|reply
I recommend Josef Muller-Brockmann's Grid Systems in Graphic Design: http://www.amazon.com/Grid-Systems-Graphic-Design-Communicat... or Emil Ruder's Typographie: http://www.amazon.com/Typographie-Manual-Design-Emil-Ruder/d....
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....
[+] [-] mattmanser|11 years ago|reply
[+] [-] blawa|11 years ago|reply
[+] [-] naugtur|11 years ago|reply
[+] [-] BerislavLopac|11 years ago|reply
[+] [-] e12e|11 years ago|reply
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
Also (linked): http://bldl.ii.uib.no/2014/14v-bldl_hiday-JaakkoJarvi-avoidi...
[+] [-] akvlad|11 years ago|reply
[+] [-] karlshea|11 years ago|reply
[+] [-] vonnik|11 years ago|reply
[+] [-] yojo|11 years ago|reply
Like the OP, I'd love to find more resources on good programming patterns.
[+] [-] nateweiss|11 years ago|reply
[+] [-] lightblade|11 years ago|reply
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|11 years ago|reply
[+] [-] 3oheme|11 years ago|reply
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 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/ 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|11 years ago|reply
[+] [-] larrymcp|11 years ago|reply
http://www.amazon.com/Dont-Make-Me-Think-Usability/dp/032134...
[+] [-] blawa|11 years ago|reply
[+] [-] catshirt|11 years ago|reply
[+] [-] BrandonM|11 years ago|reply
> 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.
[+] [-] blawa|11 years ago|reply
[+] [-] blawa|11 years ago|reply
[+] [-] obeid|11 years ago|reply
Nicholas Zakas: Scalable JavaScript Application Architecture https://www.youtube.com/watch?v=vXjVFPosQHw
[+] [-] jongalloway2|11 years ago|reply
[+] [-] toomim|11 years ago|reply
[+] [-] chocopoche|11 years ago|reply
[+] [-] grandalf|11 years ago|reply
[+] [-] jkinz86|11 years ago|reply
www.youtube.com/watch?v=1OKZOV-iLj4