• Home
  • Quick Start
    • Configurator
    • Download YUI 3
  • Documentation
    • User Guides
    • Examples
    • Tutorials
    • API Docs
  • Community
    • Gallery
    • Blog
    • Forums
    • YUI Theater
    • Calendar
  • Contribute
    • YUI on GitHub »
    • File a Ticket
    • View Tickets
    • Dashboard
  • Other Projects
    • YUI 2
    • YUI Compressor
    • YUI Doc »
    • YUI Builder
    • YUI PHP Loader
    • YUI Test
    • YUI Website

Blog: Archive for May, 2010

« Older Entries

An Introduction to Using YUI 3 in Offline Applications

About the author: Alex Kessinger works as a front-end engineer at Yahoo! Past working as a front-end, he enjoys working on the entire stack. He also spends a lot of time reading, curating, and writing about the internet, social media, and building websites. You can find all of it at his website alexkessinger.net. You can also find him on twitter @voidfiles.

I could say that HTML5 is building steam, but that time is passed: HTML5 is here. Mobile is already huge, WebKit is growing rapidly, and the number of people who will have an HTML5-capable browser on their phone and/or laptop over the next few years will create a “new normal” in which HTML5 capabilities are the standard.

One of the awesome features in HTML5 is the Application Cache, which gives websites the ability to tell the browser which files to cache and to use the cached files when the browser doesn’t have a network connection. You can use the Application Cache to ensure that a user will be able to access at least part of your app while he is offline. In the case of devices like phones or tablets (or even old-fashioned devices like laptops), this could mean that your users are able to use your app while on an airplane. Meanwhile, you get to continue building your app with web technologies rather than learning Objective-C.

Besides the Application Cache, there are also other APIs available in HTML5 that give web developers the tools to create useful offline experiences. There are two persistent storage APIs available in most newer browsers. One is a simple key/value data store, called localStorage. The second is a SQL database. Both can be leveraged while the user is offline.

With these concepts in mind, I’m going to explore the evergreen “To Do list” application, using it as a springboard to look at how we can leverage the Application Cache and persistent storage in an app that builds upon everything we love about YUI 3, including the YUI 3 Gallery.

Markup

Markup is always a great place to start when building anything related to the web. The basic shell of our HTML5 page:

<!DOCTYPE HTML>
<html
<head>
    <title>YUI ToDo</title>
    <link rel="stylesheet" href="base.css" type="text/css" media="screen" title="no title" charset="utf-8">
</head>
<body class="yui-skin-sam">
    <script src="yui-min.js"></script>
    <script src="base.js"></script>
</body>
</html>

Although we’re building an offline-ready application, follow best practice but putting CSS in the head, and Javascript just before the closing body tag. Even if your page is going to be available offline, the initial page load should be responsive. (Note that we’re using the awesomely simple HTML5 doctype here.)

The app needs some placeholder markup:

<!DOCTYPE HTML>
<html>
<head>
   <title>YUI ToDo</title>
   <link rel="stylesheet" href="base.css" type="text/css" media="screen" title="no title" charset="utf-8">
</head>
<body class="yui-skin-sam">
    <div id="doc3">
        <div class="hd">
            <h1>ToDo App</h1>
            <a class="callout" href="http://alexkessinger.net" target="_blank">by Alex Kessinger</a>
            <div class="item_entry">
                <form class="entry_form">
                    <input type="text" name="todo_item_input" class="todo_item_input">
                    <p class="toRight"><a class="addItem" href="#add">Add</a></p>
                </form>
            </div>
        </div>
        <div class="bd">   
            <div class="yui-main">
                <div class="yui-b">
                    <div class="todo_items">
                        <h2>Todo Items</h2>
                        <ul>
                            <li class="no_items">Fetching ToDo Items ...</li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
        <div id="debug"></div>
        <!-- Initialization process //-->
        <script src="yui-min.js"></script>
        <script src="base.js"></script>
    </div>
</body>
</html>

This will let the user know we’re planning on getting some data for them when they first load the app. It also sets up our stage, a DOM structure for our Javascript to start working with.

A Note About Progressive Enhancement

There is no reason that an application can’t be built with principles of progressive enhancement and still made available for offline use. In this exploration, I’m omitting the additional complexity that would be involved in PE in order to focus as much as possible on the techniques required for offline support. Some might criticize that approach, and I’m sympathetic to that argument.

Additional Properties for Handling mobile devices

iPhoneOS and Android browsers can handle most webpages without any special attention, but when dealing with mobile devices it’s worth investigating how the content gets squeezed to fit on the smaller screen. Quirksmode has not one but two in-depth articles on viewport that are well worth your time.

Briefly, there is a meta tag, called viewport. It looks something like this:

<meta name="viewport" value="">

The goal of the viewport tag is to help mobile browsers figure out how to display a really big webpage on a small screen. Mobile devices need help because most devices try to squeeze 700-1100px of content onto a 300-500px screen. Also, when we set our widths at 100%, the browser takes its best guess at how big the webpage should be, and then scales it from that big to fit inside the size of the device.

To help we could set the viewport to this.

<meta name="viewport" value="width=device-width">

This will tell the device to set the width of our page to the width of the device’s screen. If we make sure our page is fluid, then our page will fill the screen on most mobile devices. This also means that if the phone has a landscape mode the page will expand to fill the extra space.

There are other things we can do to the viewport as well. If you have worked with mobile browsers, you know they allow you to zoom. If you are taking to time to build a website to fill the whole screen you may not want a user to be able to zoom. If we set our viewport to be something like the following, the user won’t be able to zoom in, or out. On a device like the iPhone this may make it feel more native. But if you do this, make sure that the content of your app gives the user no reason to ever want to zoom (e.g., small text); otherwise, this will be a frustrating usability constraint.

<meta name="viewport" value="width=device-width,user-scalable=no">

The viewport is not a W3C standard, but is a common convention. It’s currently supported by WebKit browsers on the iPhone and Android operating systems. Fennec, the Mozilla mobile browser, will probably also support this convention.

CSS

More then ever, using CSS’s ability to be fluid and dynamic is important. When looking at the broad range of phones, tablets, and other small screens, developers of applications need to be aware that our apps are going to be used on a plethora of devices. Even though there is no magic wand we can wave to make everything just work, for most applications we may not need to be pixel perfect on every device. Just following best practices can take us most of the way to support the most devices.

Starting with setting the width of our app at its base in % is a great start. Using em’s to set font-sizes is also helpful because ems are calculated based on the rendered webpage. Another thing that helps is to make sure that you base column widths on percentages as well. Even column gutters can be set in em’s.

A great place to start, without having to do a lot of work is a CSS framework. YUI 2 Grids CSS is naturally one of our favorites, and it helps us think of our page in terms of ratios instead static-width blocks.

So building off YUI 2 CSS Grids here is the starting CSS for my app.

.todo_items {
    padding-top:1em;
}
 
.todo_items ul{
    padding:0;
    margin:0;
}
.todo_items ul li {
    margin:.125em 0 .5em 0;
    padding:.125em 0 0 0;
    border-top:1px solid #ccc;
    list-style:none;
    display:block;
    word-wrap: break-word;
    text-wrap: suppress;
}
 
.toRight{
     text-align:right;
}
 
.yui3-console {
     text-align:left;
     margin-left:10px;
}
 
body h1 {font-size:200%;}
body h2 {font-size:150%;}

Javascript

Next up for our offline to-do application is the JavaScript. First download yui_min.js to your document root, and add it to the markup like we have above. Then put this in your base.js file:

YUI().use('node', function (Y) {
    Y.one(".todo_items h2").setContent("I am flying");
});

Besides Node, I am also going to include the YUI 3 CSS Reset and YUI 2 CSS Grids. I’m going to include a module from the YUI 3 Gallery, Ryan Grove’s excellent Storage Lite, that will wrap all the possible local data storage methods in to one easy-to-use API.

YUI().use('cssreset','yui2-grids','gallery-storage-lite','node', function (Y) {

  // TO-DO LIST APPLICATION CODE

});

Note: I’m not going to dive into the to-do list code, nor into some of the techniques I’d use to make it easier to debug this sort of project on mobile devices. You can find all of that on github: yui3-todo. Inside base.js you’ll find the entirety of the app. You can also see the app up and running at http://html5.alexkessinger.net/yui/ytodo/. Here, I’m going to focus on the steps necessary to enhance this simple app with offline capabilities.

Cache Manifest

The first step to taking a web app offline is the Application Cache. The Application Cache can tell your browser what files you want to download and keep offline. In this example, I know I want to keep my JavaScript and my CSS offline, as well as the main HTML page for the app. With that in mind, my cache manifest will look like this:

CACHE MANIFEST
 
index.html
base.css
yui_min.js
base.js

Some things to note about the cache manifest.

  • It must start with the line CACHE MANIFEST.
  • You must serve it with a Content-Type header of text/cache-manifest

If you are on Apache, you can add the following snippet to .htaccess to get the right content type.

AddType text/cache-manifest .manifest

With that in place, any file with a .manifest suffix will be served with the text/cache-manifest Content-Type header.

Next we need to inform the browser of the cache manifest, to do that we add an attribute to our HTML tag:

<html manifest="todo.manifest">

Now if you go to your page in a browser that supports offline apps you will probably see a notification stating that this webpage is requesting offline access.

Offline / Online

With the manifest in place telling our browser what resources to cache, we’re ready to think about what happens in online mode versus offline mode. There are now two “boot sequences,” the first being the full online sequence that we already have (and during which resources are cached for offline use). This online sequence uses the Yahoo CDN to load the files, and the files are combo-handled so we have only a few HTTP requests.

But we are also building an offline boot procedure. We need to be able to detect the fact that the browser is offline and then initialize YUI properly to draw from cached resources.

var online = (navigator.onLine) ? true : false;

Now, we just need to choose a configuration object based on being offline, or online.

var YUI_ONLINE_CONF = {},
    YUI_OFFLINE_CONF = {
        base: "yui3/build/",
        combine:0,
        groups: {
            gallery: {
                base:'yui3-gallery/build/',
                patterns:  { 'gallery-': {} }
            },
            yui2: {
                base: '2in3/dist/2.8.0/build/',
                patterns:  { 
                    'yui2-': {
                        configFn: function(me) {
                            if(/-skin|reset|fonts|grids|base/.test(me.name)) {
                                me.type = 'css';
                                me.path = me.path.replace(/\.js/, '.css');
                                me.path = me.path.replace(/\/yui2-skin/, '/assets/skins/sam/yui2-skin');
                            }
                        }
                    } 
                }
            }
        }
     },
     ONLINE = (navigator.online) ? true : false; 
     CURRENT_CONF = (ONLINE) ? YUI_ONLINE_CONF : YUI_OFFLINE_CONF;
 
YUI(CURRENT_CONF).use('cssreset','yui2-grids','gallery-storage-lite','node', function (Y) {
    ...
});

The YUI_OFFLINE_CONF configuration might need some explanation. First, I am changing the base to my document root + yui3/build/. I have posted the full distribution of YUI 3 to my server because the W3C spec states that the offline cache has a strict single origin policy. All cached resources must come from the same domain as does the manifest. As a result, I can’t rely on Yahoo! or Google or any other CDN to serve my files — all of them must be available for caching from my server.

The next part, combine:0, tells the YUI loader to not automatically combo the files, because I don’t have a combo-handler installed on my own server.

Finally, I want to mention the groups config. Groups is a new feature in YUI 3.1.1 that allows you define whole groups of files that come from the same place. You can also configure them to be combo’d from the source. I set up the YUI 3 Gallery here to load from a local copy I have of the yui3-gallery repository on GitHub.

When we are online, we can bootstrap from the Yahoo CDN, but offline we need to have local copies of the files. This is easy to do. You can either download the files needs in a big zip file to your directory:

cd docroot;
wget http://yuilibrary.com/downloads/yui3/yui_3.1.0.zip;
unzip yui_3.1.0.zip;
mv yui yui3;
wget http://download.github.com/yui-yui3-gallery-gallery-2010.05.19-19-08-0-g2a49f06.zip;
unzip yui-yui3-gallery-gallery-2010.05.19-19-08-0-g2a49f06.zip;
mv yui-yui3-gallery-2a49f06 yui3-gallery;
wget http://download.github.com/yui-2in3-yui-2in3.3-0-gdf09025.zip;
mv yui-2in3-yui-2in3.3-0-gdf09025 2in3;

Or you can clone the git repositories from github directly if git is installed on your machine:

cd docroot;
git clone git://github.com/yui/yui3.git yui3;
git clone git://github.com/yui/yui3-gallery.git yui3-gallery;
git clone git://github.com/yui/2in3.git 2in3;

For testing purposes. I will sometimes set ONLINE = false and check how my site loads. If you do that, and then visit your app in a normal browser, you can see each file that needs to be included individually. To properly fill out our cache manifest, you need to take note of each file being pulled in, using something like Firebug. Then in your cache manifest you will list each file one by one. It will look something like this.

CACHE MANIFEST
# A comment
index.html
base.css
base.js
yui-min.js
yui3/build/loader/loader-min.js
yui3/build/widget/assets/skins/sam/widget.css
yui3/build/console/assets/skins/sam/console.css
yui3/build/oop/oop-min.js
yui3/build/event-custom/event-custom-min.js
yui3/build/intl/intl-min.js
yui3/build/console/lang/console.js
yui3/build/attribute/attribute-min.js
yui3/build/event/event-base-min.js
yui3/build/pluginhost/pluginhost-min.js
yui3/build/dom/dom-min.js
yui3/build/node/node-min.js
yui3/build/event/event-delegate-min.js
yui3/build/event/event-focus-min.js
yui3/build/base/base-min.js
yui3/build/classnamemanager/classnamemanager-min.js
yui3/build/widget/widget-min.js
yui3/build/substitute/substitute-min.js
yui3/build/console/console-min.js
yui3/build/cssreset/reset-min.css
2in3/dist/2.8.0/build/yui2-grids/yui2-grids-min.css
yui3-gallery/build/gallery-storage-lite/gallery-storage-lite-min.js
yui3/build/json/json-min.js
startup.png
icon.png

At this point we can go all the way offline. If you have an iPhoneOS or Android device (or any HTML5-capable browser) you can now visit your webpage, let it finish loading, and then reload the page with the device’s internet access disabled.

iPhone-Specific Goodies

The iPhone affords the WebApp developer the ability to give your app some space on the home screen just like all other apps. You can even have a glossy icon and startup screen as you’d have with a “native” application. First, you need to follow the specs for the icon and startup screen. And then you can add the following meta tags:

<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="white" />
<link rel="apple-touch-icon" href="icon.png"/>
<link rel="apple-touch-startup-image" href="startup.png" />

The first two tags tell mobile Safari that your web page is a HTML5 WebApp and that you wan the color of the status bar at the top to be white. This will also remove all the navigation chrome around browser window. The second two tags point to the files you want to use for your icon and startup screen.

What’s Next

The HTML5 spec is still a moving target. Keep an eye out for new developments. That said, even today there are fantastic new capabilities in modern browsers. As you can see from this tutorial, it’s not hard to take a web application offline, dramatically increasing it’s potential usefulness. And, when you go offline, don’t hesitate to take YUI 3 with you, along with all the power you’re accustomed to from the YUI 3 Gallery and the YUI 2 widget family.

By Alexander KessingerMay 27th, 2010

Work with YUI as part of the Yahoo! Open Strategy (YOS) Engineering Team

The Yahoo! Open Strategy (YOS) Team is building the next generation of open platforms. One of our upcoming products – Connect – is targeted at third-party publishers and developers. Connect allows third-parties to easily integrate with Yahoo! by dropping a few lines of Javascript code on their site. Further, Connect enables users to login to third-party websites using their Yahoo! IDs and broadcast their updates to friends and followers.

Connect uses several Yahoo technologies including YQL and YUI. In particular, Connect leverages the core libraries from YUI3 (node, io, custom events) and the widget infrastructure to provide a consistent api and cross-browser experience. Once fully developed, Connect will be deployed across thousands of web-sites and be visible to millions of consumers. This is an exciting opportunity to be involved with a project that will have outstanding consumer reach and challenging scalability requirements.

The ideal candidate will have 5+ years of large-scale web development experience, including familiarity with browser-side client technologies such as Javascript, HTML and CSS and with cross-browser compatibility issues, optimization techniques, and internationalization. Knowledge of PHP and a JavaScript library — such as YUI — are required.

Interested? See the full job description at http://careers.yahoo.com/jdescription.php?oid=29752 and contact Rohit Dube (rdube AT yahoo-inc.com).

By Rohit DubeMay 20th, 2010

YUI Theater — Ryan Dahl: “Introduction to NodeJS” (58 min.)

Ryan Dahl's Talk at the BayJax event at Yahoo! on May 5th, 2010.

Two weeks ago, Yahoo! hosted a BayJax meetup dedicated to NodeJS (since the meetup coincided with Cinco de Mayo, we named it ‘Cinco de Node’). Ryan Dahl, the creator of NodeJS, gave a talk on the project and was very kind to let us record his presentation for YUI Theater.

P.S. The video opens with a 30-second glimpse into the Cinco the Mayo celebrations at Yahoo!

If the video embed below doesn’t show up correctly in your RSS reader of choice, be sure to click through to watch the high-resolution version of the video on YUI Theater.

  • Download HD video (480p ~767MB)
  • Download video (m4v)

Other Recent YUI Theater Videos:

  • Elijah Insua: jsdom: a CommonJS Implementation of the DOM — Elijah Insua introduces a server-side implementation of the JavaScript DOM at the May 2010 BayJax meetup at Yahoo.
  • Nicholas Zakas, Stoyan Stefanov, Ross Harmes, Julien Lecomte, Matt Sweeney: High Performance JavaScript — Five contributors to O’Reilly’s High Performance JavaScript discuss advanced JavaScript and DOM scripting optimizations at the April 2010 BayJax meetup at Yahoo.
  • Douglas Crockford: The State and Future of JavaScript — Yahoo! JavaScript Architect Douglas Crockford discusses the recent ECMA5 development process and efforts to improve the language in the future.
  • Dav Glass: Contributing to YUI — YUI engineer Dav Glass introduces you to the YUI Gallery and steps through the process of making contributions to the YUI project.
By Allen RabinovichMay 20th, 2010

YUI Theater — Elijah Insua: “jsdom: a CommonJS Implementation of the DOM” (18 min.)

Elijah Insua's Talk at the BayJax event at Yahoo! on May 5th, 2010.

Elijah Insua, a star developer from Arc90, presented his work on jsdom at the Cinco de Node BayJax event at Yahoo!. Elijah was presenting from Brooklyn via Skype (so please forgive the less-than-ideal video and audio quality), and graciously allowed us to capture his talk for YUI Theater.

If the video embed below doesn’t show up correctly in your RSS reader of choice, be sure to click through to watch the high-resolution version of the video on YUI Theater.

  • Download HD video (480p ~243MB)
  • Download video (m4v)

Other Recent YUI Theater Videos:

  • Ryan Dahl: Introduction to NodeJS — Ryan Dahl, the creator of NodeJS, introduces the project and talks about performance improvements and new architecture. The talk took place at the May 2010 BayJax meetup at Yahoo.
  • Nicholas Zakas, Stoyan Stefanov, Ross Harmes, Julien Lecomte, Matt Sweeney: High Performance JavaScript — Five contributors to O’Reilly’s High Performance JavaScript discuss advanced JavaScript and DOM scripting optimizations at the April 2010 BayJax meetup at Yahoo.
  • Christian Heilmann: YQL and YUI: Building Blocks for Quick Applications — The Yahoo! Developer Network’s international evangelist Christian Heilmann discusses his philosophy for creating fast, powerful, compelling applications using the Yahoo Query Language (YQL) and the Yahoo User Interface Library (YUI).
  • Luke Smith: Events Evolved — YUI engineer Luke Smith provides a deep introduction to the YUI 3 event system including its support for DOM events, event delegation, synthetic events, and custom events.
By Allen RabinovichMay 20th, 2010

Implementation Focus: Phanfare Media Organizer

Cory Mintz from Phanfare wrote in last week to tell us about their recent product launch, which is heavily based on YUI 2.8.0.

We just released our new web organizer yesterday… It is a full photo and video organizer built as a web application, using just about every YUI 2 component. We think it really blurs the line between desktop and web software.

Some notable features are:

  • Using the Uploader, we let people organize and edit their photos as they upload.
  • With the help of Drag and Drop and Menu, the thumbnail grid has all of the behaviors of an OS’s file browser. You can drag select, drag and drop reorder, multi-select using ctrl and shift, arrow between thumbnails, etc.
  • The dynamic loading of the TreeView, let us lazy load user accounts with 100s of albums since they are hierarchical ( year -> album -> section ). This allows the page for an extremely large account to load just as fast as a small account.

I love the clean professionalism of the site and the extraordinary attention to detail in the UI. Feel free to tour the site — trial accounts are free and come populated with sample albums to give you a feel for what the site has to offer. Congratulations to Cory and the team for such a fantastic launch.

By Eric MiragliaMay 19th, 2010

CSS 101: Block Formatting Contexts

About the author: Thierry Koblentz is a front-end engineer at Yahoo!
He owns TJK Design, ez-css.org and css-101.org. You can follow Thierry on Twitter at @thierrykoblentz.

A block formatting context is a box that satisfies at least one of the following:

  • the value of “float” is not “none”,
  • the used value of “overflow” is not “visible”,
  • the value of “display” is “table-cell”, “table-caption”, or “inline-block”,
  • the value of “position” is neither “static” nor “relative”.

When it comes to the visual formatting model (this is how user agents process the document tree for visual media), block formatting contexts are big players. So it is crucial for CSS authors to have a solid understanding of their relationship with the flow, floats, clear, and margins.

What does the spec say about…

How block formatting contexts flow

The positioning scheme to which block formatting contexts belong is normal flow. Therefore, the “block” of a block formatting context is positioned in the flow of the page as you’d expect with block boxes, inline formatting of inline boxes, relative positioning of block or inline boxes, and positioning of run-in boxes. Simply put, they are part of the page flow.

What triggers block formatting contexts

Section 9.4.1 says that the following will establish new block formatting contexts:

  • floats,
  • absolutely positioned elements,
  • inline-blocks,
  • table-cells,
  • table-captions,
  • elements styled with “overflow” (any value other than “visible”)

But according to the CSS level 3 specification, a block formatting context (a “flow root” in CSS3 speak) is created when the following condition is met:

  • The value of ” position” is neither “static” nor “relative” (see [CSS3POS]).

This definition means that position:fixed establishes a new block formatting context, too. This is not a miss in section 9.4.1, though; fixed positioning is a subcategory of absolute positioning (9.6.1) and references in the specification to an absolutely positioned element (or its box) imply that the element’s ” position” property has the value “absolute” or “fixed” .

Note that display:table does not establish block formatting contexts per se. But because it can generate anonymous boxes, one of them (with display:table-cell) establishes a new block formatting context. In other words, the trigger is the anonymous box, not display:table. This is something authors should keep in mind, because even if both styles establish new block formatting contexts (implicitly or explicitly), clear does not work the same with display:table as it does with display:table-cell.

A final trigger is the fieldset element. Oddly enough, there was no information on www.w3.org about this behavior until the HTML5 specification. There were browser bugs ( Webkit, Mozilla) that mentioned this, but nothing “official”. Actually, even if fieldsets establish new block formatting contexts in most browsers, as per section 3.2 (UA conformance), authors were not supposed to take this for granted:

CSS 2.1 does not define which properties apply to form controls and frames, or how CSS can be used to style them. User agents may apply CSS properties to these elements. Authors are recommended to treat such support as experimental. A future level of CSS may specify this further.

What block formatting contexts do

Block formatting contexts contain floats because of the way they flow, and per section 9.4.1, they prevent collapsing margins and do not overlap floats:

In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is determined by the “margin” properties. Vertical margins between adjacent block boxes in a block formatting context collapse.

In a block formatting context, each box’s left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the presence of floats (although a box’s line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may become narrower due to the floats).

Enough with the specs, what does this mean in the real world?

Block formatting contexts behave more or less like any block box, apart from these important exceptions:

  • Block formatting contexts prevent margin collapsing

    Vertical margins between adjacent block boxes collapse, but only if they are in the same block formatting context. In other words, if the adjacent boxes do not belong to the same block formatting context, their margin will not collapse.

    Example:

    This is a paragraph inside a DIV with a blue background, styled with margin:20px.

    This is a paragraph inside a DIV with a blue background, styled with margin:20px.

    This is a paragraph inside a DIV with a blue background, it is styled with margin:20px, The parent DIV is styled with overflow:hidden;zoom:1.

    Between the two first blue boxes above, the bottom and top margin of the paragraphs collapse (the gap equals 20 pixels, not 40 pixels), but because the last DIV creates a new block formatting context, the margins of the third paragraph do not collapse, hence they do not “stick out” of the paragraph’s container but instead are part of that block box.

    Note: in IE6, without explicit margins the DIV would fail to enclose the margins.

    When it comes to collapsing margins, creating a new block formatting context acts the same as applying border or padding to the element.

  • Block formatting contexts contain floats

    I am sure you have heard of the sentence ” a float always contains floats “, or maybe heard of the FNE ( float nearly everything) method. But the basis of this is that floats are block formatting contexts, so a better way to formulate this is to say that ” a block formatting context always contains floats “.

    Example:

    This paragraph is a float inside a DIV with a blue background, it is styled with margin:20px

    This paragraph is a float inside a DIV with a blue background, it is styled with margin:20px. The parent DIV is styled with overflow:hidden;zoom:1.

    The first paragraph is a float so it is removed from the flow and its container collapses, hence the background of this container does not show.

    The second paragraph is also a float, but it is contained inside a DIV that creates a new block formatting context, hence that container encloses the child’s “margin box”. You should also note that, unlike with the first paragraph, there is no need to clear the previous box. This is often referred to as “self-clearing”, which makes lot of sense considering that block formatting contexts are a normal part of the flow.

    Note: clear only clears floats within the same block formatting context.

  • Block formatting contexts do not overlap floats

    This one is my favorite. According to the spec, the border-box of a block formatting context must not overlap the margin-box of floats in the same block formatting context as the element itself. What this means is that browsers create implicit margins on block formatting contexts to prevent them from overlapping the margin-box of floats. For this very reason, negative margins should have no effect when applied to a block formatting context next to floats (WebKit and IE6 have a problem with this though – see test case).

    Example:

    .sideBar { background: skyBlue; float: left; width: 180px; }

    .sideBar { background: yellow; float: right; width: 180px; }

    #main { background: pink; overflow: hidden; zoom: 1; border: 5px solid teal; } 

    Because this behavior is attached to the “border box” (not the “margin box”), to create space (e.g., a 20px gap) between the pink box and its siblings, authors would need to either:

    • Set a 20px margin on the floats
    • Set margin values on the pink box greater than the width of the floats (i.e., margin:0 220px)

    Yes, you’d use 220px, not 20px. Because it is the border-box that tries to fit between the floats, not the margin-box. And if I say it tries it is because that container would drop if there was not enough room for it between the two floats.

    In other words, if the pink box was given a 400 pixels width, that box should drop when the parent container is narrower than 770 pixels (180px + 180px + 400px + 10px). As a side note, in a few instances, this behavior appears to be broken in Firefox (at least in v.3.5.9) (i.e., when the above construct is the first child of body – see test case).

    Note: the space that shows in IE6 between the pink box and the two floats is due to the three pixel jog bug.

hasLayout versus block formatting context

As you may have noticed, all previous examples are styled using overflow:hidden;zoom:1. The former declaration establishes a new block formatting context in modern browsers while the latter triggers hasLayout in Internet Explorer (IE 5.5/6/7). This is because these renderings are very close ( similarities with the CSS specs). Like block formatting contexts, elements that are given a layout appear to prevent collapsing margins, to contain floats, and to not overlap floats.

Properties/declarations that give elements a layout

The lists below show that the properties that establish a new block formatting context also trigger hasLayout, at least the ones supported by the browser, with the exception of overflow in IE < 7.

In Internet Explorer 5 and 6
position:absolute
position:fixed
float (any value other than ” none“)
display:inline-block
width (any value other than ” auto“)
height (any value other than ” auto“)
zoom (any value other than ” normal“)
writing-mode:tb-rl
-ms-writing-mode:tb-rl
In Internet Explorer 7
min-width (any value)
min-height (any value)
max-width (any value other than none)
max-height (any value other than none)
elements styled with overflow (any value other than visible)
overflow-x and overflow-y (any value other than visible)
Things to consider
  • zoom and writing-mode are proprietary properties and do not validate.
  • IE 5.0 does not support zoom
  • width and height trigger hasLayout on inline elements only when these properties apply to these elements (i.e., IE6 in quirks mode).
  • overflow-x and overflow-y are part of the CSS3 box model module
  • hasLayout is also triggered when the layout-flow is different from the parent layout flow (i.e., rtl to ltr)

In Quirks Mode and IE7 Mode (All Versions)

  • When overflow is set to something other than visible, table-cell elements *do not * establish new block formatting contexts.
  • When overflow is set to visible, table-cell elements *establish * a new block formatting context.

HTML elements that always have a layout:

In Internet Explorer, these elements have – *by default * – a layout. * <body> (as well as <html> in Strict mode) * <table>, <tr>, <th>, <td> * <img> * <hr> * <input>, <button>, <select>, <textarea>, <fieldset>, <legend> * <iframe>, <embed>, <object>, <applet> * <marquee>

Wrap up

To reduce the risk of issues between modern browsers and Internet Explorer ( < 8), authors may choose to give a layout to boxes that establish new block formatting contexts. This way the flow is identical, elements escape floats the same way, clear clears the same floats, and margins collapse where expected. Also, authors must pay attention when styling boxes using hasLayout triggers (i.e., width) as such styling may require making that element a new block formatting context as well.

Further readings

Implications

  • Page breaks and block-formatting contexts: Allowed page breaks (13.3.3).
  • Clearfix and block formatting contexts: Everything you Know about Clearfix is Wrong

Demos and testcases

  • Block formating contexts, “hasLayout” – IE Window vs CSS2.1 browsers: simulations.
  • New block formatting contexts next to floats

hasLayout articles

  • On having layout
  • “HasLayout” Overview
  • hasLayout Property

Special thanks to Philippe Wittenbergh and Bruno Fassino for finding spec references when one needs them and to Ingo Chao for giving us the best resource on having layout.

By Thierry KoblentzMay 19th, 2010

YUI: Open Hours, Fri May 21st

It’s a new week, and time for another YUI: Open Hours!

This week, we’ll be joined by the inimitable Dav Glass, author of (among other things) YUI’s Rich Text Editor and Drag and Drop utility, and the primary architect behind yuilibrary.com and the Gallery itself. He’ll be discussing the YUI 3 Gallery project — where it’s going, how to contribute — and answer any questions about it, about the site, or really about anything else while we have him on the line.

After that, we’ll jump into our main event, which will be a “Gallery widget sampler”. We have a number of module authors joining us this week, including

  • Iliyan Peychev (Accordion)
  • Andrew Bialecki (Lightbox)
  • Matt Snider (Radial Menu)
  • Jacob Fogg (Sliding Sidebar)
  • and hopefully more

They’ll introduce their module, give an example or two, go over their API, and discuss their experience creating it. Besides just being a nice introduction to additional components available to YUI 3 users, it should provide a good platform to talk about widget API best practices and help give a sense of some of the decisions that are made during widget creation.

Thanks again to Caridy Patiño for joining us last week and reviewing his Accordion Node plugin and Dispatcher modules. We’ll have more topics in the future about creating Node plugins and the reasons why the plugin approach or the widget approach might be a better fit for your needs. And thanks to Matt Sweeney (author of YUI’s Node class and selector engine) for dropping in as a surprise guest as well.

The time will be the same as before, 10am – 12pm PDT and the connection details are also the same:

  1. Dial in to 1-888-371-8922 (non-US participants, email me for a local number)
  2. Enter the attendee code 4718 8953#
  3. Join the screen sharing session (this will prompt you to install the Adobe Connect plugin if this is your first time using it)

And as always, you can keep up to date with the upcoming schedule and topics by following @yuilibrary on Twitter or subscribing to the YUI Event Calendar.

Hope to see you there!

By Luke SmithMay 19th, 2010
« Older Entries

Pages

  • About
  • Contribute
  • YUI Jobs

Recent Posts

  • YUI Weekly for May 17th, 2013
  • Yahoo’s International Team Is Hiring!
  • YUICompressor 2.4.8 Released
  • YUI 3.10.1 Released to Fix SWF Vulnerability
  • YUI Weekly for May 10th, 2013

Archives

Categories

  • Accessibility (25)
  • CSS 101 (6)
  • Design (51)
  • Development (590)
  • Frontend Jobs at Yahoo (13)
  • Graded Browser Support (8)
  • In the Wild (63)
  • Miscellany (11)
  • Open Hours (44)
  • Performance (23)
  • Releases (25)
  • Target Environments (11)
  • Yeti (3)
  • YUI 3 Gallery (29)
  • YUI Events (45)
  • YUI Implementations (55)
  • YUI Theater (146)
  • YUI Weekly (37)

Meta

  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org
© 2013 YUI Blog