CSS Layout

#CSS layout

#Introduction to CSS Layout

###The flow
Each elements in the document alters the flow of text in various ways:

  • Some elements can simply follow the text flow as if they were non-existent.
  • Some elements can force a line break at any point in the flow whether it has reached the edge of the document or not.
  • Some elements can create a new text flow for their inner content independent from the main text flow.

####Elements display categories

The element behavior is defined using the property display. This property can take tons of values but let's focus on the four most important:

  • none
    This value completely removes the element from the flow, exactly as if the element and its content weren't there in the first place.
  • inline
    This value makes an element "transparent": it flows with the text normally and its content is part of the global text flow.
  • block
    This value is for the element to break the text flow with a forced line break before and after it. Its content is no longer part of the global text flow and flows only within the constraints provided by the element box model.
  • inline-block
    This value makes the element somewhat in between inline and block type display: like inline boxes it flows with the text normally but, like block boxes, it's content is no longer part of the global text.

HTML:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<p class="none">
1. I'm a big black cat,
<span>walking under a ladder,</span>
and I can see broken mirrors everywhere.
</p>
<p class="inline">
2. I'm a big black cat,
<span>walking under a ladder,</span>
and I can see broken mirrors everywhere.
</p>
<p class="block">
3. I'm a big black cat,
<span>walking under a ladder,</span>
and I can see broken mirrors everywhere.
</p>
<p class="inline-block">
4. I'm a big black cat,
<span>walking under a ladder,</span>
and I can see broken mirrors everywhere.
</p>

CSS:

1
2
3
4
5
6
7
8
9
span {
width: 5em;
background: yellow;
}
.none span { display: none; }
.inline span { display: inline; }
.block span { display: block; }
.inline-block span { display: inline-block; }

###Altering the flow

####Text layout
CSS provides many properties to deal with simple text layout. Those properties are: hyphens, text-align, text-align-last, text-indent, vertical-align, white-space, word-break, and word-wrap.

It's worth noting that the trick we used to compensate the negative text indentation is a very common trick. Any property that accepts a length also accepts negative values. By fiddling with negative values and compensating them with other properties, it's possible to produce very clever effects on the layout, especially when it applies to properties of the box model.

####Floating

1
2
3
XXX{
float: left;
}

####Positioning
If floating boxes are still part of the flow, another mechanism exists to perform some layouts by extracting boxes out of the flow: CSS Positioning. Positioning is acheived by defining a positioning context with the position property and then allows boxes to be positioned using top, left, right, and bottom properties.

The position property can take on four different values:

  • static
    This is the default value for all elements: they are part of the flow and don't define any specific positioning context.
  • relative
    With this value, elements are still part of the flow, but they can be visually moved around their positions with top, left, right, and bottom. They also define a positioning context for their children elements.
  • absolute
    With this value, elements are pushed out of the flow and no longer influence it. The position of such blocks is defined by the top, left, right, and bottom properties. The 0,0 position point for the top/left corner of the box is the top/left corner of the closest parent element which defines a positionning context other than static. If there is no parent with a positioning context, then, the 0,0 position point for the top/left corner of the box is the top/left corner of the document.
  • fixed
    With this value, elements are pushed out of the flow and no longer influence it. The position of such blocks is define by the top, left, right, and bottom properties. The 0,0 position point for the top/left corner of the box is the top/left corner of the browser window viewport.

Such positioned boxes can stack on top of each other. In that case, it's possible to change the stacking order by using the z-index property.

HTML:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div class="relative">
<div class="absolute-one">
<p>Position:absolute</p></br>
<p>Top Right</p>
</div>
<div class="absolute-two">
<p>Position:absolute</p></br>
<p>Bottom Centre</p>
</div>
<div class="absolute-three">
<p>Position:static</p></br>
<p>Where it falls</p>
</div>
</div>

CSS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
p {
text-align: centre;
color: #fff;
}
/* Setting the position to relative
allows any child elements to be positioned
anywhere, in relation to its container. */
.relative {
position: relative;
width: 95%;
margin: 0 auto;
height: 300px;
background-color: #fff;
border: 3px solid #ADD8E6;
}
/* Just some styles for text alignment /*
.relative div {
text-align: center;
padding: 5px;
display: block;
width: 125px;
height: 125px;
background-color: #ADD8E6;
}
/* By setting this div to position absolute
we can position this element anywhere in relation
to the 'relative' div /*
.absolute-one {
position: absolute;
top: 0;
right: 0;
}
/* Unlike the first div which was positioned at the
top right corner of the container div. '.absolute-two'
is positioned bottom centre. By setting both left and right
to 0, along with margin:auto.
.absolute-two {
position: absolute;
bottom: 0;
right: 0;
left: 0;
margin: auto;
}
/* Where the div would fall naturally within it's container.
This is also useful for returning elements from a floated
position. E.g. on responsive styles. /*
.absolute-three {
position: static;
}

#Flexbox
Using flexbox can help you design compelling layouts in web applications that scale better from desktop to mobile. Put an end to floating

elements, absolute positioning, and JavaScript hacks, and start building horizontal and vertical flowing layouts in just a few lines of CSS.

###Basics
You can make the elements inside any

flow with flexbox by setting the display property to flex and then setting the flex-flow property to either row, if you want the elements to flow horizontally, or column, if you want the elements to flow vertically. If you are using a horizontal flexbox and want your content to wrap vertically, then also specify the wrap value.(flex-flow: row wrap;)

Then, for each element that you want to be part of the flex flow, set the flex property. Generally you will want to use one of the three following values:

  • If you want an element that only takes up its allocated width, like a button, use flex: none that expands to 0 0 auto.
  • If you want to explicitly size an element, use flex: 0 0 size. For example: flex 0 0 60px.
  • If you want an element that expands to fill space available, that is sharing space equally if there are multiple elements of this kind within the flow, use flex: auto. It expands to 1 1 auto.

###Centering an element inside a page

HTML:

1
2
3
4
5
6
7
8
9
<div class="vertical-box">
<div class="spacer"></div>
<div class="centered-element horizontal-box">
<div class="spacer"></div>
<div class="centered-element">Centered content</div>
<div class="spacer"></div>
</div>
<div class="spacer"></div>
</div>

CSS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.vertical-box {
display: flex;
height: 400px;
width: 400px;
flex-flow: column;
}
.horizontal-box {
display: flex;
flex-flow: row;
}
.spacer {
flex: auto;
background-color: black;
}
.centered-element {
flex: none;
background-color: white;
}

###Flowing a set of containers vertically

Imagine that you have a page laid out with a header section, a content section, and a footer. The header and footer should have a fixed size, but the content should resize according to available space. This can be done by setting the content's flex property to auto and flex property on the header, and the footer, to none.

CSS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.vertical-box {
display: flex;
height: 400px;
width: 400px;
flex-flow: column;
}
.fixed-size {
flex: none;
height: 30px;
background-color: black;
text-align: center;
}
.flexible-size {
flex: auto;
background-color: white;
}

HTML:

1
2
3
4
5
<div id="document" class="vertical-box">
<div class="fixed-size"><button id="increase-size">Increase container size</button></div>
<div id="flexible-content" class="flexible-size"></div>
<div class="fixed-size"><button id="decrease-size">Decrease container size</button></div>
</div>

JS:

1
2
3
4
5
6
7
8
9
10
11
12
var height = 400;
document.getElementById('increase-size').onclick=function() {
height += 10;
if (height > 500) height = 500;
document.getElementById('document').style.height = (height + "px");
}
document.getElementById('decrease-size').onclick=function() {
height -= 10;
if (height < 300) height = 300;
document.getElementById('document').style.height = (height + "px");
}

###Creating a collapsing horizontal container

In some cases you might want to lay a set of information out horizontally where the screen size permits, but collapse the contents horizontally where it does not. This is quite straightforward with flexbox. You can do this by adding the wrap value to the flex-flow property.

CSS:

1
2
3
4
5
6
7
8
9
10
11
12
.horizontal-container {
display: flex;
width: 300px;
flex-flow: row wrap;
}
.fixed-size {
flex: none;
width: 100px;
background-color: black;
color: white;
text-align: center;
}

HTML:

1
2
3
4
5
6
7
<div id="container" class="horizontal-container">
<div class="fixed-size">Element 1</div>
<div class="fixed-size">Element 2</div>
<div class="fixed-size">Element 3</div>
</div>
<button id="increase-size">Increase container size</button>
<button id="decrease-size">Decrease container size</button>