New terms from treehouse – CSS Layout Techniques Part 2 – Positioning Schemes and Flexbox Layout

Positioning Schemes

Relative Positioning

In this example we’ll use relative positioning to set up the header. We start with this:

Screen Shot 2014-06-24 at 2.10.59 PM

With relative positioning, elements are still in the normal document flow, but they don’t influence the layout of the surrounding elements. This is because the positional offsets we provide position it relative to its original position. We’ll start by setting the logo and nav to position:relative and give the logo a width.

Screen Shot 2014-06-24 at 2.14.49 PMScreen Shot 2014-06-24 at 2.13.30 PM

Now, if we were to style the logo bottom:20px;, it would offset it 20px up from the bottom from its original position.

Screen Shot 2014-06-24 at 2.16.57 PM Screen Shot 2014-06-24 at 2.16.50 PMIf we were to change it to top:20px;, it would move it 20px from the top.

Screen Shot 2014-06-24 at 2.17.59 PM

Screen Shot 2014-06-24 at 2.18.05 PM

If we were to do right:20px;, it would move to the left, and it we were to do left:20px; it would move to the right. Notice also how the nav elements are not affected or moved by the logo.

Screen Shot 2014-06-24 at 2.19.44 PM

Screen Shot 2014-06-24 at 2.19.59 PM

Next, we’ll reposition our main nav so in it’s inline with our logo. To move it up, we’ll give it a bottom: 32px; and to move it to the right, we’ll give it a left: 200px;.

Screen Shot 2014-06-24 at 2.22.29 PMScreen Shot 2014-06-24 at 2.22.37 PM

Now, because the header and nav are block level elements, They’re both still taking up an entire line or block on the page. And since they’re still in the normal document flow, the positioning offsets we defined are causing the logo and nav to overflow its parent header container, causing the big gap on the right.

Screen Shot 2014-06-24 at 2.25.01 PM

The best way to fix this is by giving the header an overflow value of hidden.

Screen Shot 2014-06-24 at 2.27.19 PM Screen Shot 2014-06-24 at 2.27.08 PM


Absolute positioning

Relative positioning also serves as a positioning context for absolute positioning, because an element with absolute positioning will always be relative to its first parent that has a relative position. If no parent element has that, the browser viewport will be the positioning context.

We’re going to use absolute positioning to style this header. Here’s what we’re starting with:

Screen Shot 2014-06-25 at 9.38.28 AM

First, we need to establish the header container as position:relative. Then we’ll set the logo and nav elements as position:absolute;

Screen Shot 2014-06-25 at 9.42.20 AM Screen Shot 2014-06-25 at 9.42.08 AM

As you can see, this positions them in the top left part of the container header div by default. The space we’re seeing is the padding applied to the header container (not the logo), and the margins given to the list items. However, if we were to select the logo and set its top and left offsets to 0…

Screen Shot 2014-06-25 at 9.45.18 AMScreen Shot 2014-06-25 at 9.45.30 AM

The key thing here is 0 will put it at that edge of its parent container, and a positive value will move it away from it.

So, when absolute positioning is used, the element is completely removed from the normal document flow, so it no longer affects the positioning of other elements (like the nav items).

You can use negative values as well, which can move elements outside of their parents.

Screen Shot 2014-06-25 at 9.47.55 AMScreen Shot 2014-06-25 at 9.48.05 AM

We’ll use offsets now to position the elements.

Screen Shot 2014-06-25 at 9.49.47 AM Screen Shot 2014-06-25 at 9.49.36 AM

Now, let’s say we wanted to put the nav items on the right.

Screen Shot 2014-06-25 at 9.51.18 AM Screen Shot 2014-06-25 at 9.52.08 AMThe downside to the absolute positioning is that we’ll need to make sure there’s a height in the containing element, otherwise it will collapse. For example:

Screen Shot 2014-06-25 at 9.53.18 AMScreen Shot 2014-06-25 at 9.53.25 AM

Unfortunately there’s no clearfix for this like there is for floats, so you’ll need to make sure there’s always a height for the container.

Next, we’ll want to reposition the three columns of content using absolute positioning.

Screen Shot 2014-06-25 at 9.55.15 AMLike before, we need to set the containing element (.content-row) to position:relative;. Then, we’ll set widths for the columns and position them absolute.

Screen Shot 2014-06-25 at 9.59.42 AM Screen Shot 2014-06-25 at 9.59.28 AM

Now, we’ll give the columns positioning offsets. Give the .primary-content a new width and position it 30% from the left, and the .secondary one right on the right.

Screen Shot 2014-06-25 at 10.01.57 AM Screen Shot 2014-06-25 at 10.01.46 AM

Once again, because we’re using absolute positioning, we need to set the height of the parent containers to 100%, or the content-row will collapse, which is why the footer is jammed up in there.  For some reason I had to do it for .main-wrapper and .col as well, so I guess it’s for all containing parents.

Screen Shot 2014-06-25 at 10.03.53 AM Screen Shot 2014-06-25 at 10.03.46 AM

We can also now add more content above and below, and also remove the wrapper styling without breaking the layout.

Screen Shot 2014-06-25 at 10.06.43 AMScreen Shot 2014-06-25 at 10.06.50 AM


Fixed Positioning

Best example of this is with a fixed header. Once again, we’re starting with this:

Screen Shot 2014-06-25 at 10.48.13 AM

First, we’ll give the main-header container a width:100% and position:fixed; Because we’ve given it that position, we can now use the top, bottom, left and right offsets we’ve used before, so we’ll also give it a top:0; to make sure it stays at the top.

Screen Shot 2014-06-25 at 10.51.46 AM  Screen Shot 2014-06-25 at 10.51.19 AM

The second screen shows an issue – since the columns are positioned absolute, they have a higher z-index than the header which has position:fixed;. To fix this, give it a z-index of anything higher than 1, since we haven’t specified one for the columns. Though you wouldn’t normally set up the columns with absolute positioning, it’s good to keep z-index in mind.

Screen Shot 2014-06-25 at 10.54.06 AM Screen Shot 2014-06-25 at 10.53.44 AM

If we wanted the header to be at the bottom of the page, you’d simply change it to bottom:0;

Screen Shot 2014-06-25 at 10.55.09 AMScreen Shot 2014-06-25 at 10.55.33 AM

 

When the header is position:fixed, it’s also being taken out of the normal document flow, as you can see in the example below. It’s not affecting/pushing down the position of the banner like it would in the normal document flow, and is instead covering it.

Screen Shot 2014-06-25 at 10.51.37 AM

To fix this, add some top padding to the body of the page. Since the header is 100px tall, we’ll use 100px.

Screen Shot 2014-06-25 at 10.59.35 AM Screen Shot 2014-06-25 at 10.59.28 AM


Absolute Centering

There’s a quick and easy way to center absolutely positioned elements inside their parent container. We’re going to make an icon with a pseudo element then center it vertically and horizontally.

Screen Shot 2014-06-25 at 11.07.40 AMFirst, we’ll need to set a relative positioning context for the icon, so that any child or pseudo element will be relative to its width and height.

Screen Shot 2014-06-25 at 11.09.25 AM

We’ll then set up a pseudo element. Content will be blank, display will be block, and we’ll set the width and height we want. Then, we’ll use background to set the background image url, and set background-size:100%, which means it will use the width and height we just specified. Then, we’ll set it’s position to absolute.

Screen Shot 2014-06-25 at 11.34.19 AMScreen Shot 2014-06-25 at 11.33.47 AM

Now w’ll give it some offsets to center it. If we set all four ones to 0, and set the margins to auto, it will position it right in the center.

Screen Shot 2014-06-25 at 11.36.29 AM

Screen Shot 2014-06-25 at 11.36.13 AM


Flexbox Layout

Still tough to decide whether to use today. It’s awesome, but the browser support for it is very weak for older browsers. Flexbox is source order independent, so you can layout elements in any direction/order regardless of where they’re written in the markup.


 

Building a navigation with flexbox

Starting with this:

Screen Shot 2014-06-27 at 12.34.08 PM

Notice how the header logo has been added as a list item to the main nav. This will make it easier for us later.

Screen Shot 2014-06-27 at 12.34.14 PM

First, we need to establish a flex formatting context. We do this with display:flex; By doing so on the .main-nav, we make the list items inside it flex items, which by default lays everything out in a row, in what’s called the flex direction. This let’s us layout the list items in all sorts of different ways.

Screen Shot 2014-06-27 at 12.40.24 PMScreen Shot 2014-06-27 at 12.40.37 PM

For perfectly vertically aligned elements, we can set the li’s to align-self:center;. We also need to set a height for its parent container.

Screen Shot 2014-06-27 at 12.39.45 PMScreen Shot 2014-06-27 at 12.39.54 PM

Next we’ll give them some margin left and right.

Screen Shot 2014-06-27 at 12.42.47 PM Screen Shot 2014-06-27 at 12.42.37 PM

 

Now, with flexbox, margins can have a pretty significant effect on flex items. Let’s say that we wanted to put the nav items on the right hand side and keep the logo on the left. We’ll use .main-logo:first-child because it’s more specific than the .main-nav li descendent selector above. When we set margin-right to auto, it absorbs all the extra space and pushes the remaining list items to the right.

Screen Shot 2014-06-27 at 12.49.06 PMScreen Shot 2014-06-27 at 12.49.18 PM

For now, we’ll keep it at 50px.

Screen Shot 2014-06-27 at 12.50.23 PMScreen Shot 2014-06-27 at 12.50.27 PM

We can use the flex-grow property to control the amount of space the flex items take up in the main nav. If we want all the links to be evenly spaced, we can do flex-grow:1;. The value 1 represents the ratio of free space we want them to take up.

Screen Shot 2014-06-27 at 1.14.04 PM Screen Shot 2014-06-27 at 1.13.58 PM

If we want the logo to be bigger, simply give it a larger flex-grow value of 2, which makes it take up twice as much space of a flex item with the value 1.

Screen Shot 2014-06-27 at 1.15.06 PM Screen Shot 2014-06-27 at 1.14.04 PM

For this to work in Safari, we must copy the flex declarations and use the -webkit- prefix.

Screen Shot 2014-06-27 at 1.17.58 PM

IE10 uses a whole different syntax, which thankfully we won’t be going into today.


Animating Flexbox

In this example, he’s added data icons to each nav link, whose values are html unicode characters. He’s using a before psuedo element to insert the content based on the value of the data-icon attribute set.

Screen Shot 2014-06-28 at 12.26.36 PM

Screen Shot 2014-06-28 at 12.28.41 PMScreen Shot 2014-06-28 at 12.26.44 PMThey’re currently positioned absolute, to get them inside the nav links, we’ll give the links a relative positioning context. The logos will then be position 10px from the top of the nav link area.

Screen Shot 2014-06-28 at 12.34.09 PMScreen Shot 2014-06-28 at 12.34.19 PM

Next, we’ll position them with a left:-30%;, and add an overflow:hidden to the nav links, to hide them.

Screen Shot 2014-06-28 at 12.36.14 PMScreen Shot 2014-06-28 at 12.36.37 PMScreen Shot 2014-06-28 at 12.36.23 PMScreen Shot 2014-06-28 at 12.36.28 PMNow, we’ll make it so that when you hover the icons appear. We’ll select the a under .main-nav, when you hover it selects the pseudo element and moves it over 10% from the left.

Screen Shot 2014-06-28 at 12.39.45 PMScreen Shot 2014-06-28 at 12.39.54 PM

We’ll add a transition to make it look nicer.

Screen Shot 2014-06-28 at 12.41.28 PMaa

Now, we’ll make the flex items grow on hover. We’ll select li items when hovered that are not the .main-logo (cause we don’t want that to expand), and give them a new flex-grow. Then, we’ll select main-nav list items and give them a transition to make it smoother.

Screen Shot 2014-06-28 at 12.45.31 PMaassThe transition also works on mobile devices.

sss

 


Flexbox Columns

Now we’ll layout the three columns with flexbox. Starting with this:

Screen Shot 2014-06-28 at 12.51.01 PM

First we’ll create that flex formatting context in the containing .content-row element. This makes the child elements act as flex items, which puts them in a row, and the stretch to fill the container both horizontally and vertically.

Screen Shot 2014-06-28 at 12.50.54 PMScreen Shot 2014-06-28 at 12.51.08 PM

To have the columns be evenly distributed, we can give them a flex value of 1.

Screen Shot 2014-06-28 at 12.53.10 PMScreen Shot 2014-06-28 at 12.53.22 PM

Now, let’s say we want primary-content column to take up twice the amount of space. Simply select it and give it a flex value of 2.

Screen Shot 2014-06-28 at 12.54.47 PM Screen Shot 2014-06-28 at 12.55.19 PM

Once again, we can change the order of the columns without changing the markup. If we want primary content to be first, we can use the order property.

Screen Shot 2014-06-28 at 12.57.22 PM Screen Shot 2014-06-28 at 12.57.06 PM

To swap the extra and secondary content ones, select the extra content and give it an order of 1.

Screen Shot 2014-06-28 at 12.58.25 PMScreen Shot 2014-06-28 at 12.58.33 PM

Lastly, once again we need to include the vendor prefixes so it works in Safari.

Screen Shot 2014-06-28 at 1.00.16 PM


Providing fallbacks with Modernizr

This will allow us to provide fallbacks for browsers that don’t support Flexbox. It detects if a feature is supported by a browser, and if it doesn’t, it falls back to conditional CSS we write in the stylesheet. It lets you select which features you want to detect for. Then you download the js file and simply link it in the head section like any other one.

Screen Shot 2014-06-28 at 1.04.32 PM

You’ll know it’s working when you see class=” js flexbox” the html element when viewing the page source. This means that javascript is enabled in the browser, and that it supports flexbox. If it didn’t, it would display no-flexbox, which we can use to provide fallback styles for browsers that don’t support it.

Screen Shot 2014-06-30 at 2.17.39 PM

Screen Shot 2014-06-30 at 2.21.05 PM

 

To do this, we’ll find where we put our flexbox styles and adjust them. For display: flex in .main-nav, this is fine because if a browser doesn’t support it it will go back to the default display value, in this case block.  We need a fallback for the list items. So, we select the class .no-flexbox, then any list items in the class .main-nav inside of that.

Screen Shot 2014-06-30 at 2.24.59 PM

Next, we’ll fix the columns.

Screen Shot 2014-06-30 at 2.26.29 PM Screen Shot 2014-06-30 at 2.26.59 PM

Lastly, we’ll fix the icons by adjusting their position when you hover.

Screen Shot 2014-06-30 at 2.28.17 PM Screen Shot 2014-06-30 at 2.28.08 PM

 

 

 

New terms from treehouse – CSS Layout Techniques Part 1- Display Modes and Float Layout

Excited to start a new Deep Dive, and even more so to learn about layout techniques, as this is the part of CSS I feel like I am still most in the dark about.

Display Modes

Before planning out a page, you need to consider how a browser’s default styling might affect our layout. It may give certain elements like the body and lists certain margins and paddings by default. If you don’t reset these, the browser will use its own instead, which can lead to an inconsistency of our layout between browsers. A CSS reset is good to use because it removes most of those styles, giving you a clean slate to work from in all browsers. Below, you can see the page with normal browser styling.

Screen Shot 2014-05-31 at 4.08.13 PM

There are two common CSS reset methods used today.

  • Reset CSS – a method that zeros out every elements default browser styles. That means that for all properties like padding, margin, etc, they’re all set to zero or none. The line height and fonts are also affected. It should look exactly like it does below in every browser. You shouldn’t use all the of the reset CSS if you don’t need it – you can customize it and remove the selectors you don’t. You just copy and paste the styles on the site into your CSS.reset
  • Normalize.css – depending on the size of your project, this zeroing out might not be the best option. It may make a lot of elements unreadable, forcing you to spend time writing more CSS to produce the new default values. Normalize is more suitable for this, as a lot of the times is totally okay to leave in some of those default browser styles. It brings all browsers down to a even playing field, by leaving those useful default browser styles. However, it also styles elements with no common default styles, so it looks consistent in every browser. This is used in frameworks like Bootstrap and Foundation. You just link to it like any other CSS file. It’s pretty well split up and labeled, so you’ll know what each rule is doing and why. Once again, you can remove sections you don’t need for that specific project, or add things you do need.Screen Shot 2014-05-31 at 4.35.55 PM

Block vs inline elements – most elements are one of these by default, but you can modify that using the display property.

block level elements take up an entire line in the layout, so no elements can be positioned to their right or left.

In the example page we’re starting with, it’s missing a wrapper or main container, which are commonly used to center a layout and keep it from looking too wide or narrow, depending on the device or viewport width. There are two ways to do this. The first is using the body element as the wrapper, as the body is a container anyways. Start by giving it a width of 90%, which will prevent the layout from stretching out too wide, and setting the margin to auto will center it on the page. The advantage to this method is you don’t have to create an additional div element for our layout. However, with this method if you want to add a full background color or image, we’ll have to add it to the html element instead. This is ok, but adding a wrapper div gives you a little more control over the layout.

Screen Shot 2014-05-31 at 4.56.26 PMScreen Shot 2014-05-31 at 4.57.25 PMScreen Shot 2014-05-31 at 4.56.41 PM

Simply wrap all the content in a div, give it a class, then use that to set the width to 90% and the margin to auto.

Screen Shot 2014-05-31 at 5.02.40 PM

Now, in the normalize.css we set the body’s default margins to 0, so why is there a 24px gap above our header at the top? What we’re actually seeing here is the top margin of our h1 element. But, the h1 element is inside of its header element container, which has the green background, shouldn’t the margin show up there? This is called a margin collapsing issue. The reason this is happening here is because there’s no border, padding, content or anything to separate the top margin of the block level body element with the top margin of its first child (the main-wrapper div). If there’s nothing to separate those margins, then they collapse, which is why we’re seeing the margin for the h1 element outside of its parent element. This is also happening in the soon to be columns below.

Screen Shot 2014-05-31 at 6.13.19 PM

To fix this, give the parent element (in this case the header container) either a border or padding. In the example below, you can now see the backgrounds of the header container, the h1 and the list clearly defined.

Screen Shot 2014-05-31 at 6.16.02 PM Screen Shot 2014-05-31 at 6.16.23 PMNext, we give the h1 “logo” a display: inline. You can see it no longer takes up an entire line and we can now lay other elements next to it.

Screen Shot 2014-05-31 at 6.19.35 PM

Screen Shot 2014-05-31 at 6.18.20 PM

If you tried to set the class for the ul to display:inline as well, it wouldn’t look any different because the list items act as block level items. They’re actually set by the  browser to the list item display mode that generates a block level box. So, set the individual list items to display:inline as well. Below, I show what happens if you don’t set the ul element to inline as well, then what it looks like for both. The reason the first example still shows the list items on the second line is because the ul is still block level.

Screen Shot 2014-05-31 at 6.22.43 PM Screen Shot 2014-05-31 at 6.22.34 PM

Screen Shot 2014-05-31 at 6.24.15 PMScreen Shot 2014-05-31 at 6.24.25 PM

Next, we’ll give the h1 and the list items some padding and a border-radius to make them rounded, and give the h1 a margin-right to put some space between it and the list items.

Screen Shot 2014-05-31 at 6.27.24 PM 1 Screen Shot 2014-05-31 at 6.27.06 PM

Now, the downside to this inline method is that you can’t give inline elements a width or a top or bottom margin. There’s also a minor whitespace issue that happens with them, notice the default space between the list items. This won’t go away even if you set the margins and paddings to zero. The reason it’s happening is that it’s counting the line breaks in the html as whitespace (like spaces between words in a p element). One solution to this is to push the elements right next to each other in the html with no spaces, but obviously this sucks, as you don’t want to affect the presentation via the html.

Screen Shot 2014-05-31 at 6.31.13 PMScreen Shot 2014-05-31 at 6.31.23 PM

A better solution is to apply negative margins to the list items.

Screen Shot 2014-05-31 at 6.33.11 PMScreen Shot 2014-05-31 at 6.32.54 PM

Now, these are nav links, so we probably do want spacing. So, add use margin-right to make them bigger.

Screen Shot 2014-05-31 at 6.35.13 PM

Screen Shot 2014-05-31 at 6.34.38 PM

New issue – since the display is inline, when the browser gets narrow it gets all bunched up on itself as they wrap on themselves. It’s wrapping how text would wrap in a paragraph.

Screen Shot 2014-05-31 at 6.36.15 PM

To fix this you can give the .main-header a whitespace property of nowrap, but notice how now it breaks out of the container.

Screen Shot 2014-05-31 at 6.37.36 PM


To fix this, you can use the inline-block value for the display property. when you do this, notice how there’s more space now there as well, and that they’ll move to the next line if the browser width gets too narrow. This also lets us give these elements a width and a top or bottom margin. It treats elements as inline elements, that can be styled the same way as block level elements, but they’re still distributed as inline with other inline elements.

Screen Shot 2014-05-31 at 6.44.31 PM Screen Shot 2014-05-31 at 6.44.24 PMScreen Shot 2014-05-31 at 6.45.34 PM

It’s worth noting, the same whitespace issue for inline elements also happens for inline-block elements. The reason the size of the header container increased when we switched to inline-block is because we’re using a h1 element, and headings by default have a top and bottom margin, which normalize.css does not reset.

Screen Shot 2014-05-31 at 6.50.40 PM Screen Shot 2014-05-31 at 6.50.32 PM

If you were to hover, you’d notice the clickable areas for the lines in the logo and list items is small, it’s only on the text itself. To make the link hover target larger and take up the full width and height of its parent container element. To fix this, we need to set the display of the anchor elements to block, because display values are not inherited. We also took the padding from the h1 and list items, and gave it to the anchors as well. Note – even though the anchor elements are block level, since their parent elements are inline-block elements, they don’t display on the next line.

Screen Shot 2014-05-31 at 6.54.51 PM Screen Shot 2014-05-31 at 6.54.45 PM


Table is another handy display mode. It emulates the old school table based layouts that were used before css. It allows you to easily vertical align elements to the center of its parent container.

First, in the parent container you need to set the display property to table. You must also give it a width of 100%, so it takes up 100% of its own parent container div. Finally give it a min-height of 150px.

Screen Shot 2014-06-02 at 1.44.04 PMScreen Shot 2014-06-02 at 1.47.00 PM

You can see there is a bit of a box model bug appearing here. Because the header has 20px of padding all around, the browser is calculating that padding into the headers total width and height as well. This causes there to be 40 pixels of padding on the right there. To fix this, use the box-sizing property. You can actually declare it once, with the universal selector (*), and set it to border-box

Screen Shot 2014-06-04 at 12.39.30 PM

Screen Shot 2014-06-18 at 2.43.53 PMNext, we need the main-logo and main-nav elements to display as table-cell. This will make them display as a table-cell in a table. Now, we can make it align vertically with vertical-align: middle;. We’ll also remove the top margins of the list items and the logo (which I’ve commented out here so you can see where it was before), as our table display mode will take care of the spacing for us. Regardless of the height we set for the header, the logo and nav elements will always be vertically centered now.

Screen Shot 2014-06-18 at 2.53.49 PM

Screen Shot 2014-06-18 at 2.51.53 PM

To fix the spacing, we’ll add some padding-LEFT to the .main-nav, which is the ul.

Screen Shot 2014-06-18 at 2.54.43 PMScreen Shot 2014-06-18 at 2.54.51 PM

Now, if we had used a margin instead, it won’t work because you’re not able to use margins on elements that are displayed as table cells.

Finally, when the viewport is resized, things start to look strange. This is common behavior of table cell layout.

Screen Shot 2014-06-18 at 2.57.38 PM

To fix this, use a media query. We’ll set the logo and nav elements back to block with their initial padding and margins, and give the list items a little margin-top so they have some spacing between them. Now, when the browser is resized, everything looks good.

Screen Shot 2014-06-18 at 3.01.16 PM Screen Shot 2014-06-18 at 3.01.43 PM


Column layout with inline-block

We’re starting with this layout:

Screen Shot 2014-06-18 at 3.12.57 PM

Each div with content has the class col. We’ll start by setting their display to inline-block, and give them some padding, about 20px. We’ll also give them some widths, which add up to 100% of their parent container.

Screen Shot 2014-06-18 at 3.15.57 PMScreen Shot 2014-06-18 at 3.15.26 PM

Now, that doesn’t look right. The reason this is happening is due to the whitespace issue discussed before with the list items in the nav. Once again, the fix for that is to give these columns a negative margin-right of -5px. Apparently the negative pixel value depends on the font size we’ve set.

Screen Shot 2014-06-18 at 3.17.56 PM Screen Shot 2014-06-19 at 1.47.27 PM

One thing to note with inline-block, is you’ll see some that are vertically aligned bottom by default, like the secondary content div above. The best way to adjust this is to give the columns a vertical-align of top. This works similar to using floats, without the collapsing problem that comes with them.

 

Screen Shot 2014-06-19 at 1.49.30 PMScreen Shot 2014-06-19 at 1.49.37 PM

Sometime we’ll want the footer to be positioned at the very bottom of the viewport, regardless of how tall or short the columns of content are, which it’s not doing right now in the example above. There are a few methods to create what’s called a sticky footer, which will do that. The simplest way is as follows:

First, select all the main containers on the page (html, body, .main-wrapper, .col) and give them a height of 100%. This height of 100% is calculated based on the height of the parent element. So, if the height of all the main containers is set to 100%, we’ll get the desired result.

Screen Shot 2014-06-19 at 1.54.22 PMScreen Shot 2014-06-19 at 1.54.43 PMScreen Shot 2014-06-19 at 1.54.49 PM

We’ll then improve out footer by adding some padding styles to make it thicker and center align the text.

Screen Shot 2014-06-19 at 1.56.24 PM Screen Shot 2014-06-19 at 1.56.02 PM

Now, if you want the layout to span the full width of the viewport, simply remove the width and margin declarations for the .main-wrapper.

Screen Shot 2014-06-19 at 1.58.55 PMScreen Shot 2014-06-19 at 2.00.01 PM

We can now introduce new block elements and still maintain the flow of the document. We’ll add a new div with an h1 and a p element.

Screen Shot 2014-06-19 at 2.01.59 PM

We’ll then style it with a background color, some padding and align the text center. Notice how it lines up nicely with the other divs due to how we set this page up.

Screen Shot 2014-06-19 at 2.04.54 PM Screen Shot 2014-06-19 at 2.04.42 PM

Screen Shot 2014-06-19 at 2.06.33 PM

You can even put it somewhere else, like between the secondary content and the footer, and it will still work. It only won’t work if you put it between the primary and secondary content divs.

Screen Shot 2014-06-19 at 2.08.00 PMFinally, like always, we’ll add some media queries to ensure this looks nice on smaller screens. Remember again you can always hide sections you don’t need, so we’ll hide the banner as well.

Screen Shot 2014-06-19 at 2.10.02 PM Screen Shot 2014-06-19 at 2.09.57 PM


Float Layout

Floats come from print design, where a picture would be to the left and the article would flow around it’s right.  Using the property let’s you place it along the left or right side of its container, outside of the normal document flow.


 

Creating a horizontal Menu

Floats are technically block level elements, but they act like inline elements because they don’t exist on a line of their own. With floats, the surrounding content usually wraps around the floated element, because it exists outside of the normal document flow. This is what we’re starting with:

Screen Shot 2014-06-23 at 10.52.01 AM

 

We’ll start with the logo.

Screen Shot 2014-06-23 at 10.53.53 AMScreen Shot 2014-06-23 at 10.54.04 AM

That doesn’t look right, but makes sense. Notice how the nav links are ignoring the space that the logo element would normally take up on the page. But the content (Link 1, Link 2, etc) wraps around the logo element, because content wraps around the floated element.

So, we now need to float the list items.

Screen Shot 2014-06-23 at 10.57.16 AM Screen Shot 2014-06-23 at 10.57.08 AM

Now, we’ll mess with their margins to help them sit better.

Screen Shot 2014-06-23 at 10.59.19 AM Screen Shot 2014-06-23 at 10.59.11 AM

Screen Shot 2014-06-23 at 11.00.47 AM Screen Shot 2014-06-23 at 11.00.31 AM

Now, in this example we can just float the list items without having to float the main-nav ul element itself since it doesn’t have any of it’s own styles. But let’s say it did.Screen Shot 2014-06-23 at 11.03.47 AMScreen Shot 2014-06-23 at 11.03.32 AM

It appears like that because the main-nav ul is still in the normal document flow, even though it’s child elements are not. To fix this, simply make the main-nav ul float as well.

Screen Shot 2014-06-23 at 11.05.52 AM Screen Shot 2014-06-23 at 11.05.43 AM

We can also make it float right instead.

Screen Shot 2014-06-23 at 11.07.35 AMScreen Shot 2014-06-23 at 11.07.43 AM


The Float Clearfix

The floats added to the header elements above have caused another layout issue. Anytime we float an element, it takes it out of the normal document flow, which can sometimes cause the parent element to collapse, because it no longer honors the space of the content inside it. This is what’s happening in our header, since both of its child elements are floated. The reason it’s not collapsing now though is because it has a min-height set to 100px. If we were to remove that, we get this.

Screen Shot 2014-06-23 at 11.18.29 AM

This is an okay workaround, but it’s not future proof and leaves us with an fragile layout.  Now, if we were to also float the main-header left, and give it a width of 100%, it would actually fix the issue as well.

Screen Shot 2014-06-23 at 11.20.51 AMScreen Shot 2014-06-23 at 11.21.05 AM

But, this leads to a new issue where the elements below the main-header will now start wrapping around it. For example, if the width of the header was less than 100%.

Screen Shot 2014-06-23 at 11.23.45 AMScreen Shot 2014-06-23 at 11.23.57 AM

Though we could fix this, floating the main-header actually isn’t the best solution. What you should do is what’s called a clearfix, which forces the parent element to clear its children. We went over this before for the CSS foundations deep dive. We’ll use a ::after psuedo element with blank content, and clear:both here makes it so that it clears both the right and left sides of a float. The .group class will be used to group the child elements within the parent, to prevent it from collapsing. So, now anytime we need to clear a container, we simply need to give it the class .group.

Screen Shot 2014-06-23 at 11.40.05 AMScreen Shot 2014-06-23 at 11.40.12 AM  Screen Shot 2014-06-23 at 11.39.59 AM

Similar to inline block elements, floats move to the next line as the width of the viewport gets smaller.

Screen Shot 2014-06-23 at 11.41.39 AM

As before, we’ll use a media query to make this looks better.  We’ll set the float to initial and set the margin-right to 0 for the logo.

Screen Shot 2014-06-23 at 11.43.26 AMScreen Shot 2014-06-23 at 11.44.07 AM


Floating Columns and Images

We already have a .col class for the divs of content on the page. If we float them left, nothing really happens (except the footer wrapping around the last div).

Screen Shot 2014-06-23 at 12.05.42 PM Screen Shot 2014-06-23 at 12.06.06 PM

To fix this, we need to give the columns a width.

Screen Shot 2014-06-23 at 12.07.23 PMScreen Shot 2014-06-23 at 12.07.31 PM

Now, with the extra content div we can see we once again have the collapsing container issue. To fix this, we’ll add the .group class to the content-row container div it’s sitting in, to apply the clearfix.

Screen Shot 2014-06-23 at 12.10.33 PMScreen Shot 2014-06-23 at 12.10.39 PM

Notice how the grey part appearing in extra content before was actually the footer jammed up in there. The content in the footer is wrapping around the last floated element, the secondary content div, but it’s grey background is pushing back through the other parts.

Next, we’ll tweak the width of some of the columns. We’ll set the primary one to width: 40%. then use .col:last-child pseudo-class to select the last .col element in its parent container to float it right. I’m not sure why we did that last part though, as setting the width of the primary one have the same results.

Screen Shot 2014-06-23 at 12.52.46 PM Screen Shot 2014-06-23 at 12.52.29 PM

You can change the order they display by setting them to float:right;

Screen Shot 2014-06-23 at 12.54.12 PMScreen Shot 2014-06-23 at 12.54.20 PM

You can also reorder the content in the markup (like move extra above primary) and it will still fit together well.

Screen Shot 2014-06-23 at 12.55.55 PM

Next, we’ll make the layout 100% of the browser, by removing the wrap elements properties.

Screen Shot 2014-06-23 at 12.57.05 PMScreen Shot 2014-06-23 at 12.57.21 PM

Next, let’s inset an image into the primary content div.

Screen Shot 2014-06-23 at 1.00.46 PM

Next, we’ll make the text wrap around the image by setting it’s width to 50% and float:left;

Screen Shot 2014-06-23 at 1.02.49 PMScreen Shot 2014-06-23 at 1.02.04 PMTo create space between the image and text, give the image a margin. If we were to apply the margin to the text instead, it would not have the same effect. Since the image is outside of the normal document flow due to the float, margin for the text would only create space between it and the left side of the blue column it’s sitting in.

Screen Shot 2014-06-23 at 1.04.15 PM Screen Shot 2014-06-23 at 1.04.08 PMWe can give the image border and padding styles as well.

Screen Shot 2014-06-23 at 1.08.00 PM Screen Shot 2014-06-23 at 1.07.47 PM

Finally, we need to make it look good on mobile.

Screen Shot 2014-06-23 at 1.09.19 PM

We’ll use a media query and make it so we remove all the floats (which will make the columns display one after another in the normal document flow), and then also set the image’s width to 100% so that it takes up it’s full parent container.

Screen Shot 2014-06-23 at 1.13.10 PM Screen Shot 2014-06-23 at 1.13.04 PM

Even if we add more content, it will still fit well.

Screen Shot 2014-06-23 at 1.17.07 PM Screen Shot 2014-06-23 at 1.17.01 PM


Mobile First Layout

It’s better to start with mobile, then build bigger sites, rather than starting big then going smaller.  In the examples above, they’re using normalize.css to reset the values, then adding the property values for the site, then adding even more values with the media query. For example, we set a margin-right for one of the elements, then in the media query reset it back to 0 when the site viewport is under 768px. Same with the floats for the columns. This isn’t very efficient, as it forces the browser to load and parse all the css when it doesn’t have to.

So, we provide the minimal styling be default, then build on that with media queries. This will let the mobile site load faster. We’ll refactor the css for the main layout elements, which gets us this far.

Screen Shot 2014-06-23 at 2.14.52 PM Screen Shot 2014-06-23 at 2.14.41 PMNext, we’ll style the columns by adding some padding, and hide the extra content and banner divs because we don’t want them to appear on mobile.

Screen Shot 2014-06-23 at 2.16.28 PM Screen Shot 2014-06-23 at 2.16.12 PMNext, we’ll style the image to take up 100% of its parent container.

Screen Shot 2014-06-23 at 2.19.07 PMScreen Shot 2014-06-23 at 2.18.23 PM

Now that we have our mobile view on lock, we can build on that using media queries and the min-width media feature. First, we’ll style the header. Then we’ll style the columns so they float nicely. Then, we’ll add the clearfix rule to prevent the header container from collapsing since all its children are floated. Finally, we’ll restyle the image with a float so the content wraps around it.

Screen Shot 2014-06-23 at 2.29.01 PMScreen Shot 2014-06-23 at 2.29.09 PM  Screen Shot 2014-06-23 at 2.28.54 PM