Web Development

Optimize a CSS box model by using a flexbox layout

Read an introductory overview of the W3C's CSS Flexible Box Layout Module to discover its main advantages, learn its terminology, and get a demo.

The CSS Flexible Box (flexbox) Layout Module Level 1 is a W3C candidate recommendation specification that describes how to optimize a CSS box model for user interface design, where the child of a flex container can be laid out in any horizontal or vertical direction and can "flex" its sizes either way to fill any unused space or shrink to avoid overflowing outside of the parent container. Nesting of flex boxes is another available option, and the CSS language is used for describing the structured HTML documents on screen, on paper, in speech, and in other media types. As of this writing, the specification's Editor's Draft was last updated on October 30, 2013.

With CSS 2.1 defining four layout modes to determine the size and position of boxes based on their relationships with sibling or ancestor boxes, including block, inline, table, and positioned layout, the flex layout becomes the fifth and newest layout mode, which means that more complex applications and webpages can be designed to fit the seemingly endless amalgam of devices and browsers. On the outside, the flex layout is similar to the block layout but lacks many of the text- and document-centric properties that can be used with block layout such as float and columns. But the flex layout gains power from being able to distribute space and align its content in ways that web applications and complex grid-based web pages now require for fluid and responsive-based design principles.

The primary advantages of using the flex box layout is that the contents:

  • Can be laid out in any flow direction either top, down, left or right;
  • Can have the display order reversed or rearranged in a style layer;
  • Can be laid out in linear fashion along a single main axis or wrapped into multiple lines along or across a secondary cross axis;
  • Can "flex" their box sizes based on available space;
  • Can be aligned with respect to the parent container or with each other; and
  • Can be set to dynamically collapse or expand along the main axis while preserving the secondary cross axis size.

Flexbox terminology

The flex layout is biased to flex directions and is defined to a set of flex-flow relative terms. The "flex-flow" value determines how these terms map to physical directions either top to bottom or right to left, and either horizontal or vertical axes, and sizes defined by height and width. The illustration in Figure A, as presented in the W3C Editor's Draft Flex Layout Box Model and Terminology section, displays the various directions and sizing terms as applied to a "row" within a flex container.

Figure A (click the image to see an enlarged view)

FlexBox_FigA_120213.gif
These descriptions are from the W3C Editor's Draft:
  • Main Axis, Main Direction is the primary axis along which contained flex items are laid out. It extends the main dimension.
  • Main Start and Main End: All flex items are placed within a container and start on the main-start side and move toward the main-end side.
  • Main Size, Main Size Property is a flex item's width or height and whichever is the main dimension becomes the main size. The main size property is either the "height" or the "width" property, whichever is the main dimension.
  • Cross Axis, Cross Dimension is the axis perpendicular to the main axis and extends into the cross dimension.
  • Cross-Start, Cross-End: Flex lines are filled with items and are placed into the container starting at the cross-start side and moving toward the cross-end side of the flex container.
  • Cross Size, Cross Size Property is the width or height of a flex item, whichever becomes the cross dimension is the cross size. The cross size property is whichever of "width" or "height" that is the cross dimension.

A great feature with the flexbox CSS recommendation is that content within a flex box can respond to device and screen sizes; this is highlighted with the screen capture in Figure B as displayed in Chrome 31.0.1650.57 m.

Figure B (click the image to see an enlarged view)

FlexBox_FigB_120213.gif

A flexbox demo

Built on a similar demonstration from the specification recommendation, the CSS in this demo features a catalog of four dairy products and includes a photo, a title, a short description, and a Buy Now button for each product. The assumed design requirements stipulate that the image appear at the top, with a short title and then descriptive text just below the image, and a purchase button to appear at the bottom of each entry regardless of the length of the item's description. You can download the demo files used in this article. 

The CSS

The CSS uses the settings display: flex (which sets the flex layout so items will have equal height along rows), flex-flow: row wrap (so items are allowed to wrap into multiple lines), and flex-flow: column (so each item's content is laid out in a vertical fashion). Two additional interesting CSS properties for the item images are order: -1 (which sets the item's images and shifts them above and before other content in visual order) and align-self: center (which sets the images to a horizontal center). And in the item's button property, the margin-top: auto aligns the top margin, pushing the button to the bottom of the flex box. A snippet of the CSS is displayed below.

#products {
  	display: flex;
	flex-flow: row wrap;  
  
}

.items {
  	display: flex;
	flex-flow: column; 
	padding-left: 20px;
	padding-bottom: 15px;
	border: #CCC dashed thin;
}

.items > img {
  	order: -1;
	align-self: center;
	margin-top: 5px;
}

.items > button {
  	margin-top: auto;
	width: 100px;
	align-self: center;
	color: #666;
	background-color: #D0EAFD;
	font-weight: bold;
	border-radius: 12px;
}
 

The HTML

The abbreviated HTML code snippet is displayed below.

<h1>CSS Flex Box Demo</h1>
   <h2>Dairy Products</h2>
    <section id="products">
    	<section class="items">
    	  <h3>Organic Whole Milk</h3>
   	   <p>Fresh organic whole milk!</p>
         <p>"Duis…</p>
    	   <img src="i/whole-milk.png" alt="You get: Fresh organic milk from our dairy farm." title="You get: Fresh organic milk from our dairy farm."/>
    	   <button>Buy Now</button>
  	</section>
  	<section class="items">
  	  <h3>Organic Cheese</h3>
   	   <p>Rich flavorful cheeses from our whole organic dairy! </p>
         <p>"Ut enim..."</p>
    	   <img src="i/cheese.png" alt="You get: Rich flavorful cheeses from our organic milk." title="You get: Rich flavorful cheeses from our organic milk.">
         <button>Buy Now</button>
  	</section>
    </section>
    <section id="products">
    	<section class="items">
  	  <h3>Organic Sweet <br />Creamery Butter</h3>
   	   <p>Organic Sweet Creamery Butter made from our whole organic cream!</p>
	   <p>"Lorem..."</p>
    	   <img src="i/butter.png" alt="You get: Organic Sweet Creamery Butter made from our whole organic cream." title="You get: Organic Sweet Creamery Butter made from our whole organic cream.">
         <button>Buy Now</button>
  	   </section>
    	   <section class="items">
  	    <h3>Organic Yogurt</h3>
   	     <p>Organic Yogurt made fresh at our dairy farm!</p>
           <p>"Duis…"</p>
    	     <img src="i/yogurt.png" alt="You get: Organic Yogurt made fresh at our dairy farm." title="You get: Organic Yogurt made fresh at our dairy farm.">
           <button>BUY NOW</button>
  	   </section>    
    </section>

The screen capture for this demonstration is shown in Figure C as displayed in Chrome 31.0.1650.57 m.

Figure C (click the image to see an enlarged view)

FlexBox_FigC_120213.gif

Browser support

According to Can I use Flexible Box Layout Module?, supported browsers make up 41.49%; partially supported browsers make up 35.45% with a total support percentage of 76.94%.

These browsers support the flexible box layout module: IE 11.0, Chrome 31.0+, Safari 7.0, Opera 17.0, iOS Safari 7.0, BlackBerry Browser 10.0, Opera Mobile 16.0, and Chrome for Android 30.0. Partial support includes the browsers Firefox 25.0+, Android Browser 4.2+, Firefox for Android 25.0, and IE Mobile 10.0.

Additional flexbox resources

 

About

Ryan has performed in a broad range of technology support roles for electric-generation utilities, including nuclear power plants, and for the telecommunications industry. He has worked in web development for the restaurant industry and the Federal g...

2 comments
Lisaaa45
Lisaaa45

Was looking for some solution like that. I just gotta figure out how to make the input field flexible with that. Any ideas?

Lisa
Editor at http://www.fragweb.com

Editor's Picks