Blog


  •   

    When the mockups for the new Financial Times application hit our desks in mid-2012, we knew we had a real challenge on our hands. Many of us on the team (including me) swore that parts of interface would not be possible in HTML5. Given the product team’s passion for the new UI, we rolled up our sleeves and gave it our best shot.

    We were tasked with implementing a far more challenging product, without compromising the reliable, performant experience that made the first app so successful.

    promo-500-compr

    We didn’t just want to build a product that fulfilled its current requirements; we wanted to build a foundation that we could innovate on in the future. This meant building with a maintenance-first mentality, writing clean, well-commented code and, at the same time, ensuring that our code could accommodate the demands of an ever-changing feature set.

    In this article, I’ll discuss some of the changes we made in the latest release and the decision-making behind them. I hope you will come away with some ideas and learn from our solutions as well as our mistakes.

    Supported Devices

    The first Financial Times Web app ran on iPad and iPhone in the browser, and it shipped in a native (PhoneGap-esque) application wrapper for Android and Windows 8 Metro devices. The latest Web app is currently being served to iPad devices only; but as support is built in and tested, it will be rolled out to all existing supported platforms. HTML5 gives developers the advantage of occupying almost any mobile platform. With 2013 promising the launch of several new Web application marketplaces (eg. Chrome Web Store and Mozilla Marketplace), we are excited by the possibilities that lie ahead for the mobile Web.

    Fixed-Height Layouts

    The first shock that came from the new mockups was that they were all fixed height. By “fixed height,” I mean that, unlike a conventional website, the height of the page is restricted to the height of the device’s viewport. If there is more content than there is screen space, overflow must be dealt with at a component level, as opposed to the page level. We wanted to use JavaScript only as a last resort, so the first tool that sprang to mind was flexbox. Flexbox gives developers the ability to declare flexible elements that can fill the available horizontal or vertical space, something that has been very tricky to do with CSS. Chris Coyier has a great introduction to flexbox.

    Using Flexbox in Production

    Flexbox has been around since 2009 and has great support on all the popular smartphones and tablets. We jumped at the chance to use flexbox when we found out how easily it could solve some of our complex layouts, and we started throwing it at every layout problem we faced. As the app began to grow, we found performance was getting worse and worse.

    We spent a good few hours in Chrome Developers Tools’ timeline and found the culprit: Shock, horror! — it was our new best friend, flexbox. The timeline showed that some layouts were taking close to 100 milliseconds; reworking our layouts without flexbox reduced this to 10 milliseconds! This may not seem like a lot, but when swiping between sections, 90 milliseconds of unresponsiveness is very noticeable.

    Back to the Old School

    We had no other choice but to tear out flexbox wherever we could. We used 100% height, floats, negative margins, border-box sizing and padding to achieve the same layouts with much greater performance (albeit with more complex CSS). Flexbox is still used in some parts of the app. We found that its impact on performance was less expensive when used for small UI components.

    layout-time-with-flexbox-500_comp
    Page layout time with flexbox

    layout-time-without-flexbox-500_comp
    Page layout time without flexbox

    Truncation

    The content of a fixed-height layout will rarely fit its container; eventually it has to overflow. Traditionally in print, designers have used ellipses (three dots) to solve this problem; however, on the Web, this isn’t the simplest technique to implement.

    Ellipsis

    You might be familiar with the text-overflow: ellipsis declaration in CSS. It works great, has awesome browser support, but has one shortfall: it can’t be used for text that spans multiple lines. We needed a solution that would insert an ellipsis at the point where the paragraph overflows its container. JavaScript had to step in.

    ellipsis-500_mini
    Ellipsis truncation is used throughout.

    After an in-depth research and exploration of several different approaches, we created our FTEllipsis library. In essence, it measures the available height of the container, then measures the height of each child element. When it finds the child element that overflows the container, it caps its height to a sensible number of lines. For WebKit-based browsers, we use the little-known -webkit-line-clamp property to truncate an element’s text by a set number of lines. For non-WebKit browsers, the library allows the developer to style the overflowing container however they wish using regular CSS.

    Modularization

    Having tackled some of the low-level visual challenges, we needed to step back and decide on the best way to manage our application’s views. We wanted to be able to reuse small parts of our views in different contexts and find a way to architect rock-solid styling that wouldn’t leak between components.

    One of the best decisions we made in implementing the new application was to modularize the views. This started when we were first looking over the designs. We scribbled over printouts, breaking the page down into chunks (or modules). Our plan was to identify all of the possible layouts and modules, and define each view (or page) as a combination of modules sitting inside the slots of a single layout.

    Each module needed to be named, but we found it very hard to describe a module, especially when some modules could have multiple appearances depending on screen size or context. As a result, we abandoned semantic naming and decided to name each component after a type of fruit — no more time wasted thinking up sensible, unambiguous names!

    An example of a module’s markup:

    
    <div class="apple">
      <h2 class="apple_headline">{{headline}}</h2>
      <h3 class="apple_sub-head">{{subhead}}</h3>
      <div class="apple_body">{{body}}</div>
    </div>
    

    An example of a module’s styling:

    
    .apple {}
    
    .apple_headline {
      font-size: 40px;
    }
    
    .apple_sub-head {
      font-size: 20px;
    }
    
    .apple_body {
      font-size: 14px;
      column-count: 2;
      color: #333;
    }
    

    Notice how each class is prefixed with the module’s name. This ensures that the styling for one component will never affect another; every module’s styling is encapsulated. Also, notice how we use just one class in our CSS selectors; this makes our component transportable. Ridding selectors of any ancestral context means that modules may be dropped anywhere in our application and will look the same. This is all imperative if we want to be able to reuse components throughout the application (and even across applications).

    What If a Module Needs Interactions?

    Each module (or fruit) has its own markup and style, which we wrote in such a way that it can be reused. But what if we need a module to respond to interactions or events? We need a way to bring the component to life, but still ensure that it is unbound from context so that it can be reused in different places. This is a little trickier that just writing smart markup and styling. To solve this problem, we wrote FruitMachine.

    Reusable Components

    FruitMachine is a lightweight library that assembles our layout’s components and enables us to declare interactions on a per-module basis. It was inspired by the simplicity of Backbone views, but with a little more structure to keep “boilerplate” code to a minimum. FruitMachine gives our team a consistent way to work with views, while at the same time remaining relatively unopinionated so that it can be used in almost any view.

    The Component Mentality

    Thinking about your application as a collection of standalone components changes the way you approach problems. Components need to be dumb; they can’t know anything of their context or of the consequences of any interactions that may occur within them. They can have a public API and should emit events when they are interacted with. An application-specific controller assembles each layout and is the brain behind everything. Its job is to create, control and listen to each component in the view.

    For example, to show a popover when a component named “button” is clicked, we would not hardcode this logic into the button component. Instead “button” would emit a buttonclicked event on itself every time its button is clicked; the view controller would listen for this event and then show the popover. By working like this, we can create a large collection of components that can be reused in many different contexts. A view component may not have any application-specific dependencies if it is to be used across projects.

    Working like this has simplified our architecture considerably. Breaking down our views into components and decoupling them from our application focuses our decision-making and moves us away from baking complex, heavily dependent modules into our application.

    The Future of FruitMachine

    FruitMachine was our solution to achieve fully transportable view components. It enables us to quickly define and assemble views with minimal effort. We are currently using FruitMachine only on the client, but server-side (NodeJS) usage has been considered throughout development. In the coming months, we hope to move towards producing server-side-rendered websites that progressively enhance into a rich app experience.

    You can find out more about FruitMachine and check out some more examples in the public GitHub repository.

    Retina Support

    The Financial Times’ first Web app was released before the age of “Retina” screens. We retrofitted some high-resolution solutions, but never went the whole hog. For our designers, 100% Retina support was a must-have in the new application. We developers were sick of maintaining multiple sizes and resolutions of each tiny image within the UI, so a single vector-based solution seemed like the best approach. We ended up choosing icon fonts to replace our old PNGs, and because they are implemented just like any other custom font, they are really well supported. SVG graphics were considered, but after finding a lack of support in Android 2.3 and below, this option was ruled out. Plus, there is something nice about having all of your icons bundled up in a single file, whilst not sacrificing the individuality of each graphic (like sprites).

    Our first move was to replace the Financial Times’ logo image with a single glyph in our own custom icon font. A font glyph may be any color and size, and it always looks super-sharp and is usually lighter in weight than the original image. Once we had proved it could work, we began replacing every UI image and icon with an icon font alternative. Now, the only pixel-based image in our CSS is the full-color logo on the splash screen. We used the powerful but rather archaic-looking FontForge to achieve this.

    Once past the installation phase, you can open any font file in FontForge and individually change the vector shape of any character. We imported SVG vector shapes (created in Adobe Illustrator) into suitable character slots of our font and exported as WOFF and TTF font types. A combination of WOFF and TTF file formats are required to support iOS, Android and Windows devices, although we hope to rely only on WOFFs once Android gains support (plus, WOFFs are around 25% smaller in file size than TTFs).

    icon-font-500-compr
    The Financial Times’ icon font in Font Forge

    Images

    Article images are crucial for user engagement. Our images are delivered as double-resolution JPEGs so that they look sharp on Retina screens. Our image service (running ImageMagick) outputs JPEGs at the lowest possible quality level without causing noticeable degradation (we use 35 for Retina devices and 70 for non-Retina). Scaling down retina size images in the browser enables us to reduce JPEG quality to a lower level than would otherwise be possible without compression artifacts becoming noticeable. This article explains this technique in more detail.

    It’s worth noting that this technique does require the browser to work a little harder. In old browsers, the work of scaling down many large images could have a noticeable impact on performance, but we haven’t encountered any serious problems.

    Native-Like Scrolling

    Like almost any application, we require full-page and subcomponent scrolling in order to manage all of the content we want to show our users. On desktop, we can make use of the well-established overflow CSS property. When dealing with the mobile Web, this isn’t so straightforward. We require a single solution that provides a “momentum” scrolling experience across all of the devices we support.

    overflow: scroll

    The overflow: scroll declaration is becoming usable on the mobile Web. Android and iOS now support it, but only since Android 3.0 and iOS 5. IOS 5 came with the exciting new -webkit-overflow-scrolling: touch property, which allows for native momentum-like scrolling in the browser. Both of these options have their limitations.

    Standard overflow: scroll and overflow: auto don’t display scroll bars as users might expect, and they don’t have the momentum touch-scrolling feel that users have become accustomed to from their native apps. The -webkit-overflow-scrolling: touch declaration does add momentum scrolling and scroll bars, but it doesn’t allow developers to style the scroll bars in any way, and has limited support (iOS 5+ and Chrome on Android).

    A Consistent Experience

    Fragmented support and an inconsistent feel forced us to turn to JavaScript. Our first implementation used the TouchScroll library. This solution met our needs, but as our list of supported devices grew and as more complex scrolling interactions were required, working with it became trickier. TouchScroll lacks IE 10 support, and its API interface is difficult to work with. We also tried Scrollability and Zynga Scroller, neither of which have the features, performance or cross-browser capability we were looking for. Out of this problem, FTScroller was developed: a high-performance, momentum-scrolling library with support for iOS, Android, Playbook and IE 10.

    FTScroller

    FTScroller’s scrolling implementation is similar to TouchScroll’s, with a flexible API much like Zynga Scroller. We added some enhancements, such as CSS bezier curves for bouncing, requestAnimationFrame for smoother frame rates, and support for IE 10. The advantage of writing our own solution is that we could develop a product that exactly meets our requirements. When you know the code base inside out, fixing bugs and adding features is a lot simpler.

    FTScroller is dead simple to use. Just pass in the element that will wrap the overflowing content, and FTScroller will implement horizontal or vertical scrolling as and when needed. Many other options may be declared in an object as the second argument, for more custom requirements. We use FTScroller throughout the Financial Times’ Web app for a consistent cross-platform scrolling experience.

    A simple example:

    
    var container = document.getElementById('scrollcontainer');
    var scroller = new FTScroller(container);
    

    The Gallery

    The part of our application that holds and animates the page views is known as the “gallery.” It consists of three divisions: left, center and right. The page that is currently in view is located in the center pane. The previous page is positioned off screen in the left-hand pane, and the next page is positioned off screen in the right-hand pane. When the user swipes to the next page, we use CSS transitions to animate the three panes to the left, revealing the hidden right pane. When the transition has finished, the right pane becomes the center pane, and the far-left pane skips over to become the right pane. By using only three page containers, we keep the DOM light, while still creating the illusion of infinite pages.

    Web
    Infinite scrolling made possible with a three-pane gallery

    Making It All Work Offline

    Not many Web apps currently offer an offline experience, and there’s a good reason for that: implementing it is a bloody pain! The application cache (AppCache) at first glance appears to be the answer to all offline problems, but dig a little deeper and stuff gets nasty. Talks by Andrew Betts and Jake Archibald explain really well the problems you will encounter. Unfortunately, AppCache is currently the only way to achieve offline support, so we have to work around its many deficiencies.

    Our approach to offline is to store as little in the AppCache as possible. We use it for fonts, the favicon and one or two UI images — things that we know will rarely or never need updating. Our JavaScript, CSS and templates live in LocalStorage. This approach gives us complete control over serving and updating the most crucial parts of our application. When the application starts, the bare minimum required to get the app up and running is sent down the wire, embedded in a single HTML page; we call this the preload.

    We show a splash screen, and behind the scenes we make a request for the application’s full resources. This request returns a big JSON object containing our JavaScript, CSS and Mustache templates. We eval the JavaScript and inject the CSS into the DOM, and then the application launches. This “bootstrap” JSON is then stored in LocalStorage, ready to be used when the app is next started up.

    On subsequent startups, we always use the JSON from LocalStorage and then check for resource updates in the background. If an update is found, we download the latest JSON object and replace the existing one in LocalStorage. Then, the next time the app starts, it launches with the new assets. If the app is launched offline, the startup process is the same, except that we cannot make the request for resource updates.

    Images

    Managing offline images is currently not as easy as it should be. Our image requests are run through a custom image loader and cached in the local database (IndexedDB or WebSQL) so that the images can be loaded when a network connection is not present. We never load images in the conventional way, otherwise they would break when users are offline.

    Our image-loading process:

    1. The loader scans the page for image placeholders declared by a particular class.
    2. It takes the src attribute of each image placeholder found and requests the source from our JavaScript image-loader library.
    3. The local database is checked for each image. Failing that, a single HTTP request is made listing all missing images.
    4. A JSON array of Base64-encoded images is returned from the HTTP response and stored separately in the local database.
    5. A callback is fired for each image request, passing the Base64 string as an argument.
    6. An <img> element is created, and its src attribute is set to the Base64 data-URI string.
    7. The image is faded in.

    I should also mention that we compress our Base64-encoded image strings in order to fit as many images in the database as possible. My colleague Andrew Betts goes into detail on how this can be achieved.

    In some cases, we use this cool trick to handle images that fail to load:

    
    <img src="image.jpg" onerror="this.style.display='none';" />
    

    Ever-Evolving Applications

    In order to stay competitive, a digital product needs to evolve, and as developers, we need to be prepared for this. When the request for a redesign landed at the Financial Times, we already had a fast, popular, feature-rich application, but it wasn’t built for change. At the time, we were able to implement small changes to features, but implementing anything big became a slow process and often introduced a lot of unrelated regressions.

    Our application was drastically reworked to make the new requirements possible, and this took a lot of time. Having made this investment, we hope the new application not only meets (and even exceeds) the standard of the first product, but gives us a platform on which we can develop faster and more flexibly in the future.

    (al)


    © Wilson Page for Smashing Magazine, 2013.


  •   

    Flexible box layout (or flexbox) is a new box model optimized for UI layout. As one of the first CSS modules designed for actual layout (floats were really meant mostly for things such as wrapping text around images), it makes a lot of tasks much easier, or even possible at all. Flexbox’s repertoire includes the simple centering of elements (both horizontally and vertically), the expansion and contraction of elements to fill available space, and source-code independent layout, among others abilities.

    Flexbox has lived a storied existence. It started as a feature of Mozilla’s XUL, where it was used to lay out application UI, such as the toolbars in Firefox, and it has since been rewritten multiple times. The specification has only recently reached stability, and we have fairly complete support across the latest versions of the leading browsers.

    There are, however, some caveats. The specification changed between the implementation in Internet Explorer (IE) and the release of IE 10, so you will need to use a slightly different syntax. Chrome currently still requires the -webkit- prefix, and Firefox and Safari are still on the much older syntax. Firefox has updated to the latest specification, but that implementation is currently behind a runtime flag until it is considered stable and bug-free enough to be turned on by default. Until then, Firefox still requires the old syntax.

    When you specify that an element will use the flexbox model, its children are laid out along either the horizontal or vertical axis, depending on the direction specified. The widths of these children expand or contract to fill the available space, based on the flexible length they are assigned.

    Example: Horizontal And Vertical Centering (Or The Holy Grail Of Web Design)

    Being able to center an element on the page is perhaps the number one wish among Web designers — yes, probably even higher than gaining the highly prized parent selector or putting IE 6 out of its misery (OK, maybe a close second then). With flexbox, this is trivially easy. Let’s start with a basic HTML template, with a heading that we want to center. Eventually, once we’ve added all the styling, it will end up looking like this vertically and horizontally centered demo.

    
    <!DOCTYPE html>
    <html lang="en">
    <head>
       <meta charset="utf-8"/>
       <title>Centering an Element on the Page</title>
    </head>
    <body>
       <h1>OMG, I’m centered</h1>
    </body>
    </html>
    

    Nothing special here, not even a wrapper div. The magic all happens in the CSS:

    
    html {
       height: 100%;
    } 
    
    body {
       display: -webkit-box;   /* OLD: Safari,  iOS, Android browser, older WebKit browsers.  */
       display: -moz-box;   /* OLD: Firefox (buggy) */ 
       display: -ms-flexbox;   /* MID: IE 10 */
       display: -webkit-flex;    /* NEW, Chrome 21+ */
       display: flex;       /* NEW: Opera 12.1, Firefox 22+ */
    
       -webkit-box-align: center; -moz-box-align: center; /* OLD… */
       -ms-flex-align: center; /* You know the drill now… */
       -webkit-align-items: center;
       align-items: center;
    
        -webkit-box-pack: center; -moz-box-pack: center; 
       -ms-flex-pack: center; 
       -webkit-justify-content: center;
       justify-content: center;
    
       margin: 0;
       height: 100%;
       width: 100% /* needed for Firefox */
    } 
    
    h1 {
       display: -webkit-box; display: -moz-box;
       display: -ms-flexbox;
       display: -webkit-flex;
       display: flex;
     
       -webkit-box-align: center; -moz-box-align: center;
       -ms-flex-align: center;
       -webkit-align-items: center;
       align-items: center;
    
       height: 10rem;
    }

    I’ve included all of the different prefixed versions in the CSS above, from the very oldest, which is still needed, to the modern and hopefully final syntax. This might look confusing, but the different syntaxes map fairly well to each other, and I’ve included tables at the end of this article to show the exact mappings.

    This is not exactly all of the CSS needed for our example, because I’ve stripped out the extra styling that you probably already know how to use in order to save space.

    Let’s look at the CSS that is needed to center the heading on the page. First, we set the html and body elements to have 100% height and remove any margins. This will make the container of our h1 take up the full height of the browser’s window. Firefox also needs a width specified on the body to force it to behave. Now, we just need to center everything.

    Enabling Flexbox

    Because the body element contains the heading that we want to center, we will set its display value to flex:

    
    body {
       display: flex;
    }

    This switches the body element to use the flexbox layout, rather than the regular block layout. All of its children in the flow of the document (i.e. not absolutely positioned elements) will now become flex items.

    The syntax used by IE 10 is display: -ms-flexbox, while older Firefox and WebKit browsers use display: -prefix-box (where prefix is either moz or webkit). You can see the tables at the end of this article to see the mappings of the various versions.

    What do we gain now that our elements have been to yoga class and become all flexible? They gain untold powers: they can flex their size and position relative to the available space; they can be laid out either horizontally or vertically; and they can even achieve source-order independence. (Two holy grails in one specification? We’re doing well.)

    Centering Horizontally

    Next, we want to horizontally center our h1 element. No big deal, you might say; but it is somewhat easier than playing around with auto margins. We just need to tell the flexbox to center its flex items. By default, flex items are laid out horizontally, so setting the justify-content property will align the items along the main axis:

    
    body {
       display: flex;
       justify-content: center;
    }

    For IE 10, the property is called flex-pack, while for older browsers it is box-pack (again, with the appropriate prefixes). The other possible values are flex-start, flex-end, space-between and space-around. These are start, end, justify and distribute, respectively, in IE 10 and the old specification (distribute is, however, not supported in the old specification). The flex-start value aligns to the left (or to the right with right-to-left text), flex-end aligns to the right, space-between evenly distributes the elements along the axis, and space-around evenly distributes along the axis, with half-sized spaces at the start and end of the line.

    To explicitly set the axis that the element is aligned along, you can do this with the flex-flow property. The default is row, which will give us the same result that we’ve just achieved. To align along the vertical axis, we can use flex-flow: column. If we add this to our example, you will notice that the element is vertically centered but loses the horizontal centering. Reversing the order by appending -reverse to the row or column values is also possible (flex-flow: row-reverse or flex-flow: column-reverse), but that won’t do much in our example because we have only one item.

    There are some differences here in the various versions of the specification, which are highlighted at the end of this article. Another caveat to bear in mind is that flex-flow directions are writing-mode sensitive. That is, when using writing-mode: vertical-rl to switch to vertical text layout (as used traditionally in China, Japan and Korea), flex-flow: row will align the items vertically, and column will align them horizontally.

    Centering Vertically

    Centering vertically is as easy as centering horizontally. We just need to use the appropriate property to align along the “cross-axis.” The what? The cross-axis is basically the axis perpendicular to the main one. So, if flex items are aligned horizontally, then the cross-axis would be vertical, and vice versa. We set this with the align-items property (flex-align in IE 10, and box-align for older browsers):

    
    body {
       /* Remember to use the other versions for IE 10 and older browsers! */
       display: flex;
       justify-content: center;
       align-items: center;
    }

    This is all there is to centering elements with flexbox! We can also use the flex-start (start) and flex-end (end) values, as well as baseline and stretch. Let’s have another look at the finished example:

    figure1.1_mini
    Simple horizontal and vertical centering using flexbox. Larger view.

    You might notice that the text is also center-aligned vertically inside the h1 element. This could have been done with margins or a line height, but we used flexbox again to show that it works with anonymous boxes (in this case, the line of text inside the h1 element). No matter how high the h1 element gets, the text will always be in the center:

    
    h1 {
       /* Remember to use the other versions for IE 10 and older browsers! */
       display: flex;
       align-items: center;
       height: 10rem;
    }

    Flexible Sizes

    If centering elements was all flexbox could do, it’d be pretty darn cool. But there is more. Let’s see how flex items can expand and contract to fit the available space within a flexbox element. Point your browser to this next example.

    figure1.2_mini
    An interactive slideshow built using flexbox. Larger view.

    The HTML and CSS for this example are similar to the previous one’s. We’re enabling flexbox and centering the elements on the page in the same way. In addition, we want to make the title (inside the header element) remain consistent in size, while the five boxes (the section elements) adjust in size to fill the width of the window. To do this, we use the new flex property:

    
    section {
       /* removed other styles to save space */
       -prefix-box-flex: 1; /* old spec webkit, moz */
       flex: 1;
       height: 250px;
    }

    What we’ve just done here is to make each section element take up 1 flex unit. Because we haven’t set any explicit width, each of the five boxes will be the same width. The header element will take up a set width (277 pixels) because it is not flexible. We divide the remaining width inside the body element by 5 to calculate the width of each of the section elements. Now, if we resize the browser window, the section elements will grow or shrink.

    In this example, we’ve set a consistent height, but this could be set to be flexible, too, in exactly the same way. We probably wouldn’t always want all elements to be the same size, so let’s make one bigger. On hover, we’ve set the element to take up 2 flex units:

    
    section:hover {
       -prefix-box-flex: 2;
       flex: 2;
       cursor: pointer;
    }

    Now the available space is divided by 6 rather than 5, and the hovered element gets twice the base amount. Note that an element with 2 flex units does not necessarily become twice as wide as one with 1 unit. It just gets twice the share of the available space added to its “preferred width.” In our examples, the “preferred width” is 0 (the default).

    Source-Order Independence

    For our last party trick, we’ll study how to achieve source-order independence in our layouts. When clicking on a box, we will tell that element to move to the left of all the other boxes, directly after the title. All we have to do is set the order with the order property. By default, all flex items are in the 0 position. Because they’re in the same position, they follow the source order. Click on your favorite person in the updated example to see their order change.

    figure1.3_mini
    An interactive slideshow with flex-order. Larger view.

    To make our chosen element move to the first position, we just have to set a lower number. I chose -1. We also need to set the header to -1 so that the selected section element doesn’t get moved before it:

    
    header {
       -prefix-box-ordinal-group: 1; /* old spec; must be positive */
       -ms-flex-order: -1; /* IE 10 syntax */
       order: -1; /* new syntax */
    } 
    
    section[aria-pressed="true"] {
       /* Set order lower than 0 so it moves before other section elements,
          except old spec, where it must be positive.
     */
       -prefix-box-ordinal-group: 1;
       -ms-flex-order: -1;
       order: -1;
    
       -prefix-box-flex: 3;
       flex: 3;
       max-width: 370px; /* Stops it from getting too wide. */
    }

    In the old specification, the property for setting the order (box-ordinal-group) accepts only a positive integer. Therefore, I’ve set the order to 2 for each section element (code not shown) and updated it to 1 for the active element. If you are wondering what aria-pressed="true" means in the example above, it is a WAI-ARIA attribute/value that I add via JavaScript when the user clicks on one of the sections.

    This relays accessibility hints to the underlying system and to assistive technology to tell the user that that element is pressed and, thus, active. If you’d like more information on WAI-ARIA, check out “Introduction to WAI-ARIA” by Gez Lemon. Because I’m adding the attribute after the user clicks, this example requires a simple JavaScript file in order to work, but flexbox itself doesn’t require it; it’s just there to handle the user interaction.

    Hopefully, this has given you some inspiration and enough introductory knowledge of flexbox to enable you to experiment with your own designs.

    Syntax Changes

    As you will have noticed throughout this article, the syntax has changed a number of times since it was first implemented. To aid backward- and forward-porting between the different versions, we’ve included tables below, which map the changes between the specifications.

    Specification versions
    Specification IE Opera Firefox Chrome Safari
    Standard 11? 12.10+ * Behind flag 21+ (-webkit-)
    Mid 10 (-ms-)
    Old 3+ (-moz-) -webkit-) 3+ (-webkit-)

    * Opera will soon switch to WebKit. It will then require the -webkit- prefix if it has not been dropped by that time.

    Enabling flexbox: setting an element to be a flex container
    Specification Property name Block-level flex Inline-level flex
    Standard display flex inline-flex
    Mid display flexbox inline-flexbox
    Old display box inline-box
    Axis alignment: specifying alignment of items along the main flexbox axis
    Specification Property name start center end justify distribute
    Standard justify-content flex-start center flex-end space-between space-around
    Mid flex-pack start center end justify distribute
    Old box-pack start center end justify N/A
    Cross-axis alignment: specifying alignment of items along the cross-axis
    Specification Property name start center end baseline stretch
    Standard align-items flex-start center flex-end baseline stretch
    Mid flex-align start center end baseline stretch
    Old box-align start center end baseline stretch
    Individual cross-axis alignment: override to align individual items along the cross-axis
    Specification Property name auto start center end baseline stretch
    Standard align-self auto flex-start center flex-end baseline stretch
    Mid flex-item-align auto start center end baseline stretch
    Old N/A
    Flex line alignment: specifying alignment of flex lines along the cross-axis
    Specification Property name start center end justify distribute stretch
    Standard align-content flex-start center flex-end space-between space-around stretch
    Mid flex-line-pack start center end justify distribute stretch
    Old N/A

    This takes effect only when there are multiple flex lines, which is the case when flex items are allowed to wrap using the flex-wrap property and there isn’t enough space for all flex items to display on one line. This will align each line, rather than each item.

    Display order: specifying the order of flex items
    Specification Property name Value
    Standard order
    Mid flex-order <number>
    Old box-ordinal-group <integer>
    Flexibility: specifying how the size of items flex
    Specification Property name Value
    Standard flex none | [ <flex-grow> <flex-shrink>? || <flex-basis>]
    Mid flex none | [ [ <pos-flex> <neg-flex>? ] || <preferred-size> ]
    Old box-flex <number>

    The flex property is more or less unchanged between the new standard and the draft supported by Microsoft. The main difference is that it has been converted to a shorthand in the new version, with separate properties: flex-grow, flex-shrink and flex-basis. The values may be used in the same way in the shorthand. However, the default value for flex-shrink (previously called negative flex) is now 1. This means that items do not shrink by default. Previously, negative free space would be distributed using the flex-shrink ratio, but now it is distributed in proportion to flex-basis multiplied by the flex-shrink ratio.

    Direction: specifying the direction of the main flexbox axis
    Specification Property name Horizontal Reversed horizontal Vertical Reversed vertical
    Standard flex-direction row row-reverse column column-reverse
    Mid flex-direction row row-reverse column column-reverse
    Old box-orient

    box-direction

    horizontal

    normal

    horizontal

    reverse

    vertical

    normal

    vertical

    reverse

    In the old version of the specification, the box-direction property needs to be set to reverse to get the same behavior as row-reverse or column-reverse in the later version of the specification. This can be omitted if you want the same behavior as row or column because normal is the initial value.

    When setting the direction to reverse, the main flexbox axis is flipped. This means that when using a left-to-right writing system, the items will display from right to left when row-reverse is specified. Similarly, column-reverse will lay out flex items from bottom to top, instead of top to bottom.

    The old version of the specification also has writing mode-independent values for box-orient. When using a left-to-write writing system, horizontal may be substituted for inline-axis, and vertical may be substituted for block-axis. If you are using a top-to-bottom writing system, such as those traditional in East Asia, then these values would be flipped.

    Wrapping: specifying whether and how flex items wrap along the cross-axis
    Specification Property name No wrapping Wrapping Reversed wrap
    Standard flex-wrap nowrap wrap wrap-reverse
    Mid flex-wrap nowrap wrap wrap-reverse
    Old box-lines single multiple N/A

    The wrap-reverse value flips the start and end of the cross-axis, so that if flex items are laid out horizontally, instead of items wrapping onto a new line below, they will wrap onto a new line above.

    At the time of writing, Firefox does not support the flex-wrap or older box-lines property. It also doesn’t support the shorthand.

    The current specification has a flex-flow shorthand, which controls both wrapping and direction. The behavior is the same as the one in the version of the specification implemented by IE 10. It is also currently not supported by Firefox, so I would recommend to avoid using it when specifying only the flex-direction value.

    Conclusion

    Well, that’s a (flex-)wrap. In this article, I’ve introduced some of the myriad of possibilities afforded by flexbox. Be it source-order independence, flexible sizing or just the humble centering of elements, I’m sure you can find ways to employ flexbox in your websites and applications. The syntax has settled down (finally!), and implementations are here. All major browsers now support flexbox in at least their latest versions.

    While some browsers use an older syntax, Firefox looks like it is close to updating, and IE 11 uses the latest version in leaked Windows Blue builds. There is currently no word on Safari, but it is a no-brainer considering that Chrome had the latest syntax before the Blink-WebKit split. For the time being, use the tables above to map the various syntaxes, and get your flex on.

    Layout in CSS is only getting more powerful, and flexbox is one of the first steps out of the quagmire we’ve found ourselves in over the years, first with table-based layouts, then float-based layouts. IE 10 already supports an early draft of the Grid layout specification, which is great for page layout, and Regions and Exclusions will revolutionize how we handle content flow and layout.

    Flexbox can be used today if you only need to support relatively modern browsers or can provide a fallback, and in the not too distant future, all sorts of options will be available, so that we can use the best tool for the job. Flexbox is shaping up to be a mighty fine tool.

    Further Reading

    (al)


    © David Storey for Smashing Magazine, 2013.

  • W FTW (for the Whitney)

    Whitney Logo, Before and After

    Established in 1930, the Whitney Museum of American Art in New York is devoted to the art of the United States presenting a “full range of twentieth-century and contemporary American art, with a special focus on works by living artists.” Its permanent collection contains approximately 19,000 paintings, sculptures, prints, drawings, and photographs, representing more than 2,900 artists and is considered one of the finest in the world. Currently located on Madison Avenue at 75th Street since 1966, the Whitney will move to a Renzo Piano-designed building dozens of blocks south in the Meatpacking District facing the popular High Line in 2015. In preparation for this move, the museum has introduced a new identity designed by Amsterdam-based Experimental Jetset.

    Two years ago, Museum staff began a thoughtful internal dialogue regarding the Whitney’s graphic identity and selected the design studio Experimental Jetset to develop an approach which embraces the spirit of the Museum while serving as a visual ambassador for our new building. The result is a distinctive and inventive graphic system that literally responds to art–a fundamental attribute of the Whitney since its founding in 1930. This dynamic identity, which the designers refer to as the “responsive ‘W’”, also illustrates the Museum’s ever-changing nature. In the upcoming years it will provide an important point of continuity for members, visitors, and the public during the transition to the new space.
    Whitney announcement

    Introduction and animation possibilities for the new logo.

    “It would be much easier to present the history of art as a simplistic line — but that’s not the Whitney”.

    This sentence immediately conjured up an image, a shape. It also begged the question: if the history of art should not be seen as a simplistic, straight line — then how should it be seen instead? And secondly, if presenting a straight line is not what the Whitney is about — then what is?

    That’s when we came up with the idea of the zig-zag line — the zig-zag being a metaphor for a non-simplistic, more complicated (and thus more interesting) history of art. And as it happens, the zig-zag also resembles a capital W.

    But even more than the letter W, we think the line also represents a pulse, a beat — the heartbeat of New York, of the USA. It shows the Whitney as an institute that is breathing (in and out), an institute that is open and closed at the same time. An institute that goes back and forth between the past and the future, moving from one opposite to the other (history and present, the ‘Old World’ and the ‘New World’, between the industrial and the sublime, etc.), while still moving forward.
    Experimental Jetset case study

    Whitney Logo and Identity

    The “periodic table” of the logo’s flexibility.

    Whitney Logo and Identity

    A couple of different ways of populating the logo with information.

    Whitney Logo and Identity

    The logo adapting to the white space surrounding a piece of artwork shown in its original proportions.

    As we already pointed out, it might be exactly this dialogue with the European ‘other’ that enables the Whitney to continuously define and re-define its American identity. We believe that, within the redrawn version of Neue Haas Grotesk, one can find a somewhat similar tension between the ‘Old’ and the ‘New World’: an European typeface, reinterpreted by a young American designer, originally commissioned by an English client.

    Added to that, we think that the redrawn Neue Haas Grotesk is a very ‘New York’ typeface, and we’re not only saying that because the designer is living and working in the city. In our view, NHG has a sharpness that is typical for NYC. On the one hand, it is quite similar to Akzidenz Grotesk, and other iconic sans serif typefaces, as employed by typical public institutes such as the NY Subway; on the other hand, we believe NHG possesses the minimalist boldness that one associates with No Wave, Conceptual Art, New York Punk, the downtown loft scene of the ’70s, and other subcultural phenomena. In that sense, and as paradoxical as it may sound, we believe that NHG refers to both ‘poles’ of New York: the established institutional sphere, and the underground tradition.
    Experimental Jetset case study

    All product shots below by Jens Mortensen, cropped to show materials bigger.

    Whitney Logo and Identity

    Stationery.

    Whitney Logo and Identity

    Visitor’s guide.

    Whitney Logo and Identity

    Materials for the Membership department.

    Whitney Logo and Identity

    Admission tickets.

    Whitney Logo and Identity

    Pins.

    Whitney Logo and Identity

    Kids’ materials for the Education department.

    Whitney Logo and Identity

    Puzzle for the retail store.

    Whitney Logo and Identity

    Totebags.

    Whitney Logo and Identity

    Shopping bags. This is what did it for me. They kick ass.

    I purposely put my review at the end of this long scrolling of work because this is an identity that definitely needs to be absorbed in full and as a system, because its individual parts may not seem as strong or that very interesting on their own, starting with the logo. At first glance, and specially in comparison to the previous bold wordmark designed by Pentagram’s Abbott Miller, the new logo feels fickle, almost imperceptible and invisible, and, in a standalone application, kind of boring. But as the “W” becomes alive, adapting to its context and changing without much consideration for the proper drawing of a “W”, it becomes highly engaging, dynamic, and anything but boring. I actually think this is one of the best logos — even outside of its application — we’ve seen all year: it goes against conventions, it is perfect for the client and its audience, and it serves as a solid system for the Whitney’s design staff to build on their own. I may also be reacting positively to it because it reminds me a lot of our identity for this year’s Brand New Conference — if I were a douchebag I would claim they stole my idea. (Kidding of course, at ease).

    In application, the logo adapts wonderfully to anything and everything, creating a sophisticated, edgy look that fits the museum perfectly. I obviously wish the identity used something other than the rich man’s Helvetica — Christian Schwartz’s Neue Haas Grotesk (which we also used on the BNConf identity, except it was done ironically) — as it makes the identity feel like something we’ve seen a hundred times before, especially coming from the Helvetica-loving folks at Experimental Jetset.

    Nonetheless, definitely one of the best museum identities in some time — specially within, or perhaps despite, the trend of black-on-white, minimalist museum identities

     


  • Elven iPhone App UI Kit

    thumb

    Description & details

    Elven App UI Kit contains all the basic elements you need to create your awesome app.  This template is optimized for iPhone 5 Retina display. All elements are build with vector shapes and layer styles, so it will scale perfectly @2x. The photos used for presentation are not included in the Download.

    Format: Layered PSD
    Vector Shapes: Yes
    Dimensions: 640×1136 px (iPhone 5)
    Minimum Photoshop Version: CS5
    Size: 4.6 Mb

    iphone5 UI design

Back to top