Intermediate CSS

Outline

Common Mistakes from HW2

DON'T use magic numbers for positioning when there is a way to express what you want in a better way!

  • Might break things when the layout is resized
  • Usually there is a way to express what you want in CSS
  • Sometimes though, it's unavoidable (top, left, bottom, right values)

Example: If you want to center something, don't place it "300 pixels from the left", find a way that actually centeres it.

Example (CodePen)

DON'T repeat yourself, abstract things out to classes where you can!

  • If you find yourself copying the same property/value pairs in multiple rules, you can probably abstract those out to a class.

Example: The icons in the footer on hw2--no reason to put height and width on each of those. Make a class that you give to all three, and only use IDs to specify what is unique (the background-image).

Example (CodePen)

DON'T use nonexistent properties/values!

  • There is no error, these will just fail silently
  • If you have any doubt, google it!
  • If the browser doesn't know how to interpret them, they'll show up crossed out in the webkit inspector--usually a sign that something is amiss (though this could also mean that the property/value is being overridden)

Example: layout: relative;, vertical-align: 10px

Example (CodePen)

DO use the webkit inspector!

  • Why look at the code without the context of how it’s being displayed when you can look at both at once?
  • There are a few ways to open the inspector in Chrome
    • right-click ? inspect element
    • View ? Developer ? Developer Tools

DON'T use class or ID names that don’t semantically describe the content!

Example: You probably shouldn't have the following:

<div class="addPadding"></div>
<span class="bold"></span>

DON'T leave off units (even if you can)!

  • Some browsers will convert unitless numbers to pixels, others will just ignore them completely.
  • The exception to this is 0. 0 is the same no matter what unit, and browsers know that. But still a good idea to use units (doesn’t hurt anything).

Shorthand CSS

Margin/Padding, Border, Font

Example (CodePen)

Relative Units of Measurement

Percentages

Percentage units (a number followed by a percentage sign, with no space in between) may be used instead of absolute units (like px) when we want to specify the size of an element in relation to it's parent. You can use percentage units for many length properties, such as width, height, margin, padding, and more. Percentages can also be used for text-sizing.

Warning: percentages work differently depending on what length property they are used with. For example, a percentage margin or padding is relative to the parent's width. This is true even for margin-top/bottom and padding-top/bottom which can be confusing. On the other hand, offsets (top, bottom, left, and right) are all relative to the parent's height. See this link for more details.

EMs

EMs are a relative sizing unit typically used for sizing fonts. For any element, 1em is equal to the font-size of the parent element. For example:

HTML

<div id="foo">
    237
    <div id="bar">
        is
        <div id="baz">
            awesome!
        </div>
    </div>
</div>

CSS

#foo {
    /* assuming nothing else has changed the font size of this elements parent, 1em will be equal 
     * to the default font size of the browser, which is usually 14px. 
     */
    font-size: 1em;
}
#bar {
    /* 1.5 * 14px (parents font size) = 27px */
    font-size: 1.5em;
}
#baz {
    /* 2 * 27px (parents font size) = 54px */
    font-size: 2em;
}

Specifying relative font sizes using EMs is very popular because it makes it easy to instantly scale up all the font sizes of your website just by changing the size of one element (usually body or html). In order to make EMs easier to work with, you'll often see the font-size on the body set to 62.5%. Given that the default font-size is 14px in most browsers, this causes 1em to be equal to 10px at body level. This makes it easy to say what pixel sizes certain EMs will correspond to (1.4em = 14px, 1.6em = 16px, etc.).

However, the fact that the value of an EM is defined by it's direct parent can cause frustration when we throw cascading into the mix. In the example above, #baz scales off the font size of it's immediate parent, #bar. It can get very confusing to keep track of this, and it would honeslty just be easier if EMs always sized relative to the root element's font-size. Turns out, this is exactly what the rem unit is for. REM stands for root em and you can read more about it, as well as the whole px/em/rem/pt debate here and here.

Backgrounds

Example (CodePen)

CSS Pseudo-Classes

Be careful! Some pseudo-classes have limited cross-browser support! Always check www.caniuse.com

Select elements in certain states

  • :hover (mouse-over)
  • :active (mouse button held in)
  • :visited (links that have been visited)
  • :focus (input elements that currently have keyboard focus)

Select elements more specifically

  • :first-child
  • :last-child
  • :nth-child(n)

So how do I use a pseudo-class?

a {
    /* styles here will affect all a tags */
}

a:hover {
    /* styles here will only affect a tags which are being hovered over */
}

What about specificity?

Pseudo-classes are considered the same level of specificty as a class. You won't often run into specificty issues with psuedo-classes though, because they are often tacked on to an existing selector.

So is that it?

There are many more psuedo-classes than mentioned here. See the links below for more details.

Extra Resources:

CSS Tricks - Pseudo-class Selectors
MDN - Pseudo-class Selectors

Example: CSS3 Menu Bar

Download an example of a CSS3 Menu Bar here

Responsive Web Design

Fixed Layouts:

  • Have an outer container with a defined width
  • Are always the same regardless of browswer window size
  • Easier to design and code

Fluid Layouts

  • Have an outer container with a width of 100%, fills the entire browser window
  • Have subsections with widths defined in percentages
  • Often use space more efficiently (no side gutters)
  • Harder to design and code

Media Quries

  • Allow you to code for a few different common screen sizes (perhaps you'll want a layout for a large desktop screen, small desktop screen, tablet, and mobile)

Media Queries

Media Queries allow you to specify CSS which only applies for certain screen sizes, device sizes, device orientations, or a number of other conditions.

A basic media query

@media only screen and (min-width : 0px) and (max-width : 480px) {
    #main {
        background-color: green;
    }
}

In the above code, the background-color: green will only be applied to #main if the conditions after the @media are met. In this case, the conditions specify that we ony want to target screen media (as opposed to say, a printer) where the viewport width is between 0px and 480px.

min-width vs min-device-width

You'll see and write media queries with both min-width and min-device-width and the difference is very important.

min-width (or max-width) refers to the size of the viewport. This is the area onto which the browser renders content. Note, this area may be smaller than your actual screen size (especially on non-mobile devices), when the browser window doesn't take up the entire screen.

min-device-width (or max-device-width) refers to the size of your screen. This measure is completely independent of how large your browser window is. On mobile devices, width and device-width are often the same when the device is in portrait mode. __In landscape mode, the device will sometimes still report the same max/min-device-width as it did in portrait, but the max/min-width measurement will change to a larger value to reflect that it is in portrait mode.

Common media queries

  • min/max-width
  • min/max-device-width
  • orientation
  • -moz-/-webkit-pixel-ratio

A number of logical operators are also available such as and, not, and only.

Pixel Ratios

Older iPhones have a resolution of 480x320. The iPhone4 has a resolution of 640x960--twice that of it's predecessos. It would be very inconvenient if everyone who had written media queries intended to target iPhones suddently had to add another query to handle the case of the new retina iPhones. So instead, the iPhone4 reports the same device-width as older iPhones (320x480), but it reports a device-pixel-ratio of 2. For now, you'll still need to use the vendor specific prefixes when testing for these values, such as -webkit-min/max-device-pixel-ratio and -moz-min/max-device-pixel-ratio.

Media Queries and Platform Detection

Though it seems to have become pretty commonplace, you shouldn't use media queries as a form of platform detection. Remember that media queries only have the ability to detect certain characteristics about a device, and not what the device is itself. For example, if wrote a media query with the goal of detecting iPhones, we should be aware that any device (even an Android device) that meets the same characteristics will also meet requirements we set. Besides, there are better ways to do platform detection in Javascript.

Loading media queries

You can either:

(a) load all of the CSS and define media queries within the CSS file:

<link rel="stylesheet" href="css/style.css"/>
/* general styles */

@media ______________________________ {
    /* styles for this media query */
}

(b) only load entire css files given media query conditions

<link rel="stylesheet" media="your-media-query-goes-here" href="css/media-specific-styles.css"/>

Sample Media Queries

/* Smartphone size DESKTOP window (using VIEWPORT width) */
@media only screen and (min-width : 0px) and (max-width : 480px) {
    ...
}

/* Note: All iPads (including 2 and 3) report the same device width and device height */

/* iPad and similar tablets (portrait and landscape) */
@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) {
    ...
}

/* iPad and similar tablets (portrait) */
@media screen and (device-width : 768px) and (orientation : portrait) {
    ...
}

/* iPad and similar tablets (landscape) */
@media screen and (max-device-width : 1024px) and (orientation : landscape) {
    ...
}

/* Smartphones */
@media screen and (min-device-width : 320px) and (max-device-width : 767px) {
    ...
}

The above are just a few simple examples, see what values your target device is returning using the links below and write your media queries accordingly.

Extra Resources:

MDN on Media Queries
CSSMediaQueries.com (test which queries your device matches)
Media Query Diagnostic Tool (see what values your device reports)

Example: Fixed/Fluid/Responsive Layout

Download an example of a fixed/fluid/responsive layout here

Floats

Floats were originally conceived as a way to have text flow around images, though they are often used as the basis for CSS layouts as well.

The Basics

  • Floats can be used to shift things horizontally to the left or to the right, there is no center floating.
  • Floated elements will shift to left or the right until they (a) hit the edge of their container or (b) another floated element.
  • Floats keep the same vertical position as if they weren't floated.

Float Theory

The following are good introductory articles on floats:

The Zero-height Container Problem

Floated elements take up no vertical space according to their parent containers, causing the zero-height container problem (also known as the collapsing parent problem). This can be fixed using the clear property.

Clears

Elements below a floated element will either appear underneath it (for block elements) or wrap around it (for inline elements). If you want them to not do that, and just appear beneath (as if the floated element were block), you can use the clear property. Important: the clear property goes on the element you want to dorp down below the float, and NOT the floated element itself.

The clear Property:

With clear, you've got three options:

  • clear: left;
    • element is moved below the bottom edge of any left-floated elements before it in the DOM
  • clear: right;
    • element is moved below the bottom edge of any right-floated elements before it in the DOM
  • clear: both;
    • element is moved below the bottom edge of all floated elements before it in the DOM
    • you'll almost always use this instead of the left or right varieties

Clearing Techniques


Technique 1 (DON'T USE)

Put clear: both; in the CSS of every item that we want to clear.

HTML

<div id="container">
    <div id="foo"> ... </div>
    <div id="bar"> ... </div>
    <div id="baz"> .... </div>
</div>

CSS

#foo { float: left; }
#bar { clear: both; }
#baz { clear: both; }

PROs

  • very straightforward and easy to use

CONs

  • have to repeat clear: both; in a bunch of places
  • attaches the clearing directly to the DOM elements below the float--can be annoying if the layout changes

Technique 2 (DON'T USE)

Put overflow: hidden; on the parent of the floated element

  • Wait what? Yup, doing this for some reason causes children elements to clear floats.

HTML

<div id="container">
    <div id="foo"> ... </div>
    <div id="bar"> ... </div>
    <div id="baz"> .... </div>
</div>

CSS

#foo { float: left; }
#container { overflow: hidden; }

PROs

  • easy to use

CONs

  • about as unclear as you can get because the clearing effect is incidental

Technique 3 (DON'T USE)

Make a class called clear or clearfix whose only purpose is to apply the CSS clear: both;, and put that class on every item that we want to clear.

HTML

<div id="container">
    <div id="foo"> ... </div>
    <div id="bar" class="clearfix"> ... </div>
    <div id="baz" class="clearfix"> ... </div>
</div>

CSS

.clearfix { clear: both; }
#foo { float: left; }

PROs

  • abstracts clearing out into it's own class

CONs

  • attaches the clearing directly to the DOM elements below the float--can be annoying if the layout changes

Technique 4 (MAYBE USE)

Make a class called clear or clearfix whose only purpose is to apply the CSS clear: both;, and put that class on an extra element whose only purpose is to clear floats.

HTML

<div id="container">
    <div id="foo"> ... </div>
    <div class="clearfix"></div>
    <div id="bar"> ... </div>
    <div id="baz"> .... </div>
</div>

CSS

.clearfix { 
    clear: both; 

}
#foo { float: left; }

PROs

  • abstracts clearing out into it's own class
  • decouples clearing from the DOM elements below the float--easy to adapt to layout changes

CONs

  • requires an extra non-semantic DOM element

Technique 5 (DEFINITELY USE)

There's actually one more technique we'll see for clearing floats, but first we need to learn a little bit about psuedo-elements

Pseudo-Elements

Pseudo-elements allow you to use CSS to insert DOM elements directly before or after a selected element. You can use either the :before pseudo-element or the :after psuedo-element, and you can specify the text inside this created element using the content attribute in CSS. Note: Even if you don't want any text inside the node, you still must supply the content property--just make it an empty string. By default, pseudo-elements are inline elements, but you can style them however you want.

Important: Pseudo-elements are inserted as the first child (:before) or last child (:after) of the element the pseudo-element is applied to. They are not inserted as sibling elements, but as child elements.

HTML

<div id="foo">
    <!-- :before pseudo-element would be inserted here -->
    <div id="bar"></div>
    <!-- :after pseudo-element would be inserted here -->
</div>

CSS

#foo {
    ...
}

#foo:before {
    content: "";
    /* other styles for this psuedo-element go here */
}

#foo:after {
    content: "";
    /* other styles for this psuedo-element go here */
}

Using pseudo-elements to clear floats

Here's that 5th technique for clearing floats we mentioned earlier. It's probably the best technique currently in use.

This technique involves using some combination of pseudo-elements to automatically insert a clearing element after a float. Here it is:

HTML

<div id="container" class="clearfix">
    <div id="foo"> ... </div>
    <div id="bar"> ... </div>
    <div id="baz"> .... </div>
</div>

CSS

.clearfix:after {
    visibility: hidden;
    display: block;
    content: "";
    clear: both;
    height: 0;
    }
* html .clearfix             { zoom: 1; } /* IE6 */
*:first-child+html .clearfix { zoom: 1; } /* IE7 */

There are so many different versions of this clearing hack, targeted at compatibility with various browsers. The variation above is compatible with IE6 and IE7, but if you don't need support for those browsers, you can remove those last two lines. For more information regarding these variations, see this link.

Extra Resources

CSS Tricks (Screencast) - Intro to Pseudo-Elements
CSS Tricks - CSS Tricks Pseudo-Element Roundup - A Whole Bunch of Amazing Stuff Pseudo Elements Can Do