codefoster | All posts tagged 'flexbox'
Jeremy Foster
@codefoster

The Flexbox CSS Standard

by Jeremy Foster 12. November 2012 12:40

 

Question: what is Microsoft's position on Flexbox and fallbacks for IE10 and legacy?

While I'm not the official voice of Microsoft and am not the smartest Softie in Redmond when it comes to the web standards, I'll attempt to answer this question anyway.

The official standard for the flexbox style in CSS is documented in exhaustive detail at W3C. The abstract of this implement is helpful stating that the flexbox is

"…a CSS box model optimized for user interface design. In the flex layout model, the children of a flex container can be laid out in any direction, and can "flex" their sizes, either growing to fill unused space or shrinking to avoid overflowing the parent. Both horizontal and vertical alignment of the children can be easily manipulated. Nesting of these boxes (horizontal inside vertical, or vertical inside horizontal) can be used to build layouts in two dimensions."

I think the official answer is that Microsoft doesn't have an official position on falling back from flexbox. The -ms-flexbox is an implementation by the Trident engine to the flexbox… end of story. You will, however, find some recommended strategies on the web, and the best I've run into so far is the use of inline-block for unsupporting browsers.

That said, I'm spending most of my time with Windows 8 apps these days am thus spared the pain (the ever building pain that has yet to reach a crescendo) of writing 12 lines of code to accommodate the various HTML/CSS engines. If I was doing web development for the masses, I think I would decide to avoid the use of flexboxes altogether to ease my pain. I'm not sure what's worse - an old, hacky solution or multiple solutions to maintain (one of which is still old and hacky).

 

    

Tags: , , , , , , , ,

CSS | HTML | Windows 8 | IE10

Data Presentation

by Jeremy Foster 14. September 2012 18:26

Sometimes it’s hard to know what control to use when you’re thinking about bringing your data feed into your Windows 8 app. You know you want to bring them in as tiles of some form or another. Maybe you want to do classic square tiles like eBay.

Screenshot (29)

Hopefully, though, you want to add a little bit of flare and personality to yours. You could do something like the Cookbook app. Their primary data point is obviously a recipe and it looks to me like the designers of this app have put them in little Polaroids with shadows and everything.

Screenshot (36)

You could copy the music app that utilizes hero images – larger than average images that communicate a sense of feature or significance. <disclaimer>Please ignore that Justin Bieber appears to be in my now playing section. I can assure you that’s not the case</disclaimer>

Screenshot (27)

You could even get trés chic and model Cocktail Flow with their novel, beautiful tiles. They hardly look like tiles, but they still convey that essential Windows 8 design.

Screenshot (34)

Inevitably, you’re going to have to make a choice about what control underlies this presentation of data, and eventually you’re going to have to implement it.

In this post, I’d like to do a little bit of a study into what control to choose when and why. As usual, I’ll be coming from an HTML/JS perspective, so if you’re wondering what your options are in XAML, Bing is your friend.

The first thing I want to point out is that not all lists of data are created equal. If you’re working on a section of your hub, you’re working with a very finite set of data. On the other hand, if your user has chosen to see something like your list of all recipes, then the list could have 10’s or 100’s of items in it. The two scenarios are candidates for vastly different solutions.

For the former, the hub section, I would employ a grid like what you see in the Music app screenshot above. You know that you have exactly four cells for images (for albums in this case) and you can determine which four albums you want to show and of them which deserves the ginormous featured cell on the left. The advantage to using a grid is that you have ultimate control over its layout. You don’t have to stick to symmetric lists of square. You can get funky with the layout and you can change it up too. You can create one layout for features a single item and another for featuring three. It’s all up to you (with the permission of your designer friend of course). The downside to using a grid is that you don’t get to bind it to an enumerable list of data. That’s not much of a problem, however, because again you’re only working with a handful or so of items. Also, grids don’t have any of the UX yum built in. They don’t automatically handle selection for instance, so if you want to allow the user to swipe select multiple entities in your grid, you’re going to have to figure out how to do that.

For the latter, the recipe list like you see in the Cookbook app screenshot above, I would employ a ListView. A ListView does have the UX yum built in. It automatically handles invocation, selection, and a lot more. It flows, it pans, it groups, and it wraps. It’s really great at what it’s made for.

In other scenarios, if you’re okay with giving up the yum that a ListView provides, you might want to opt for a FlexBox. Flexboxes give you better control than a ListView over how it’s members are laid out, and nothing complicated gets rendered out for each member of the flexbox. If you just inject a bunch of divs into your flexbox then that’s all it will contain.

To avoid a merely conceptual post on a developers’ blog, allow me to create a quick, custom grid and then populate it with some content.

First, the design. Let me whip out my digitizer pen and draw up a quick grid layout using CorelDRAW (woot!)…

image

That’s the concept. Now for the implementation. I’m only going to layout the seven items in the first section.

First the HTML…

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>fancygrid</title>

    <!-- WinJS references -->
    <link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet" />
    <script src="//Microsoft.WinJS.1.0/js/base.js"></script>
    <script src="//Microsoft.WinJS.1.0/js/ui.js"></script>

    <link href="fancygrid.css" rel="stylesheet" />
    <script src="fancygrid.js"></script>
</head>
<body>
    <div class="fancygrid fragment">
        <header aria-label="Header content" role="banner">
            <button class="win-backbutton" aria-label="Back" disabled type="button"></button>
            <h1 class="titlearea win-type-ellipsis">
                <span class="pagetitle">Fancy Grid</span>
            </h1>
        </header>
        <section aria-label="Main content" role="main">
            <div id="grid">
                <div></div>
                <div></div>
                <div></div>
                <div></div>
                <div></div>
                <div></div>
                <div></div>
            </div>
        </section>
    </div>
</body>
</html>

The only thing in that HTML that isn’t boilerplate is the div called grid and the seven div’s inside. There’s one for each of the tiles in our layout. And now on to the CSS which is not a terribly lot longer…

.fancygrid section[role=main] > * {
    margin-left: 120px;
}

.fancygrid #grid {
    height:540px;
    display: -ms-grid;
    -ms-grid-columns: 240px 300px 240px;
    -ms-grid-rows: 184px 184px 184px;
}

    .fancygrid #grid > div {
        border: 1px solid white;
        margin: 5px;
    }

        .fancygrid #grid > div:nth-of-type(1) {
            -ms-grid-row: 1;
            -ms-grid-column: 1;
        }
        .fancygrid #grid > div:nth-of-type(2) {
            -ms-grid-row: 2;
            -ms-grid-column: 1;
        }
        .fancygrid #grid > div:nth-of-type(3) {
            -ms-grid-row: 3;
            -ms-grid-column: 1;
        }
        .fancygrid #grid > div:nth-of-type(4) {
            -ms-grid-row: 1;
            -ms-grid-column: 2;
            -ms-grid-row-span: 3;
        }
        .fancygrid #grid > div:nth-of-type(5) {
            -ms-grid-row: 1;
            -ms-grid-column: 3;
        }
        .fancygrid #grid > div:nth-of-type(6) {
            -ms-grid-row: 2;
            -ms-grid-column: 3;
        }
        .fancygrid #grid > div:nth-of-type(7) {
            -ms-grid-row: 3;
            -ms-grid-column: 3;
        }

Great. No JavaScript. As it should be. This is just a matter of layout, so it’s a collaborative effort between HTML (our structure) and CSS (our layout and style). The HTML in this case is dead simple. It’s just a div with seven div’s inside. Our CSS is like that kid in your chemistry lab in high school that did all the work for your whole lab group while you played Nintendo. Slacker.

So let me explain. The first style rule that refers to the main section is just something I do make sure everything in that main section takes on the 120px left margin that characterizes Windows 8 apps. The next rule applies to the grid. You may know by now, but the .fancygrid that preceeds #grid is just there to namespace this rule to this page. The next rule applies to all seven of the child div’s of the #grid div. The child combinator (the >) in this case is likely important. If you end up putting content inside of these cells and that content contains any div elements at all, this rule would apply to them if you used a space (the descendent combinator) instead of that greater than sign. So for all seven cells we want to draw a white border and give 5px of space. Why 5px? Because the Windows 8 design principles call for 10px between items and so that would be 5px around each item. Then I’m using the :nth-of-type() pseudo-class to refer to each div according to its position and add the correct -ms-grid properties to put it where it belongs. Notice how the 4th div has a span of 3.

And here’s the result…

Screenshot (38)

Now, if you’re like me, you see this done once and it looks fine and dandy, but your mind races to imagine the value of something like this in a library primed for reuse. It would be super easy to dynamically add div’s and a couple of CSS properties each according to the template selection chosen by the developer. I believe I’ll get started on that now. Or perhaps soon. By all means, please beat me to it.

Hope this has been helpful. Now get to work!

Tags: , , , , , , , , , , , , , , , , , , , , , ,

CSS | Design | Windows 8

When to Use ViewBoxes and FlexBoxes

by Jeremy Foster 12. June 2012 12:11

HTML and CSS is great, but there’s at least one thing that has driven web designers mad for ages - layout. We used to use tables and it worked. We knew their weaknesses, but they worked. Then we were told that tables are for tabular data and div elements are for layout, but divs are wretched creatures. To set divs next to each other one had to float them, but then when finished floating had to be explicitly turned off - argh. Also, divs had no notion of filling vertical space or of controlling the vertical placement of anything within it.

So a myriad of web designers resorted to absolute positioning, browser hacks, jQuery UI positioning, or some other means just to get things to go where they ought.

Enter Windows 8.

Windows 8 allows us to design our Metro style apps using HTML and CSS. In doing so, however, it the CSS standards and Microsoft have given us some facilities to finally place things where we want them.

It’s not obvious how everything works though so let me give you a boost. If you start with a Fixed Layout Application (for the record, I think it should be called the Flexible Layout Application) project template you get the right stuff automatically, but here’s an explanation so you have the concept as well.

We’re dealing with two entities here: the WinJS.UI.ViewBox control and the -ms-flexbox css property value (for the display property).

WinJS.UI.ViewBox

The purpose of the ViewBox is stated in the documentation. It says that it “Scales a single child element to fill the available space without resizing it. This control reacts to changes in the size of the container as well as changes in size of the child element. For example, a media query may result in a change in aspect ratio.”

The first thing I had a hard time wrapping my head around was the overlap between a ViewBox and a FlexBox. Then I discovered that there really isn’t any. The ViewBox control is quite simple. It scales the content that it contains but maintains it’s aspect ratio.

It works like this…

image

Note that it does not work like this…

image

In other words, as it says in the documentation, it scales the contents, but it keeps their proportions.

And that’s really the end of it. The ViewBox serves this one purpose.

Flexbox

Now it’s time to talk about the flexbox. This is not a WinJS control, but rather an implementation of a CSS3 property. It’s not quite a standard property yet because all of the browsers are still implementing it with vendor specific properties and values, but it’s close. For Windows 8, we specify a display property with a value of -ms-flexbox to indicate flexbox layout.

The purpose and scope of the flexbox is a bit bigger than the ViewBox. Here’s what the W3C spec for the CSS Flexible Box Layout Module says “In the flexbox layout model, the children of a flexbox can be laid out in any direction, and can "flex" their sizes, either growing to fill unused space or shrinking to avoid overflowing the parent. Both horizontal and vertical alignment of the children can be easily manipulated. Nesting of these boxes (horizontal inside vertical, or vertical inside horizontal) can be used to build layouts in two dimensions.”

So, like the ViewBox, we still have the concept of the container’s content changing in size to fit the container, but this has more to do with a collection of child items.

Additionally, the flexbox offers a lot of properties to specify how it’s children are laid out. A quick glance in Blend at the CSS properties on a div in the Flexbox category will enumerate them for you…

image

Notice first the -ms vendor specific prefix as I mentioned.

To give a thorough description of the possibilities with these properties, I’d be duplicating what’s already done quite nicely on the flexbox page on w3.org, so just go there and read the nitty, gritty detail.

Differences

The ViewBox is a WinJS control, whereas the flexbox is a CSS property.

The ViewBox always acts on a single child item, but the flexbox can act on multiple child items.

The ViewBox itself changes size to fit it’s container as a core feature. The flexbox can be told to scale to 100% either in width or height, but it doesn’t have to.

The ViewBox does not extend control over the alignment and scale modes of it’s contents, but always does the same thing - scales the child item without changing it’s proportion.

All Together Now

Now that you know how different these controls are, consider them together. If you put a flexbox div inside of a ViewBox, you get a really effective layout tool. Try this for your HTML…

<body>
    <div data-win-control="WinJS.UI.ViewBox">
        <div class="flexy">
            <div class="item">A</div>
            <div class="item">B</div>
            <div class="item">C</div>
        </div>
    </div>
</body>

With this as the CSS…

.flexy {
    -ms-flex-align: center;
    -ms-flex-direction: column;
    -ms-flex-pack: center;
    display: -ms-flexbox;
}

.item {
    height: 200px;
    width: 200px;
    border:solid 1px;
    font-size:9em;
}

What you have now is a flexbox that fills its area well. Look at these simulator screenshots so you can see what this would look like…

imageimageimageimage

XAML is unarguably the most powerful layout engine I’ve ever seen, but I really don’t feel like there’s too much in HTML/CSS that we’re missing now with additions like this. It’s rather empowering.

Happy layouts!

Tags: , , , , , , , , , ,

CSS | Windows 8

Feed Subscribe