Flexible

Application Layout with CSS3 Flexible Box Module

It has become very easy to create fluid application layouts thanks to the CSS3 Flexible Box Layout Module. In this article we are going to implement a simple application layout, which fills the whole screen, resizes with the browser window and comes with the additional bonus of a draggable splitter.

Instead of the classic <div> elements let’s also use some HTML5 structural tags. This will not only make the code more semantic, but also more convenient to work with, since we can directly address the elements with a CSS type selector without having to rely on id attributes or parent-child relationships.

Take a look at the complete demo to see how it works.

First step: Add Vertical Boxes

We start with only three tags (<header>, <main> and <footer>) in the body.

<!DOCTYPE html>
<html>
<head>
    <title>CSS3 Application Layout</title>
</head>
 
<body>
<header></header>
<main></main>
<footer></footer>
</body>
</html>

Let’s add the CSS to make these three elements fill the space vertically. This is achieved by setting the CSS display property of the <body> to flex and the flex-direction property to column. This tells the browser to lay out the body’s children (<header>, <main> and <footer>) as vertical flexible boxes.

How this available space is distributed can be controlled with the flex shorthand property. You can read about it on MDN. In this application layout though, we don’t want the size to shrink or expand proportionally. Instead the <header> and the <footer> element should have a fixed height, whereas the <main> should just fill the remaining space by setting its flex property to auto.

html, body {
    height: 100%;
    width: 100%;
    padding: 0;
    margin: 0;
}
 
body {
    display: flex;
    flex-direction: column;
}
 
header {
    height: 75px;
}
 
main {
    flex: auto;
}
 
footer {
    height: 25px;
}

Show demo

Second Step: Horizontal Boxes

Let’s add three more elements (<nav>, <article> and <aside>) inside the <main> element. But this time we want them to fill the space inside the <main> element horizontally instead of vertically.

<body>
<header></header>
<main>
    <nav></nav>
    <article></article>
    <aside></aside>
</main>
<footer></footer>
</body>

This is achieved by setting the display property of the <main> element also to flex, but the flex-direction property to row (this is the default). The <nav> and <aside> element should have a fixed width, while the <article> should just fill the remaining space: this is achieved in the same kind of manner as before:

main {
    display: flex;
    flex-direction: row;
    flex: auto;
}
 
nav {
    width: 150px;
}
 
article {
    flex: auto;
}
 
aside {
    width: 50px;
}

Show demo

Thats all. Resize your browser window and enjoy the flexible application layout.

Next step: CSS Refinements

But wait. When there is a lot of content, an element can become smaller than specified and also scrollbars can appear.

Therefore, we need to add a min-width property to all elements where we added a width property. We also should set the overflow property of the <body> and the <main> element to hidden as well as the overflow-y of <article> and <aside> to auto to only show scrollbars where we want them.

body {
	overflow: hidden;
	display: flex;
	flex-direction: column;
}
 
header {
	height: 75px;
	min-height: 75px;
}
 
footer {
	height: 25px;
	min-height: 25px;
}
 
main {
	display: flex;
	flex-direction: row;
	flex: auto;
	border: solid grey;
	border-width: 1px 0;
	overflow: hidden;
}
 
nav {
	width: 150px;
	min-width: 150px;
}
 
article {
	border: solid grey;
	border-width: 0 0 0 1px;
	flex: auto;
	overflow-x: hidden;
	overflow-y: auto;
}
 
aside {
	width: 50px;
	min-width: 50px;
	overflow-x: hidden;
	overflow-y: auto;
}

Note: This does probably not work in Safari yet. You might be able to get it to work by using the -webkit- prefix.

Final Step: Throw a little JavaScript into the Mix

As the final step, we want the user to be able to resize the <aside> element when dragging it with the mouse. For that we add a <div> element as a splitter, which will serve as the drag handle.

<body>
<header></header>
<main>
    <nav></nav>
    <article></article>
    <div class="splitter"></div>
    <aside></aside>
</main>
<footer></footer>
</body>

We set the width of the handle to 4px and give the cursor attribute a value of col-resize, to show the user that this element can be resized East-West.

.splitter {
    border-left: 1px solid grey;
    width: 4px;
    min-width: 4px;
    cursor: col-resize;
}

All what’s left now is to add a little JavaScript, that enables moving the splitter.

var w = window, d = document, splitter;
 
splitter = {
    lastX: 0,
    leftEl: null,
    rightEl: null,
 
    init: function(handler, leftEl, rightEl) {
        var self = this;
 
        this.leftEl = leftEl;
        this.rightEl = rightEl;
 
        handler.addEventListener('mousedown', function(evt) {
            evt.preventDefault();    /* prevent text selection */
 
            self.lastX = evt.clientX;
 
            w.addEventListener('mousemove', self.drag);
            w.addEventListener('mouseup', self.endDrag);
        });
    },
 
    drag: function(evt) {
        var wL, wR, wDiff = evt.clientX - splitter.lastX;
 
        wL = d.defaultView.getComputedStyle(splitter.leftEl, '').getPropertyValue('width');
        wR = d.defaultView.getComputedStyle(splitter.rightEl, '').getPropertyValue('width');
        wL = parseInt(wL, 10) + wDiff;
        wR = parseInt(wR, 10) - wDiff;
        splitter.leftEl.style.width = wL + 'px';
        splitter.rightEl.style.width = wR + 'px';
 
        splitter.lastX = evt.clientX;
    },
 
    endDrag: function() {
        w.removeEventListener('mousemove', splitter.drag);
        w.removeEventListener('mouseup', splitter.endDrag);
    }
};
 
splitter.init(d.getElementsByClassName('splitter')[0], d.getElementsByTagName('article')[0], d.getElementsByTagName('aside')[0]);

Note: For some reason the resizing doesn’t work in IE11 (, Safari?) or Chrome 31. It seems that it has something to do with the display: flex; property value.

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Visual Merchandiser for Monthly Projects – Very Flexible!

AL-Mobile, Are you seeking… …A flexible source of side income? Competitive pay? The ability to utilize your retail merchandising skills?             Would you enjoy making your own schedule, while representing the latest and greatest in sporting good and active-lifestyle products?             Franklin Retail Solutions, a third-party merchandising company specialized in representing athletic and outdoor produ View full post on Monster Job Search Results (mobile)

View full post on WebProJobs.org

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Sr.net Lead Analyst (Flexible working hours, casual dress)

Agilesys Tarentum, PA
Job description: …SSRS 2005/2008, Visual Studio 2005/2008/2010, .Net Frameworks 2.0, 3.0, 3.5, 4.0 Web Services, IIS (6,7.5)Experience with ASP.NET security models as it pertains to design, development and implementation around authentication, authorization, impersonation, confidentiality, and… View full post on Dice.com – web security

View full post on WebProJobs.org

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)