Designers wanted

Safari Flow marked a big turning point in our product roadmap, and among all the forward-thinking attributes on display when you sign in to Flow, the design of the app is front and center. Our customers have been raving about the clean, elegant, and intuitive user interface, and the unobtrusive and simple reading environment. With Flow now out in the world, we’re looking ahead to crafting additional products in 2014 (as well as refining our existing ones), and we’re hiring designers to help us move forward.

Continue reading

Responsive First Aid

At the Ampersand conference, Nick Sherman talked about responsive typography — where typographic displays change to respond to the viewing conditions — and how we can use face detection in the browser to serve up the right size type for a reader. He showed us a nifty responsive-typography-via-face-detection demo, and he demoed his size calculator, which allows us to serve up an appropriate type size based on viewing distance.

Continue reading

&nd then what happened?

These days, being a font geek is the hip, happening thing to do. Everyone seems to have a favorite font typeface, and everyone seems to hate Comic Sans. The ability to install hundreds — if not thousands — of fonts on your computer makes playing with typefaces accessible to anyone. Then there are type geeks, who are also often typographers by trade (because let’s face it — if you’re this obsessive about type, you might as well make it your main occupation in life). Typographers rarely have one favorite typeface, although they can usually expound at length on the superiority of Helvetica over Arial. Instead, different typefaces are designed to do some kinds of work better than others; they also evoke different feelings and connotations. Type is a tool for design, and it’s a really, really powerful one at that.

Sadly, up until recently, the world of type design and the web were frustratingly separate — there just wasn’t support for using most fonts on the web, let alone fine typography. Designers were limited to a handful of web-safe fonts which, while mostly worthy workhorses (except for Arial. Let’s never use Arial again, m’kay?), dramatically limited the degree of typographic expressiveness one could achieve when designing for the web. These days, the advent of online font services such as Typekit and Google Fonts has completely changed the landscape, and web designers have (re)discovered type. For those of us who were trained as print designers, it’s like coming home, a bit.

That’s why I was incredibly excited to attend the Ampersand Conference last week. It was held at the Times Center, which is a very nice space in which to have a conference. Despite (or perhaps because of) it being a one-track, single-day event, the Ampersand schedule was packed with interesting-sounding talks. Usually, despite interesting-sounding topics, you expect most of the day to be full or decent, but unremarkable talks, and to have one or two highlights that really blow everyone away. Well, I’m happy to report that Ampersand exceeded those expectations. Each and every talk was interesting and engaging in its own way (from super cool proofs-of-concept work to wacky and offbeat personal/professional narratives) and there was a distinct earnestness about all the talks, which is reminiscent of some of the things I’ve heard about the xoxo conference. Some highlights:

Type as Brand, Brand as Type by Michael Johnson

Michael Johnson of Johnson Banks opened the conference with a rumination on the growing role of type as a key component of identity design work on the web. Johnson’s presentation did great double duty: it chronicles the progression of the state of the art in web typography from its meager beginnings to the recent flourishing of typographic expression online, while highlighting the absolutely critical role that typography has in developing the visual aspects of a brand identity. He’s been kind enough to post a transcript of his talk here — it’s well worth a read.

Putting the Fonts into Webfonts by Jonathan Hoefler

We’ve been using web fonts at Safari, most notably on Safari Flow, so we’re pretty familiar with the offerings from Google and Adobe. But Jonathan Hoefler’s presentation of Hoefler & Frere-Jones’ new web fonts service, Cloud.typography left a lot of us kind of in awe. His talk was impressive both because of the service’s rich typographical features, and because Hoefler managed to make what could have otherwise been a pretty dry product pitch into a deeply engaging survey of the state of the art in web typography. He’s doing it again this week, at the NY chapter of AIGA.

The Future of Responsive Typography by Nick Sherman

Nick Sherman has been writing really insightful things about typography on the screen and how it relates to readers’ eyes in the physical world. His talk on responsive type fed off of this theme, from the trials and tribulations of font hinting, to the vagaries of compensating for size and resolution-related issues when designing and displaying typefaces on screens.

Jen Lukas: On Icon Fonts & Working with Designers

Jenn Lukas walked a roomful of designers and typographers through what collaborating with developers looks like from the dev’s point of view, highlighting some crucial best practices along the way, with a major detour through a survey of her experience when researching icon fonts. Her liberal and wry use of animated gifs and cat macros (not to mention a radical sandwich metaphor throughout her slide deck) ensured that no one succumbed to the dreaded mid-afternoon slump.

In all, a great way to spend a Saturday (If you’re a type geek, that is. If not, YMM definitely V).

Continuing on Continuous Integration

Where We Were

Last June I wrote about our Continuous Integration setup. We’ve continued using this system and have made some enhancements in the past few months that make it even better.

In our first system of CI, we wanted everything in version control, everything tested, and nothing knifed manually into production. When we first designed this system, we were only thinking about our cookbooks. To get our version 1.0 off the ground, we stuck with just cookbooks and ignored following these rules for nodes, databags, and roles.

Same Goals, Better Implementation

  • Berkshelf
  • Test Kitchen
  • LXCs
  • Chef-zero
  • Jenkins deploys all

Our old system used real VMs (that’s an oxymoron) to run tests. These VMs would accumulate cruft with each run, so we designed a system to have fresh nodes to test on. Jeremiah Gray did a great writeup about our new testing framework. We created LXCs (Linux Containers) provisioned with chef-zero (which allowed test data bags) to run our Test Kitchen testing framework. We fully embraced Berkshelf to handle all our cookbook dependencies. We figured most of this out on our own but it looks similar to a chapter in Test-Driven Infrastructure with Chef.

Doing it right, no cheating

While we were dreaming of the next feature to add to our CI system, the ugly truth that we took some shortcuts kept gnawing at us. It was time to finish out our rules: everything in git, everything tested, Jenkins deploys all to our entire infrastructure.

Nodes

With each push to our nodes repository, a script checks JSON syntax and crosschecks all nodes in Chef and git. If a node exists in one (Chef or git) but not the other, we receive an alert. Upon success, Jenkins knifes in all nodes to our fleet. This works for us now but may not scale in the future. What I like about this process is nodes are reset across the fleet frequently. There won’t be any lingering rogue node edits for any long period of time.

Data Bags

The data bag system works in a similar manner. First a syntax check looks at the JSON, then data bags in Chef and git are compared. The script is written so you can have data bags in git that are not yet in your Chef system, but once deployed to the fleet, they will be updated en masse like nodes.

Roles

Roles were the simplest case of all of these. It too has a syntax check. Jenkins pushes all roles in git into production upon a successful push to the master roles repository.

Community Cookbooks

We wrote a cookbook that acts as a framework to test our community cookbooks. Some community cookbooks come with tests and other do not. As we add more community cookbooks into our infrastructure, we have a place for tests.

Monitoring Host Group

We are supporting our legacy and current CI system so breaking down components into groups was a worthwhile exercise. All of the servers in our CI fleet were monitored, but putting them into their own host group helped compartmentalize how all the moving parts worked.

Always in Transition

While developing this system and using it in production, we also wanted to move all nodes from our Chef 10 production servers to our new Chef 11 server. We have most of our nodes migrated and once this is done, we can turn down a lot of VMs that support the Chef 10 and CI 1.0 infrastructure.

What’s next

When we originally planned our next phase we thought we would implement Gerrit (code review) and Zuul (project gating). All of the above upgrades were required before we could even think about making this transition. We are still working on some of the details I have highlighted in this post but Gerrit+Zuul are on our road map.

Chaining and Reversing CSS Transitions

CSS3 has given us a lot of goodies that help front-end devs eliminate the use of images to achieve the stylistic effects that so many designers love to use. These include gradients and drop shadows on both text and DOM elements (and soon we’ll have blend modes!). There are also transitions and animations which, in many simple cases, can eliminate the need to use JavaScript to animate, though we still need JS to add or remove classes to trigger those effects.

I was recently reading Alex MacCaw’s great post on CSS Transitions and I learned a lot; you should check it out. I was surprised, though, that he left out mention of the transition-delay property. I’ve found it to be useful for doing some more complex transitions without building out a full JS framework like he does in his post. Let’s walk through how transition-delay can help with this.

The Setup

I’m just going to show the pertinent snippets; obviously you should use whole HTML documents! If you want to play with the examples or even fork them, they’re up on codepen.io. For our example, I’m going to build a drawer that slides out when you click on an anchor link.

The HTML

<div class="drawer">
  <div class="drawer-content">
    Some content here
  </div>
</div>

The CSS

* {
  box-sizing: border-box;
}

body {
  background: #ccc;
}

.toggle-thumb {
  display: block;
  width: 45px;
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  transition: all .2s ease-in;
}
.toggle-thumb:hover {
  background: rgba(255,0,0,.5);
}
.drawer {
  position: fixed;
  top: 0;
  bottom: 0;
  width: 275px;
  left: -235px;
  padding: 40px 45px;
  margin: 0;
  z-index: 20;
  background: rgba(255,255,255, .98);
}

.open.drawer {
  left: 0;
}

Nothing crazy here, just a few divs and our anchor to get everything in place. If you click through, the button is the white bar on the left side of the page. We’re going to open the drawer by adding a class open to the drawer container. In the example, this moves the drawer over so that you can read the contents. Currently there are no transitions, so at this point we’re seeing what a browser that doesn’t support transitions will look like.

The white bar on the left will be the clickable area for the sliding drawer.

The white bar on the left will be the clickable area for the sliding drawer.

View on Codepen.io

Adding a Transition

This one’s easy, we just add a transition. In the example I’m just using the transition shortcut, but chances are you’ll have to add a variety of vendor-prefixes as well.


.drawer {
  position: fixed;
  top: 0;
  bottom: 0;
  width: 275px;
  left: -235px;
  padding: 40px 45px;
  margin: 0;
  z-index: 20;
  background: rgba(255,255,255, .98);
  /* trigger HW acceleration */
  transform: translate3d(0,0,0);
  transition: left .15s ease-in-out .3s;
 }

.open.drawer {
  left: 0;
 }

You’ll notice that we added the transition on the base class, not on the class that we’re adding. This makes sure that the transition happens both when adding and when removing the class. If it were just on the class that was being added, the element would snap back without the transition.

View on Codepen.io

Chaining Transitions

Here’s where transition-delay comes in handy. If you need to transition in a certain order, you can actually delay them. Couple this with the fact that each element can have multiple transitions and you can start to chain transitions. To get our transitions to chain we’re going to use a delay for second transition that’s equal to the duration of the first, that way we’ll get a two transitons back to back just by adding a single class.

.drawer {
 position: fixed;
 top: 0;
 bottom: 0;
 width: 275px;
 left: -235px;
 padding: 40px 45px;
 margin: 0;
 z-index: 20;
 background: rgba(255,255,255, .98);
 /* trigger HW acceleration */
 transform: translate3d(0,0,0);
 transition: box-shadow .2s ease-in-out, left .15s ease-in-out .3s;
}
.open.drawer {
 left: 0;
 box-shadow: 10px 0 15px rgba(0,0,0, .3);
}

Here, we’ve added a second transition for the box-shadow property and we added the styling for the box shadow on the open class because we want to add the shadow as it opens to give the illusion of it coming off of the page.

Clicking on the white bar (pink when hovered) will slide the drawer out using the animation

Clicking on the white bar (pink when hovered) will slide the drawer out using the animation

View on Codepen.io

Getting It to Reverse

You might have noticed in the last example that the reverse case doesn’t exactly work properly. It still transitions the box-shadow first when removing the class. We can fix this by moving our current transition declaration to .open and then adding one to .drawer that swaps the order of the transitions.

.drawer {
 position: fixed;
 top: 0;
 bottom: 0;
 width: 275px;
 left: -235px;
 padding: 40px 45px;
 margin: 0;
 z-index: 20;
 background: rgba(255,255,255, .98);
 /* trigger HW acceleration */
 transform: translate3d(0,0,0);
 transition: left .15s ease-in-out, box-shadow .2s ease-in-out .3s;
}
.open.drawer {
 left: 0;
 box-shadow: 10px 0 15px rgba(0,0,0, .3);
 transition: box-shadow .2s ease-in-out, left .15s ease-in-out .3s;
}

View on Codepen.io

Wrap up

So that’s it! You might ask, “Why use this over animations which (now) have animation-direction built in?” I find transitions a bit more concise and manageable. This technique does lose its advantage over animations, though, when you start having to do more than two transitons. It simply becomes cumbersome, and manually re-ordering transition definitions doesn’t scale well.

Thanks for reading and I hope someone will find this trick as useful as we have.

Touch Input and Responsive Web Design

With the release of Windows 8, touch has finally landed on the desktop. There have been some great posts about the design implications of this change, but I haven’t seen much about technical implications, so I decided to write this. Chances are you’ve thought about  touch interaction if you were building a separate mobile site, but what does it mean for a desktop site or a responsive site?

Why Optimize for Touch?

Why is this something you’d want to do? It boils down to making things better for those who visit your site regardless of the device they’re using. This is why many people and companies have chosen Responsive Web Design. But what does Windows 8 have to do with any of this? It’s the first desktop operating system to include touch (and pen input, but more about that later) as an OS-wide, first-class input mechanism. So suddenly, if you have touch hardware, your desktop browser is going to be firing real touch events instead of using a third-party software abstraction to fire mouse events in the OS.

Who should be checking to see if their site needs any changes? If you’re doing anything with JavaScript click-handlers – most sites these days are doing something - then there are some touch-related things to think about. Additionally, maybe you want to consider gestures of some sort or you want to incorporate two or three-finger touch events. But the most important thing to consider is how you handle the simple single-touch event. Often you’ll want to trigger a touch event instead of click.

I’m going to focus on this last one as I think it’s the most common case. The reason single-touch needs “fixing” is that click events incur a penalty in the form of a 300 millisecond delay on many touch-enabled devices. This is to allow the OS to determine if you meant to pan or zoom instead of just clicking. You can speed up this interaction by checking those things yourself.

Optimizing (allthethings) for Touch

There are a few ways to do this. You can feature-detect touch events and then bind to “touchend” instead of click. (Modernizr is great for this but may be overkill for this one use case.) If you decide to go this route you will have to manage everything yourself: handle touch, determine if the user is scrolling/panning/zooming (if they are: don’t fire the handlers, if they’re not: fire it), and then after you fire it there will still be a click event fired.

What—you were expecting this to be straightforward? We are dealing with web browsers after all! What can we do to make this easier? Use a library, of course! But before doing that, I recommend reading through this Google post (this was the first place I read about the technique) so that you understand everything involved with overriding the default browser behavior. The library I’d recommend using is FTLabs’s FastClick. Be sure to read through the source too, it’s well documented. The nice thing about FastClick is that you only have to bind it once for the whole document and it only inserts itself if your device supports touch, as it has the feature-detection built in.

The Touch Future (or: When Touch is Not Enough)

Touch and click events are closely related as there was some effort to have backwards compatibility. But leave it to IE to break up the party. Turns out IE10 and “Metro” apps don’t have touch events (read more about the problem in this Modernizr issue on Github). Instead, Microsoft has abstracted and unified input mechanisms with what they’re calling pointer events. Instead of binding to touch or click, you bind to pointer event and the OS knows when to fire it based on the input method you’re currently using (touch, mouse, pen, laser, etc.). Boris Smus has written a polyfill for pointer events and has a great post explaining it, though I think it might not be ready for primetime. Recently, the W3C has formed a committee to begin the standardization process for pointer events, so it’s definitely something to keep an eye on.

I think pointer events will be the way forward because they are a better abstraction, and you don’t have to do a bunch of hokey pokey to get things to work properly, you simply let the browser do the heavy lifting for you. Even if that’s true though, touch events aren’t going anywhere anytime soon. They’re something you’ll need to feature-detect (there’s talk of defining Modernizr.pointer or Modernizr.mspointer in the above Modernizr issue) and then do what web developers always do: treat IE differently.