Tom Dale: Progressive Enhancement is Dead, Long Live Progressive Enhancement
Animation often needs some space to move in, but with responsive design we know the space we have is ever-changing. Balancing those two factors can lead to some tricky design problems for web animation, especially when you throw performance and design concerns into the mix! Val will break down examples and show you how to design animations that work well at all viewport sizes without driving yourself crazy.
Responsive Field Day is now only five week away! Don’t miss your chance to hear Tom Dale, Val Head and our other fantastic speakers on Friday, September 25th in Portland’s Revolution Hall. Get your tickets while you can!
It was mid-afternoon on a Wednesday when my team started finding strange bugs in older versions of Internet Explorer. At first these appeared to be unrelated… until we noticed seemingly random chunks of style appeared to be missing entirely. What was going on?
Then I looked at the compiled CSS, and realized it was actually my fault.
I’d designed a custom interface element that was pretty complex. Because we were using Sass, I used some fancy mixins and loops to avoid repetition between a handful of breakpoint-specific modifiers. It was easy to read, maintain and modify.
It was so easy, in fact, that I failed to notice that the compiled CSS made up about 25% of the total project’s styles! Even more embarrassingly, I discovered that I could replicate the exact same functionality without most of the loops. I ended up reducing the selector count for that component from 1,207 to just 42 (seriously).
While it was great to find and fix the problem, it shook me up a little. Sass didn’t write crap code; I did. I was so focused on automating my repetitive solution that I hadn’t stopped to ask myself if it was even the right solution.
We recently started using PostCSS for a few of our projects. Every PostCSS feature is a plugin, which we include as needed. So far, we’ve yet to include plugins for nesting, mixins or loops.
Every time we’ve thought to include those features, we’ve instead found a simpler way to do the same thing. Nesting gives way to descendent class names, mixins become utilities, loops are questioned entirely. The initial pain of having to repeat ourselves motivates us to approach the problem in a different way. Repetitive selectors that survive this process are intentional, because a human being actually wrote them.
I know that’s probably silly. It’s definitely not DRY. But there’s a fine line between “smarter stylesheets” and “dumber designer.” Embracing painful repetition by nerfing my preprocessor (especially in combination with analysis tools like Parker) helps me draw that line.
Sophie Shepherd: Designing for a global audience (and how a pattern library can help)
The Ushahidi platform is a data collection tool that has been used by over 18 million people in 150 countries, and translated into 49 different languages. As a designer on Ushahidi, Sophie will talk about the challenges of designing for users around the world with varying devices and connections, languages, and digital experiences, and will explain how a pattern library has made this process easier.
Until browsers add mind-reading event handlers, we have to search for an alternative way to measure how fast users think our sites are. For decades, the go-to number has been window.onload, but modern and responsive techniques have weakened the relevance of that metric. What are the metrics that DO have meaning for what your users are experiencing?
This summer has flown by and now Responsive Field Day is somehow happening next month! Don’t miss your chance to hear Sophie Shepherd, Steve Souders and our other fantastic speakers on Friday, September 25th in Portland’s Revolution Hall. Get your tickets while you can!
It’s not a perfect world, though — ask any ten JS devs what their major points of pain are and all of them will name client-side modules and code packaging:
It’s easy to find boilerplate and recipes for things like setting RequireJS up to make your client-side code modular and even maybe concatenate and minify it for you, but what actually is a module? How do the different systems compare? When should you use AMD or CommonJS or an ES6 polyfill? Just what exactly is Browserify actually doing? I’d like to explore confusing questions like this in this series.
What’s the problem?
It’s inevitably necessary in any nontrivial software project to split code into a tree of interdependent segments. And we need to be able to reuse those segments.
But say segment foo relies on segment bar, and bar in turn absolutely needs the segment baz to get its job done. How do we manage that? Does foo then need to directly ensure the presence of baz (and anything baz needs and so on up the whole chain)? That’s crazy-making and untenable, and it’s the reason that it’s not enough just to split your code into separate files and include the right script tags on each page.
But what’s the bigger picture?
Instead, I want to help you understand the context and the pieces involved in modules and packaging. The goal of this first of three articles is to give you a bigger picture of what modules—the building-block segments of our code—are at an abstract level so that we can start putting them together and making them work.
Then what’s a module?
Let’s step back from any particular language, library or standard and think about modules in the abstract for a moment. What, exactly, is a module? In the strict computer science sense, a module is a way of associating a value (most usually a collection of named subroutines) with a name of some type — and that’s it.
To make this actually useful, however, one also needs a mechanism for specifying module dependencies, that is, a way to say “This piece of code needs the values provided by this list of module names in order to be understood”.
These two parts, taken together with some under-the-hood code responsible for connecting a module name to its associated value, is what we mean when we talk about module systems.
As we’ll see to be a trend, this all actually isn’t quite true for ES6 modules — but isn’t quite false, either. More on this in a future post.
2. A module is returned by a factory function
A factory function is a bit of code that gets called and returns the value of the module. Usually, this takes the form of a function you supply to the module system that will get called when the value of your module is needed.
That said, it may or may not look like you’re writing a function when you create your module. In AMD, it does — this is the function passed to define— while in node.js, your file (module) is effectively wrapped in a function that returns the module.exports object.
This value, the one returned by the factory function, is the value that users of your module get when they request your module by name from the module system (e.g. in node, this looks like var foo = require('foo-module');).
Each time the module name associated with this module gets requested, the module system is expected to return whatever the value of the module should be by invoking this factory function. Generally this happens once per runtime environment (that is, once per web page load), and the module system caches the value for later use if more things request it.
3. A module is associated with a string name
Every module needs to have a string-valued name, e.g.
Watch out! This is not a filename, though it sometimes looks like one. It’s just an identifier to associate a value with.
Some module loading schemes do apply some level of structure to this — e.g. AMD allows relative pseudo-file-paths (to be explained in a future post, don’t worry).
Modules: putting the pieces together
…and that’s it. All nontrivial browser-side module loading schemes share this definition of a module (but as usual, we’ll see that ES6 modules are the exception), which means the main difference is the syntax for how modules get defined and resolved. This is why the UMD module definition scheme can work — also to be explained shortly.
Recall that a module is not, necessarily, associated with a file on a filesystem or web server. Many module systems do make this association in some way, but it’s not a part of the fundamental concept of a module and it’s important to understand this distinction so that you can understand that one of the important questions about any given module system is how it maps modules to files.
Code module handling is one of those simple-in-theory, fiddly-in-practice concepts, and nowhere is this more true than in the browser, but hopefully this post has given you a compass by which to navigate some of these subtleties.
Cloud Four team members Tyler Sticka, Erik Jung and Lyza Gardner contributed to this post.
Designing sites that are fast and flexible is crucially important as the web world continues to become more mobile. For a designer, making a site fast and lightweight can feel at odds with design goals. How do we find a balance between fast and memorable when establishing the aesthetic direction of a site?
In the early years of the web, there was a lot of experimentation with where to put content on a page. Then we all settled into a handful of patterns that didn’t change for over a decade. It wasn’t until the arrival of responsive design that new ideas for page layout started appearing. Now, with new CSS properties for layout landing in browsers, we’re about to see a renaissance in layout design patterns. Where are we going, and how can we better design for the true medium at hand?
Our schedule follows a single-track format. That means you don’t have to miss a single speaker—you can see them all!
Join us for a spirited, knowledge-packed day scouting the frontiers of responsive web design and development in lovely Portland, Oregon. Responsive Field Day is a welcoming and affordable gathering for web designers and developers.