Wednesday, 12 June 2013

Front-End Ops By Alex Sexton | Spotty Web

When a team builds a complex application, there is often a common breakdown of roles. Specifically on the back end, there are database engineers, application engineers and operations engineers, or something close to this. In recent years, more and more application logic is being deferred to the client side. For some reason, though, operations folks aren’t going with it.
I recently wrote an article on “Deploying JavaScript Applications.” It was largely well received, and I was happy with the content, but one negative comment stuck out to me. I probably didn’t have the reaction that the commenter was intending, but it pointed out something to me nonetheless.
“With all due respect, may I ask if you actually enjoy your job? I am a dev, and I do enjoy using tech to do stuff to a point. If your role is to squeeze every last second of performance out of your app, then yea, all this stuff must be cool. BUT if you are a coder doing something else and then come back to all of this as well, then wow, I don’t know how you haven’t gone mad already. I’d be sick to the stomach if I had to do all of this, in addition to my usual work.”
See, I had written my article with a few too many assumptions. I understood ahead of time that a few of my solutions weren’t globally applicable, and that many people wouldn’t have the time or energy to implement them. What I didn’t fully grasp was how different the role in that article is from the picture that people have of a front-end developer in their head. Up to this point, a front-end developer had just the few operations duties lumped into their role, and even then, many people chose to skip those steps (that’s why Steve Souders is constantly yelling at you to make your pages faster).
I think things are about to shift, and I’d (humbly) like to help guide that shift, because I think it’ll be great for the Web.

The Front-End Operations Engineer

A front-end operations engineer is not a title you’ve likely come across, but hopefully one that you will. Such a person would need to be an expert at serving and hosting front-end resources. They’d need to be pros at Grunt (or something similar) and have strong opinions about modules. They would find the best ways to piece together the parts of a Web application, and they’d be pros at versioning, caching and deployment.
A front-end operations engineer would own external performance. They would be critical of new HTTP requests, and they would constantly be measuring file size and page-load time. They wouldn’t necessarily always worry about the number of times that a loop can run in a second — that’s still an application engineer’s job. They own everything past the functionality. They are the bridge between an application’s intent and an application’s reality.
A front-end operations engineer would be very friendly with the quality assurance team, and they would make sure that “performance” is a test that comes up green. They’d monitor client-side errors and get alerts when things go wrong. They’d make sure that migrations to new versions of the application go smoothly, and they’d keep all external and internal dependencies up to date, secure and stable. They are the gatekeepers of the application.

Why?

We have reached a point where there is enough work to be done in the operations space that it often no longer serves us to have an application engineer do both jobs. When the application’s features are someone’s priorities, and that person has a full plate, they will typically deprioritize the critical steps in delivering their application most successfully to the end users.
Not every company or team can afford this person, but even if someone puts on the “front-end operations” hat for one day a week and prioritizes their work accordingly, users win. It doesn’t matter how many features you have or how sexy your features are if they aren’t delivered to the user quickly, with ease, and then heavily monitored. Front-end operations engineers are the enablers of long-term progress.

Builds And Deployment

If you were to ask most back-end engineers which person on their team has traditionally worried about builds and deployment, I’m sure you’d get a mixed bag. However, a very sizeable chunk of engineers would tell you that they have build engineers or operations engineers who handle these things. In that world, this often entails generating an RPM file, spinning up EC2 instances, running things through continuous integration tools, and switching load balancers over to new machines. Not all of this will necessarily go away for a front-end operations engineer, but there will be new tools as well.
A front-end operations engineer will be a master of the build tool chain. They’ll help run and set up the continuous integration (or similar) server but, more specifically, they’ll set up the testing instancesthat their application runs on and then, eventually, the deployment instances. They’ll integrate Git post-commit hooks into the application and run the tests (either in Node.js and PhantomJS or against something like Sauce Labs, Testling or BrowserStack) before anything gets merged into the master. They’ll need to make sure that those servers can take the raw code and, with a few commands, build up the resulting application.
This is where many people use Grunt these days. With a quick grunt build, these machines could be serving the built version of an application in order to enable proper testing environments. The front-end operations engineer would be in charge of much that’s behind that command as well. grunt buildcould call out to RequireJS’ r.js build tool, or a Browserify process, or it could simply minify and concatenate a list of files in order. It would also do similar things to the CSS (or your favorite preprocessed CSS dialect), in addition to crushing images, building sprites and reducing requests in any other way necessary or possible.
Front-end operations engineers would make sure that all of this stuff works on people’s local machines. A quick grunt test should be able to build everything locally, serve it and test it (likely with some WebDriver API-compatible server). They’d make sure that team members have the power to push their applications into the continuous integration environment and test them there. And they’d remove single points of failure from deployment (GitHub being down during launch wouldn’t scare them).
They’d facilitate internal deployments of feature branches and future release branches. They’d make sure that the quality assurance team has an easy time of testing anything and that the managers have an easy time of demoing things that aren’t ready.
They’d help build multiple versions of an application to best suit each of their core sets of users. This could mean builds for mobile or for old versions of Internet Explorer, but all of it should be relatively transparent to those who are programming against those feature, browser or device tests.
They’d facilitate the process of taking a release, building it, uploading it to a static edge-cached content delivery network, and flipping the switch to make it live. And they’d have a documented and fast roll-back mechanism in place.
Perhaps most importantly, they’d automate everything.
front-end ops start image_mini
(Image credits: Rube Goldberg)

Tracking Speed

The metric by which a front-end operations engineer would be judged is speed: the speed of the application, the speed of the tests, of the builds and deployment, and the speed at which other teammates understand the operational process.
A front-end operations engineer would live in a dashboard that feeds them data. Data is king when it comes to speed. This dashboard would integrate as much of it as possible. Most importantly, it would constantly be running the team’s app in multiple browsers and tracking all important metrics of speed. This space currently doesn’t have a ton of options, so they’d likely set up a private cloud of WebPageTest instances. They’d put them in multiple zones around the world and just run them non-stop.
They’d run against production servers and new commits and pull requests and anything they can get their hands on. At any given point, they’d be able to tell when, where, and what the surrounding circumstances were behind a slow-down. A decrease in speed would be directly correlated to some change, whether a new server, a diff of code, a dependency or third-party outage, or something similar.
They’d have a chart that graphs the number of HTTP requests on load. They’d also have a chart that tells them the Gzip’ed and minified payload of JavaScript, CSS and images that are delivered on load. And they’d also go crazy and have the unGzip’ed payload of JavaScript so that they can measure the effect of code parsing, because they know how important it can be on mobile. They’d instrument tools like mod_pagespeed and nginx_pagespeed to catch any mistakes that fall through the cracks.
They’d be masters of the latest development and measurement tools. They’d read flame graphs and heap snapshots of their apps from their development tools (in each browser that has them). They’d measure frames per second on scrolling and animations, prevent layout thrashing, build memory profiles, and keep a constant eye on compositing, rendering and the overall visual performance of the application. They’d do all of this for desktop and mobile devices, and they’d track trends in all of these areas.
They’d religiously parallelize tasks. They’d track the application via waterfalls and .har data to make sure that all serial operations are necessary or intentional.
They’d chart the average run time of the tests, builds and deploys. And they’d fight to keep them low. They’d chart their external dependencies in size and speed. They may not have control over slow API requests, but they’d want to be able to point to the reasons why their numbers are increasing.
They’d set an alarm if any of these numbers rose above an acceptable limit.

Monitoring Errors And Logs

Managing logging is a critical job of a normal operations engineer. The data that is generated from running an application is vital to understanding where things go wrong in the real world. A front-end operations engineer would also instrument tools and code that allow the same level of introspection on the client side.
This would often manifest itself as an analytics tool. Application engineers would be encouraged to log important events and any errors at certain levels to a logging service. These would be appropriately filtered and batched on the client and sent back as events to an internal or external analytics-style provider. The engineer would have enough information to identify the circumstances, such as browser name and version, application deployment version, screen size and perhaps a bit of other data. (Though they’d want to avoid storing personally identifiable information here.)
Logging stack traces can be very helpful in browsers that support them. You can integrate third-party services that do this for you.
The front-end operations engineer would encourage a very small tolerance for errors. Any error that happened would be investigated and either fixed or logged differently. With the data that comes back, they should be able to visualize groups of errors by browser or by state information from the application. A threshold of errors would be allowed to occur, and when that is passed, engineers would be notified. Severities would be assigned, and people would be responsible for getting patches out or rolling back as necessary (with quick patches being heavily favored to roll backs).
Much like today’s operations people focus on the security of the systems they manage, a front-end operations engineer would have probes for XSS vulnerabilities and would constantly be looking for holes in the app (along with the quality assurance team).
A front-end operations engineer would have an up-to-date picture of the state of the application in production. This is challenging in the front-end world, because your application doesn’t run on your machines — but that makes it even more necessary.

Keeping Things Fresh and Stable

My favorite thing that good operations people who I’ve worked with in the past were really good at was keeping things up to date. For some applications, stability and security are so deeply necessary that caution is the larger priority; but in most cases, failure to keep dependencies and environments up to date is what causes applications to get stale over time. We’ve all worked on a project that’s four years old where all of the tools are very old versions of the ones we know, and getting good performance out of it is impossible.
A front-end operations engineer would be effective at keeping dependencies up to date and at removing cruft in systems. When the next version of jQuery is released, they’d use their skills to switch out the dependency in the application to work with the new version and then test it to validate the change. They’d keep Grunt up to date (and Node.js along with it). When WebP becomes viable, they’d automate moving the application’s images over to that format.
They’d work closely with the more architecture-oriented application engineers to make sure that the entire system still feels viable and is not lagging behind in any one area. They would keep on top of this stuff as often as possible. Updating a dependency here and there as you build is far easier than having a big “Update Everything” day. It encourages application developers to loosely couple dependencies and to build good, consistent interfaces for their own modules.
A front-end operations engineer makes it viable and fun to work on a project long after it’s new.

The Future

I’m sure plenty of commenters will tell me that these tasks have been going on for years, and plenty will tell me that they should be the concern of all developers on a team. I would agree with both statements. I am not introducing new concepts; I’m compiling tasks we’ve all been doing for years and giving them a name. I think this will help us build better tools and document better processes in the future.
The addition of this role to a team doesn’t absolve the other members of performance responsibilities. It’s just that right now, front-end operations are no one’s explicit priority on most of the teams that I’ve encountered, and because of that, they often get skipped in crunch time. I think there’s enough to be done, especially in the configuration and monitoring of these tools, outside of the normal job of a front-end engineer, to justify this role.
Most importantly, regardless of whether a new job comes from these tasks, or whether we solve the problem in a different way, we do all need to be conscious of the importance of solving these problems in some way. You simply can’t ignore them and still achieve reliable, robust, high-experience applications. Addressing these concerns is critical to the stability and longevity of our applications and to the happiness of programmers and users.
If we build with that in mind, it helps the Web win, and we all want the Web to win.

Monday, 27 May 2013

NEW DEFAULTS IN WEB DESIGN "How Much Has The Web Really Changed?" By Vasilis van Gemert

Responsive design is about more than just layout; it’s about designing for the Web, which means, mostly, for people with browsers. And that’s just about everything we know about the people who visit our websites: they are probablyusing a browser. All the rest we just don’t know.
Up until not so long ago, we used to base our designs on some rather general assumptions about screen size and input type. With the rise of devices with various screen sizes and alternative ways to interact, these assumptions have turned out to be unreliable. We need to upgrade the defaults that we use when we start designing our websites.

People keep saying that the Web has changed. But has it really? Let’s take a look at all of the things that have actually changed.A Closer Look

SCREEN SIZES

In the 1990s, the Web was 640 pixels wide. In the early 2000s, it grew to 800 pixels. A few years later, we decided it should be 1024 pixels. But five years ago, all of a sudden, something strange happened. A device with a very small screen entered the market. Suddenly, our ideas about the size of the Web did not work anymore. Later on, tablets entered the market. People hold these things however they want. Today, the height of the viewport could be bigger than the width! But is that new? Not really.
Screen sizes, shown in a non-flexible medium. Photo and work by Aram Bartholl.
Screen sizes, shown in a non-flexible medium. (Photo and work: Aram Bartholl)
We never really knew what size the window of our visitors would be. We just assumed it was at leastthe random pixel width that we felt comfortable with. These numbers were always arbitrary, and there were always people who could not see the entire website. We simply ignored them.

“EVERYONE HAS A MOUSE”

We’ve always assumed that everyone uses a mouse. Even though we knew that this was not always true, most designs completely ignored alternative ways of interacting. People who had to use a keyboard, for whatever reason, had a very hard time interacting with our websites.
But because most people did use a mouse, and because back then many designers thought that designing only for the majority was OK, we created websites that were unusable for a lot of people. And this turned out to be a growing number. Many mouseover interactions are completely dysfunctional on a touch device. Because people love these devices, and even managers and designers use them, they are harder to ignore.

“EVERYONE HAS BROADBAND INTERNET”

Another thing we always assumed was that everyone had a super-fast Internet connection, at least as fast as our own. And if they didn’t already have it, they’d have it soon. This was again mostly true; speeds were increasing. But today, more and more people use crappy, unreliable 3G connections all the time. If you’ve ever travelled on a train in The Netherlands, you know what I mean. And if you’ve ever had to rely on the mythical “free hotel Wi-Fi,” then you know for sure that the assumption about the ever-increasing speed of our Internet connections is just not true. This is a big change in our thinking; we really should consider these users. This will have a major impact on what our designs look like.

“EVERYONE’S COMPUTER GETS FASTER EVERY YEAR”

It used to be true that computers would get faster and faster. If you waited half a year before buying a computer, you would get one that was twice as fast, for the same price. This was true of new desktop computers, but mobile devices have priorities other than processor speed. The most important thing for a phone, for instance, is battery life: you really don’t want to have to charge it after every phone call.
And there’s another trend: instead of creating ever-faster devices, many manufacturers are starting to sell ever-cheaper devices. Many people care about price and battery life more than about processor speed. This is also not new: what happened to your old computers? You probably sold them or gave them away. People keep using old stuff. Not everyone has the same hardware as we designers do.

“ALL MONITORS ARE CALIBRATED”

Well, we always knew this to be untrue, right? Only the monitors of visual professionals are calibrated. Most other monitors don’t display colors accurately, and many monitors are downright crappy. Most mobile phones that I’ve tested have pretty decent screens, until you start using them outside, in the sunshine. If you’re lucky, you can read the content, but you definitely cannot see the subtle gradients in low-contrast designs.
I haven’t even mentioned “modern” black and white screens. These, too, are not new. People have always used crappy monitors, and people with bad eyesight have always visited your websites. It’s just that more and more people are seeing a subpar color palette. Instead of buying a state of the art monitor, buying a cheap monitor and several low-end devices to test your work on might be a better investment.
All of these things are not new. In 2002, John Allsopp wrote the monumental article “A Dao of Web Design.” People such as Jeremy Keith and Roger Johansson have written about all of these facts for years and years. And yet, somehow, we’ve always managed to actively ignore them. But we really can’t anymore. The Web actually did change in the last five years, with new devices, new browsers and many, many cool new features. We need new defaults. The old ways of creating websites just don’t work anymore.
This Is Responsive, the excellent resource about responsive design by Brad Frost.
This Is Responsive, the excellent resource about responsive design by Brad Frost.
In the past few years, we’ve been actively researching new ways to deal with all of these different screen sizes. But apart from responsive design, there are many more challenges in today’s ever-growing pile of devices. We have to find new patterns of interaction: we need interfaces that work on any device. Maybe we have to reconsider that enormous photo carousel on the home page, now that we know that not everyone has a cheap and fast connection. New defaults are emerging, and I’ve collected a few for you here.
The things in this article are not new. Many clever people have written about them in many articles and many books. But these ideas, like all good stories, have to be repeated many times so that people understand and remember them.

New Default: Activate

I initially titled this section “New Default: Touch.” But I came to realize that “touch” has a different meaning for everyone. Some people, like me, think of a single tap when we hear the word. Others think about swiping and complex gestures. That’s why I settled on the heading “New Defaults: Activate.” All devices, no matter what kind of input they offer, let the user activate something in some way.
With a mouse, it’s a click; with a touch device, it’s a tap; on a keyboard, it’s the “Enter” key. There are ways to activate things by voice, and by waving your arms in the air. And many devices offer more than one way to interact. The only thing that all of these devices have in common is the action of activating. Most of them are capable of doing many other things, too, but all of them can activate stuff.
Only recently have we really started thinking about alternative methods of user input. We used to assume that everyone uses a mouse. Hiding content and showing it on mouseover was considered to be a decent design pattern. And it used to work for most people — until all of these wonderful touch devices entered the market. What should a device without a mouse do when content can be revealed only with a mouse? Different devices have different solutions. Let’s look at a simple drop-down menu.
When you hover over a menu item, a submenu appears. But apart from hovering over an item, you can also simply click on it to follow the link. Now, what should happen when you tap on the item with a touch device? Should the submenus appear, or should the link activate? Or both? Or should something else happen? On iOS, something else happens. The first time you tap a link like that, the submenu appears; in other words, the hover event fires. You have to tap a second time to actually follow the link. This is confusing, and not many people will tap a second time. On Android, the submenu appears and the link is followed simultaneously. I don’t have to explain to you that this is confusing.
It’s very well possible to think of complex solutions whereby you define different interactions for different input devices. But the better solution, I think, is to make sure that the default interaction, the activate event, just works for everybody. If you really need to, you could choose to enhance this default experience for certain users.
For instance, if you are certain that someone is using a mouse, you could enable some mouseover interactions. Or if you’re sure that someone has fat fingers, you could make small buttons a bit bigger. But only do so in addition to the default activate interaction, and only if there’s no doubt about it, and only if the enhancement would really make things better. Those are quite a few ifs, and some of them, such as the mouse usage, are very hard to detect — especially on devices that offer more than one way to interact, such as a laptop with an optional mouse, touch pad, camera, microphone, keyboard and touchscreen. Give it some serious thought. Do you really need to optimize for a mouse?

New Default: Small Screens

Growing is easy. Most things grow. Babies grow, trees grow, curious minds grow. They don’t grow by themselves, but you don’t need much energy to make things bigger. This is just what things do when they live. While shrinking things is definitely possible, it’s also much harder. You could, for instance, compress a car to a fraction of its original size. A compressed car does have a certain aesthetic appeal to it, but it is definitely not as useful as it was before. The same goes for websites. Shrinking a desktop website does not always result in a pleasant experience on a small screen.
Trees grow on their own, cars are less usefull when they shrink.
Cedro di Versailles by Italian artist Giuseppe Penone clearly shows that things grow. On the other hand, the workPapalote Goliad by American artist John Chamberlain shows that shrinking can be aesthetically appealing but may result in less useful results.
To build a responsive website that works on all kinds of screens, designing for a small screen first is easiest. It forces you to focus on what’s really important: if it doesn’t fit in this small square, it is probably not terribly important. It forces you to think better about hierarchy, about the right order of components on the page.
The same principle that we follow for interactions — whereby we design the activate event first and enhance it later — applies to graphic design. We should start designing the things that we knoweveryone will see. That’s the content. No matter how big or small a screen is and no matter how minimal the feature set of a browser, it will be able to show letters. Because this is about the only thing we know for certain — since color is absent on most Kindles, most of the latest CSS doesn’t work on old browsers, and layout is of minor importance on small screens — starting with the text is logical.
I wrote an in-depth article about defining breakpoints on the basis of typography, so I won’t repeat every detail here. But the basic idea is that you start by designing the relationship between the different font sizes. Almost everyone, no matter what device they have, will be able to see this. When the typography is done, you would start designing the layout for bigger screens; you can think of this as an enhancement for people with bigger screens. And after that, when the different layouts are done, you could add the paint. And by paint, I mean color, gradients, borders, etc.
I’ve presented this as a very strict way of working; in real life, of course, things are not as rigid. I’m not talking about “activate only” or “small screen only.” When I say to start with typography, I don’t mean that you aren’t allowed to think about paint at the same time. Rather, I’m trying to find the things that all of these different devices, with all of their different screen sizes and all of their different features, have in common. It just seems logical to first design this shared core thoroughly. The strange thing is that this core is often overlooked: Web professionals tend to view their own creations with top-of-the-line devices with up-to-date browsers. They see only the enhancements. The shared core with the basic experience is often invisible.

New Default: Content

The way we designed our websites until recently was by putting a header with the logo and navigation at the top, putting the subnavigation on the left, putting some widgets on the right, and putting the footer at the bottom. When all of that was done, we’d cram the content into the little space that was left in the middle. All of the things we created first — the navigation, the widgets, the footer — they all helped the visitor to leave the page. But the visitor probably wanted to be there! That was weird. It was as if we were not so confident in our own content and tried our best to come up with something else that our guests might like.
But rather than pollute the page with all kinds of links to get people out of there, we should really focus on that thing in the middle. Make sure it works. Make sure it looks good. Make sure it’s readable. Make sure people will understand it and find it useful. Perhaps even delight them with it!
Once you’re done with the content, you can start to ask yourself whether this content needs a header. Or a logo. Or subnavigation. Does it need navigation at all? And does it really need all of those widgets? The answer to that last question is “No.” I’ve never understood what those widgets are for. I have never seen a useful widget. I have never seen a widget that’s better than white space.
A typical news site with more attention for widgets versus the complete focus on the content on Medium.
Compare a typical news website’s attention to widgets with Medium’s complete focus on content.
By starting with the content first, you can come up with some very interesting solutions. For instance, does the logo really need to be at the top of every page? It could very well go in the footer on many websites; such as in digital style guides or on pages for registered users. Many links that we used to put in the subnavigation might work better in relevant spots in the main content.
For instance, the option to add extra luggage to a flight booking might be most effective right there in the overview of the flight, instead of in the middle of a list of links somewhere on the left of the page. And when looking at the hierarchy of a page, does the main navigation look more important than the main content? Most of the time it shouldn’t be, and I usually consider the navigation to be footer content. A simple “skip” link at the top of the page could either take the visitor to the navigation or fetch the navigation and show it at the top of the page.
In this era of responsive Web design, we need many new clever solutions. As we’ve seen here, our old defaults don’t work anymore. We need to reconsider how we work with interaction, how we approach design and how we shape our content. But we need to think about one other very important thing, and that is where our content comes from.

New Default: The API

Luke Wroblewski wrote a fantastic article about designing an application for the command line first, and then enhancing it for different needs. This is not just a nerdy idea, but a very practical idea, too. If you are able to design and develop your own application, you could test the functionality relatively easily before even starting to think about what it will look like on different devices. This requires designers to work with developers to design a feature that at first works only from the command line. If the feature does not work as expected, then you merely have to change the API, rather than also a bunch of visual designs. Once the API works as you want it to, enhancing it for all of the devices and screen sizes that you want to support becomes easier.
Most of the time, you wouldn’t design the entire API of the application that you’re building. Most companies would choose a content management system (CMS) of sorts or a specialized tool to help them achieve what they want to do. I’ve always been amazed that CMSes are so often chosen onlyby technical people and business people. This causes many problems during the design process.
Developers and business people have different goals than designers. Developers want stuff that is easy to develop on. Business people want stuff that’s cheap. But designers want to make the best and most beautiful things possible. These goals can easily conflict.
I’m not saying that designers alone should choose the system, but they should definitely be a part of the decision-making process. I’m convinced that the selection of CMSes will improve. And I’m convinced that CMS makers will start to improve their products once designers get involved. Right now, all CMSes I know of deliver hostile cruft unless you tweak them extensively.
But it works the other way around, too. If designers are involved in the selection process, they will have a say in the choice of tool and will understand how it works, what’s possible, what’s easy and what’s hard. This will result in designs that are based in part on the tool, not just on imagination. This is an important part of the design process that has not yet been optimized. Right now, the command line and the systems that deliver the content we design for are the domain of the developers, and designers have nothing to do with them. That is a pity. Just as you would want to take advantage of the knowledge of developers in the design process, you would want to take advantage of the knowledge of designers in the development process.

Progressive Enhancement

If you review the sections above, you’ll see that what I’ve described is nothing other than progressive enhancement. You start with the content, then design the content and optimize it for different screen sizes and devices, and after that you can further optimize for very specific features such as mouse usage and fat fingers. Many Web developers build websites according to this principle. They transform the beautiful Photoshop documents that they receive into all of the different layers described above.
This can work out fine if the developer has a good sense of design and a delicate attention to detail. But if they don’t — which is often the case — this can easily result in crappy usability and ugly details. I’m not saying that designers shouldn’t use Photoshop anymore. If that’s your tool, go ahead and use it. But do remember that you’re designing the layers of the Web, not the layers in Photoshop. There’s much more to the Web than a single beautiful image. People will see our creations ininnumerable ways. We design for all of these people — remember that. We don’t just design for the CEO with a laptop. We also design for the people on the train and the people with “free hotel Wi-Fi.”

TOOLS

I’ve mentioned Photoshop a few times because it’s still widely misused for designing websites. One reason we have a hard time with progressive enhancement in the design process is due to a lack of good Web design tools. The tools we use are built to wow; they mostly help you to create the “paint,” not to design the core. Fortunately, more tools are popping up with very specific functions in the design process. These are micro-tools such as the International Measure Slider, which helps you to define breakpoints in your grid; tools such as Gridset, which helps you to create grids for different screen sizes; and excellent tools that help you to define typography. By incorporating these tools into our design workflow, we might start making better stuff.

Conclusion

The Web has always been a weird, borderless, flexible medium. In the last couple of years, we’ve started to realize that designing for this medium is fundamentally different from the design work we’ve done previously. The fixed dimensions and the singular ways of interacting that formed the basis of all types of media that we’ve worked with for centuries just don’t work on the Web. This truly is a unique medium.
We have to find new defaults, new starting points for our design process. I’ve explained some of these new defaults here, but of course there are many more. The way we work with forms, for instance, could probably use a whole series of articles by itself. Some new starting points are well established by now, but I’m sure many more will be invented in the near future. I am curious to hear about new patterns and new defaults that you have discovered and have used successfully in your projects.

Monday, 6 May 2013

Building A Relationship Between CSS & JavaScript By Tim Wright


jQuery, Prototype, Node.js, Backbone.js, Mustache and thousands of JavaScript microlibraries all combine into a single undeniable fact: JavaScript is popular. It’s so popular, in fact, that we often find ourselves using it in places where another solution might be better in the long run.
Even though we keep JavaScript, CSS and HTML in different files, the concepts behind progressive enhancement are getting all knotted up with every jQuery plugin we use and with every weird technique that crops up. Because JavaScript is so powerful, there are a lot of overlaps in capability between JavaScript and HTML (building document structure) and JavaScript and CSS (injecting style information). I’m not here to pick on any JavaScript library, bootstrap or boilerplate; I’m just here to offer a little perspective as to where we are and how we can realign our goals.
Relationship Image
Image Credit: opensourceway.
Keeping CSS Out Of Your JavaScript
CSS can hook into HTML with a variety of different selectors; this isn’t anything new. By using IDs, classes or any attribute you can think of (even custom attributes), you have easy access to style an element. You can also do this with a slew of JavaScript methods, and honestly, it’s the same basic process with a different syntax (one of my JavaScript ah-ha moments). Being able to natively access HTML from JavaScript and from CSS is one of the reasons progressive enhancement has been such a successful development model. It allows a point of reference to guide us and to serve as a reminder as we develop a project, so we don’t “cross the streams”.
But, as you move forward with JavaScript and build applications with highly interactive elements, it gets harder to not only keep HTML out of your JavaScript, but also to catch yourself before injecting style information into a document. Of course, the case for not injecting style with JavaScript certainly isn’t a binary one (yes/no, true/false, 0/1); there are plenty of cases where you might need to apply styles progressively, for example, in a drag and drop interface where positioning information needs to be constantly updated based on cursor (or finger) position.
But generally speaking, you can safely house all the style information you need within CSS and reference styles as reusable classes. This is a much more flexible model than sprinkling CSS throughout a JavaScript file, and it very closely compares to the model of adding style information into your HTML. We follow this model when it’s only HTML and CSS, but for some reason it has a tendency to fall apart once JavaScript gets added into the mix. It’s certainly something we need to keep an eye on.
A lot of front-end developers take real pride in having clean HTML. It’s easy to work with, and to certain super-geeks it can even be artful. It’s great to have clean, static HTML, but what good is that if your generated HTML is riddled with injected style and non-semantic markup? By “generated HTML,” I’m referencing how the HTML looks after it’s been consumed and barfed back up after being passed around all those plugins and extra JavaScript. If step one to having clean HTML and separated progressive enhancement layers is to not use a style attribute, I’d have to say that step two is to avoid writing JavaScript that injects a style attribute for you.

CLEANING UP YOUR HTML

We can probably all agree that blindly using a technology is a terrible idea, and I think we’re at a point with jQuery where we are, indeed, blindly using a lot of the features without fully understanding what’s going on under the hood. The example I lean on pretty heavily for keeping CSS out of my JavaScript is the behavior of jQuery’s hide() method. Based on the principles of progressive enhancement, you wouldn’t code something with inline CSS like this:
<div class="content-area" style="display:none;"></div>
We don’t do that because a screen reader won’t pick up an element if the style is set to display:none, and it also muddies up the HTML with unnecessary presentational information. When you use a jQuery method like hide(), that’s exactly what it does: it will set a style attribute on the target area and add a display property of none. It’s very easy to implement, but not very good for accessibility. It also violates the principles of progressive enhancement when you inject style into the document like that (we’re all sorts of messed up, huh?). It’s not uncommon for this method to be used within a tabbing interface to hide content. The result is that the content is nonexistent to a screen reader. Once we realize that adding style from JavaScript isn’t ideal in most cases, we can move it into the CSS and reference it as a class:
CSS
.hide {
   display: none;
}
jQuery
$('.content-area').addClass('hide');
We still have to address the accessibility problem of hiding content with display:none, but since we’re not using a built-in jQuery method anymore, we can control exactly how content gets hidden (whichever accessible method you prefer is probably fine). For example we could do something like:
CSS
.hide {
   position: absolute;
   top: -9999px;
   left: -9999px;
}

.remove {
   display: none;
}
In the above example, you can see that even though both classes result in content being removed from view, they function very differently from an accessibility standpoint. Looking at the code like this makes it clear that we really are dealing with style information that belongs in a CSS file. Using utility classes in this way can not only help your JavaScript slim down, but also have double usage in an Object Oriented CSS (OOCSS) development model. This is truly a way to not repeat yourself(Don’t Repeat Yourself, or DRY) within CSS, but also across a whole project, creating a more holistic approach to front-end development. Personally, I see a lot of benefit in controlling your behaviors this way, but some people have also called me a control-freak in the past.

WEB AND TEAM ENVIRONMENTS

This is a way we can start opening up lines of communication between CSS and JavaScript and lean on the strengths of each language without overdoing it. Creating a developmental balance on the front end is very important, because the environment is so fragile and we can’t control it like we can on the back end with a server. If a user’s browser is old and slow, most of the time you can’t sit down and upgrade it (aside: I do have my grandmother using Chrome); all you can do is embrace the environmental chaos, build for the best and plan for the worst.
Some people have argued with me in the past that this style of development, where you’re referencing CSS classes in JavaScript, doesn’t work well in team development environments because the CSS is usually built by the time you’re diving into the JavaScript, which can cause these classes to get lost in the mix and create a lot of inconsistency in the code (the opposite of DRY). To those people I say: poke your head over the cube wall, open AIM, GTalk or Skype, and communicate to the rest of the team that these classes exist specifically to be used with JavaScript. I know the concept of developers communicating outside of GIT commit messages seems like madness, but it’ll be okay, I promise.

Using Behavioral CSS With JavaScript Fallbacks

Using these CSS objects as hooks for JavaScript can go far beyond simple hiding and showing of content into an area of behavioral CSS, transitions, animations and transforms that are often done with JavaScript animations. With that in mind, lets take a look at a common interaction model of fading out a div on click, and see how it would be set up with this development model, while providing the proper fallbacks for browsers that might not support the CSS transition we’re going to use.
For this example we’ll be using:
First, let’s set up our body element:
<body>
    <button type="button">Run Transition</button>
    <div id="cube"></div><!--/#cube-->
</body>
From there we’ll need to set up the CSS:
#cube {
   height: 200px;
   width: 200px;
   background: orange;
   -webkit-transition: opacity linear .5s;
      -moz-transition: opacity linear .5s;
        -o-transition: opacity linear .5s;
           transition: opacity linear .5s;
}

.fade-out {
   opacity: 0;
}
Before we add on the JavaScript layer, lets take a moment and talk about the flow of what’s going to happen:
  1. Use Modernizr to check for CSS Transition support
  2. If Yes
    1. Set up a click event on the button to add a “fade-out” class to #cube
    2. Add another event listener to catch when the transition is finished so we can time the execution of a function that will remove #cube from the DOM.
  3. If No
    1. Set up a click even on the button to use jQuery’s animate() method to manually fade#cube out.
    2. Execute a callback function to remove #cube from the DOM.
This process will introduce a new event called transitionend, which will execute at the end of a CSS transition. It’s amazing, FYI. There is also a companion event called animationend, which will execute at the end of a CSS animation for more complex interactions.
First thing we need to do is set up our variables in the JavaScript:
(function () {

   // set up your variables
   var elem = document.getElementById('cube'),
       button = document.getElementById('do-it'),
       transitionTimingFunction = 'linear',
       transitionDuration = 500,
       transitionend;

   // set up the syntax of the transitionend event with proper vendor prefixes
   if ($.browser.webkit) {
       transitionend = 'webkitTransitionEnd'; // safari & chrome
   } else if ($.browser.mozilla) {
       transitionend = 'transitionend'; // firefox
   } else if ($.browser.opera) {
       transitionend = 'oTransitionEnd'; // opera
   } else {
       transitionend = 'transitionend'; // best guess at the default?
   }

   //... rest of the code goes here.

})(); // end wrapping function
You might notice that our new transitionend event needs a vendor prefix; we’re doing a little browser detection to take care of that. Normally you might detect for the vendor prefix and add it onto the event name, but in this instance the cases for the syntaxes are a little different, so we need to get the whole name of the event for each prefix.
In the next step we’ll use Modernizr to detect support, and add our event listeners to each case (all of this stuff gets added inside the wrapping function):
// detect for css transition support with Modernizr
if(Modernizr.csstransitions) {

    // add our class on click
    $(button).on('click', function () {
       $(elem).addClass('fade-out');
    });
    
    // simulate a callback function with an event listener
    elem.addEventListener(transitionend, function () {
       theCallbackFunction(elem);
    }, false);
       
} else {

   // set up a normal click/animate listener for unsupported browsers
   $(button).on('click', function () {

       $(elem).animate({
           'opacity' : '0'
       }, transitionDuration, transitionTimingFunction, function () {
           theCallbackFunction(elem);
       });

   }); // end click event

} // end support check
Finally, we need to define a shared function between the two actions (DRY) which executes after the transition (or animation) is complete. For the sake of this demonstration we can just call ittheCallbackFunction() (even though it’s not technically a callback function). It will remove an element from the DOM and spit out a message in the console letting us know that it worked.
// define your callback function, what happens after the transition/animation
function theCallbackFunction (elem) {

   'use strict';

   // remove the element from the DOM
   $(elem).remove();

   // log out that the transition is done
   console.log('the transition is complete');

}
In the browser, this should work the same way in IE 7 (on the low end) as it does in mobile Safari or Chrome for Mobile (on the high end). The only difference is under the hood; the experience never changes for the user. This is a way you can use cutting-edge techniques without sacrificing the degraded user experience. It also keeps CSS out of your JavaScript, which was really our goal the whole time.

The Moral Of The Story

You might be asking yourself why we should even bother going through all this work. We wrote about 60 lines of JavaScript to accomplish the same design aesthetic that could be created with eight lines of jQuery. Well, no one ever said that keeping clean code and sticking to progressive enhancement was the easiest thing to do. In fact, it’s a lot easier to ignore it entirely. But as responsible developers, it’s our duty to build applications in a way that is accessible and easily scales to the future. If you want to go that extra mile and create a seamless user experience as I do, then it’s well worth the extra time it takes to dot all the i’s and cross all the t’s in a project to create an overall experience that will gracefully degrade and progressively enhance.
Using this model also lets us lean heavily on CSS for its strengths, like responsive design and using breakpoints to redefine your interaction at the various screen sizes. It also helps if you’re specifically targeting a device with a constrained bandwidth, because, as we all know, CSS is much lighter than JavaScript in both download and execution time. Being able to offload some of the weight JavaScript carries onto CSS is a great benefit.
In production, we are currently using CSS animations and transitions for micro interactions like hover effects and maybe a spinning graphic or a pulsating knot. We’ve come to a point where CSS is a pretty powerful language that performs very well in the browser and it’s okay to use it more heavily for those macro interactions that are typically built using JavaScript. If you’re looking for a lightweight and consistent experience that’s relatively easy to maintain while allowing you to use the latest and greatest browser features — it’s probably time to start mending fences and build strength back into the relationship between CSS and JavaScript. As a great man once said, “The key to writing great JavaScript is knowing when to use CSS instead.” (It was me… I said that.)
(cp)