CSS Topics
The following are important CSS topics and commonly used in Front-End Developer interviews. This page is where I explore each CSS topic and link to helpful resources.
Efficient CSS
- Avoid the
*
(universal) selector and redundant descendant selectors.
- Selectors match from right to left, so if you have a descendant selector like
`li a {}`
the browser will look for all the <a>
anchor elements and then see which are a descendant of an <li>
list element.
- Don’t qualify ID rules with tag names or classes. IDs are unique and adding to them slow down the matching process.
- Similarly, classes shouldn’t be qualified with tag names.
- The single biggest cause of slowdown is too many rules in the tag category, like I stated earlier with how the browser goes right to left. It’s better to just use a class than spend time matching rules.
- The child selector is better than the descendant, but still bad with tags since they match all occurrences.
Overall
- Watch out for selectors that will match a large number of elements
- ID selectors aren’t as good as class selectors
- Avoid redundant selects, especially in descendant and child selectors. Learn what inherits.
- Avoid
*
Universal Selector
How to Serve for Feature Constrained Browsers
Um…huge topic here.
Important
Delivering only the content and features that users desire.
The more CSS you add to accommodate more screens, the longer page load will take. CSS lacks the mechanism for qualifying its delivery to specific environments.
Prepare CSS delivery to prioritize perceived performance
Combine all CSS into 1 File
Combining all CSS into one file means one blocking HTTP request. Having all potentially applicable styles available allows the browser to apply styles immediately when conditions change (like device-orientation, browser resize, etc.). The downside here is that load time can increase since users are potentially downloading styles that aren’t applicable to their device or browser. Remember to Gzip, as CSS compresses very well because of its redundant syntax.
Separate CSS Styles
A second approach is to separate CSS styles for particular media into their own files and request them independently. The way to specify each file is to add media
attrubes to the link
elements with media query files. Here is an example:
<link rel=“stylesheet” href=“/large-width.css” media=“(min-width: 60em)”>
So the media attributes work just like media queries inline in the CSS, which would allow you to remove inline media queries in the CSS files. The downside is that browsers request everything referenced in the HTML document. Not only that, this approach adds blocking HTTP requests and separate files means accumulated CSS size.
The takeaway: If large portions of CSS are targeted to a particular environment, or breakpoint, the page may load faster for browsers that prioritize link
elements.
Inline CSS
This is really only applicable for single page websites. Inline CSS means it can compress well for delivery and there are limited requests, but at the same time won’t be able to cache those styles for future use.
Hybrid Approach
The idea here is to inline styles that take up much of the top portion of a page and then make a judgement call as to where to start requesting externally in a non-blocking manner.
The difficulty here is managing different CSS files and continually determining the most critical CSS. There are tools to extract critical CSS for each template and creating a file that can be included inline.
For non-critical CSS there is a tool called loadCSS
that loads CSS files asynchronously so that they don’t block page rendering. So, in the head
you would have a <style>
block with critical CSS styles for the template, followed by a <script>
block beginning with the loadCSS
function inline passing in a reference to the stylesheet, finally followed by a link to the sites’ full CSS to be requested if JavaScript is not available.
<style>
/* critical CSS styles for this template go here... */
</style>
<script>
// first, include the loadCSS function inline
function loadCSS( href ){ ... }
//then pass it a reference to a stylesheet to load
loadCSS( "full.css" );
</script>
<noscript><link href="full.css" rel="stylesheet"></noscript>
Resources
More info and tips from Scott Jehl
Floats and Clearing Techniques
The float
property takes an element away from the normal flow and places it along the left or right side of the containing, parent element (still a part of the flow of the web page). Text and inline elements then wrap around it.
History
Think of a newspaper or magazine where an image is set to the left or right of a page and text wraps around them as needed. This is a floating image, and in a word-processor you are performing a text-wrap on the image.
Clearing the Float
Sometimes you don’t want content to jump up into the available space made by a floating element. To fix this, you add the clear
property to ensure the element stays beneath both floated elements.
The footer then is required to jump up into that available space as is required by the float. To fix this problem, the footer can be cleared to ensure it stays beneath both floated elements. The values for clear
are left
, right
, or both
.
An example of clearing just the left or right is if you have some text and two images floating to the right, but you want one beneath the other. The image you want below can get the clear: right
property to clear itself of the other image’s float.
Collapse
If a parent element only contains floating elements, it would collapse to nothing (height: 0
). This kind of makes sense since if it didn’t collapse an unnatural spacing would occur. Take the example of a block element with text and an image floating to the right with height greater than the element. Another block element below it would move up into the white space, but without collapsing there would be some unnatural white space.
Techniques for Clearing the Collapse
Collapsing does have to be dealt with. The approach is to clear the float after the floating elements in a container and before the end of the container.
- If you know what the following element is, you can just
clear: both;
- You can put an empty
<div>
afterwards with clear: both;
.
- Set
overflow: auto;
or overflow: hidden;
to the parent element (if there is one) to expand it to contain the floats.
- Create a
.clearfix
class that just has a pseudo :after
selector with:
content: “ “;
<<<<<<< 245a04fb02b6ba1d8d93aef5fd9f5b3107af11f6
visibility: hidden;
display: block;
height: 0;
=======
visibility: hidden;
display: block;
height: 0;
>>>>>>> Add CSS and JavaScript topics to blog
clear: both;
Resources
Resetting vs Normalizing
Resetting CSS
CSS reset removes default styling from page elements so that you are essentially “starting fresh” with attributes of your choosing.
There are multiple great reasons for this:
All browsers are on the same playing field since different browsers apply different default styling to elements.
Instead of thinking about removing attributes from elements, you can think about applying attributes to elements you know need them.
This guide has some awesome versions of resetting your CSS.
Normalizing CSS
Normalize CSS resets some styles, but leaves some alone. It preserves useful browser defaults, meaning you don’t have to redeclare styles for all the common typographic elements.
Normalize also corrects some common bugs like correcting font-size
for pre-formatted text, SVG overflow in IE9, and also form-related bugs.
Normalize also doesn’t clutter debugging tools. No large inheritance chains. Targeted styles and conservative use of multiple selectors in rulesets stop this issue.
CSS Frameworks
CSS frameworks are pre-prepared software frameworks for easier web design and CSS use. Some come with JavaScript functions, but they are mostly design oriented.
Inline-block vs Block
Inline elements don’t accept width, you can think of <a>
or <span>
elements and how they don’t break the flow of the text. They can have margin and padding, but those values only push others away to the left and right, not top and bottom.
Inline-block elements is just like an inline element but you can set a width and height. Inline elements do not begin a new line.
Block elements do not sit inline and take up as much space horizontally as they can. Blocks begin a new line.
More here.
Styling SVG
SVGs are awesome. I find it really fun to have access to an image that either I created or someone else (like IcoMoon) and be able to change its fill
value or create a SVG sprite file.
SVGs can be filled with extraneous information and I like using tools like SVGOMG to optimize them. This is especially the case with images that I create myself with Sketch.
I’ve used SVGs in multiple ways:
- An SVG paired with some text using a
:before
or :after
selector, since, in this case, it is not semantically essential.
- An SVG without any accompanying text inline so that I can add a
<title>
and <desc>
tag to the <svg>
.
- An SVG as a
background-image
.
- An SVG file with many inside it, and utilizing an inline SVG to create a window to access the different images (using
viewBox
)—essential an SVG sprite technique. More here.
Image Replacement Techniques
The idea here is that you want to be semantic and SEO ready, but an image would look best. An example would be an image logo as the <h1>
tag. It’s a battle between design and accessibility.
My Preference
SVGs are my preferred way since they are semantic and look great. You could add a <title>
to and <svg>
.
Old Techniques
- Hide an element from view while remaining accessible to screen readers.
h1.visuallyhidden {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
- Not accessible, use a span to wrap text inside the header and then hide it.
h1.technique-one {
width: 250px;
height: 25px;
background-image: url(logo.gif);
}
h1.technique-one span {
display: none;
}
z-index
When elements overlap, z-order determines which one covers the other. The z-index
property specifies the z-order of an element and its descendants. z-index
creates a stacking context (obviously) as do other properties (specified below).
Stacking Context
Stacking context is the three-dimensional conceptualization of HTML elements. This is along an imaginary z-axis with the user at one end facing the webpage. HTML elements are positioned by priority.
A stacking context is formed by any element with these qualities.
Highlights
- Root element
- Positioned Elements
display: flex
parent elements
Stacking Summary
- Stacking contexts can be contained in other stacking contexts, and together create a hierarchy of stacking contexts.
- Each stacking context is completely independent from its siblings: only descendant elements are considered when stacking is processed.
- Each stacking context is self-contained: after the element's contents are stacked, the whole element is considered in the stacking order of the parent stacking context.
Stacking with z-index
If you want to specify a different stacking order, you have to position an element and use the z-index property.
Stacking without z-index
When no elements have a z-index elements are stacked from bottom to top with background and borders of the root element first, descendant blocks in the normal flow and in order of appearance in the HTML, and descendant positioned elements in order of appearance in the HTML.
translate()
vs position: absolute;
You can move elements:
- by giving them a
position
value and adjusting the top
, right
, bottom
, and left
properties
- OR making them
block
or inline-block
(if they aren’t already) and use the transform translate()
, translateX()
, or translateY()
values.
I prefer to think of design movements, for interaction purposes, as better performed by the translate()
property. Chris Coiyer calls this “design-y” motion.
translate()
also gets a blurring between pixels that lead to smoother animation (sub-pixel animation).
position
is best used for position things, not “design-y” motion.
Flex-box
Flex-box allows us to control the layout of elements contained within a parent. Thus taking away the responsibility of contained elements for their layout on a page. The closest thing we have had to this is utilizing block formatting context, but nothing with this much control.
There are ways to accomplish almost any sort of layout without using flex-box, but most of them involve asking a lot from the elements themselves and not the container element.
A great example is my portfolio site where the navigation is a column on desktop, but a row on mobile view. Flex-box allows me to say, “hey, all you children are going to be flex-direction: column
on wider screens and flex-direction: row
(default) on narrower ones.”
You can also change the order of children, so if I want the logo a the top of a column of 3 children on for certain layouts and the bottom on others, just add the order property to each child.
You can also specify the amount of space a child takes up with the flex-grow
and flex-basis
properties.
It’s awesome!
Non-Standard Fonts
With the popularity of Google Fonts it is easier than ever to include non-standard fonts into a web design.
If the design includes a Google Font, you can access it directly from Google using a <link>
element in the <head>
(before your actual external stylesheets!) and then access it in your stylesheets by adding the font name to your CSS. Google takes care of the rest.
Let’s say the font is not a Google Font, or the Google Font has issues (like it appears in italics in some web browsers—don’t laugh, this has happened to me before!). In that case, you can use the @font-face at-rule to specify online fonts or local fonts to display. With the @font-face rule you can specify a font-family
, src
’s for the file locations in the form of url(‘fonts/some-font.ttf’);
, and font-weight
and font-style
, among other properties.
Unique @font-face
Names
Most people add custom fonts use unique names for every font weight. That is not necessary and will save a lot of small headaches if you do it right from the beginning by adding multiple weights and styles for every font with the same name.
@font-face {
font-family: ‘liberation sans’;
src: url(‘fonts/liberationsan-regular.ttf’) format(‘truetype’);
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: ‘liberation sans’;
src: url(‘fonts/liberationsan-italic.ttf’) format(‘truetype’);
font-weight: normal;
font-style: italic;
}
Hiding Text
visibility:hidden;
and/or display: none;
These styles hide text for all users. The text is removed from the visual flow of the page and is ignored by screen readers.
Best Use: When you want to hide content from the user and screen readers.
width: 0px;
or height: 0px;
or other 0 pixel sizing techniques
An element with no height or width is removed from the flow of the page, so most screen readers will ignore the content.
Best Use: When you want to hide content from the user and screen readers.
Positioning content off-screen
CSS Clip
position: absolute !important;
clip: rect(1px, 1px, 1px, 1px);
Hide or clip content that does not fit into a 1px area will hide the content visibly, but still allow it to b read by most modern screen readers.
Best Use: When you want to hide content from the user, but not screen readers.
Creating a .hidden
class
Creating a class that can be added to an element that you want hidden visibly but available to screen readers. The class has:
- a
position: absolute;
to remove the element from the page flow
- a
left: -10000px;
position to move the content out of sight
- a
top: auto;
property to position the content vertically at the same location
- a
1px
width and height definition and a overflow: hidden;
to visually hide the content
Best Use: When you want to hide content from the user, but not screen readers.
Block Formatting Context
A block formatting context is an HTML box that satisfies at least one of the following conditions:
- The value of
float
is not none
.
- The value of
position
is neither static
nor relative
.
- The value of
display
is table-cell
, table-caption
, inline-block
, flex
, or inline-flex
.
- The value of
overflow
is not visible
.
Whenever we create a new block formatting context, we choose the best condition based on our requirements. The element you use those conditions on becomes responsible for the layout of its children. The child elements are then contained within a new formatting context!
So, just as we showed overflow: hidden;
can clear floats, the reason now is clear: because we are creating a new block formatting context on the parent and won’t wrap.
IDs vs Classes
or
Unique vs NOT Unique
ID
The id
selector doesn’t allow for reuse. Each element can have only one id
and each page can only have one element with that id
.
I try to use id
s only for elements with functionality. One functionality is the “hash value” in the URL. In this scenario the browser will attempt to link a hash value with a corresponding ID on the page. The browser knows where to scroll there.
Classes
The class
selector allows for reuse so you can target multiple elements. This is great for styling groups of elements. You can also use multiple classes on the same element.
The Box Model
The Box Model is used to describe the manipulation of a block-level element through margin
, border
, padding
, height
, and width
—but not position!
How does it work?
Say you have a block-level element, like a <section>
and it’s width is set to 500px. If the margin
is set to 10px
, border
to 1px
, padding
to 10px
, the resulting width of the element will be 542px
.
But I wanted it to be 500px (plus margin)!
To get the browser to render how you want, you have to take into consideration that the width
and height
of a box-level element includes the padding and border.
You can change this by using the box-sizing
property with value border-box
. This makes width
and height
calculations include padding
and the border
(but not margin
).
With our example above, if the <section>
had property:
section {
box-sizing: border-box;
margin: 10px;
width: 500px;
padding: 10px;
border-width: 1px;
}
Then its width on the page would become 500px + margin = 520px and not 542px since 1px + 1px border and 10px + 10px padding (equaling 22px) is included in the specified width!
Use the *
universal selector and set box-sizing
to border-box
so that you can depend on the width including padding and border, which, to me, is much more intuitive.
* { box-sizing: border-box; }
Media Queries and Mobile Specific Layouts
I love this!
My approach is to break apart a user interface into individual, reusable components. Say you have a section of multiple pricing tiers. Each pricing tier is a module within the pricing tier component.
Constructing a page in this way means that your styles begin with a mobile screen. This isn’t always the case, but styling for individual components means they are more ready for a mobile screen than a desktop.
Media Queries
I put @media
queries to good use when expanding a component/module style for a larger context. This usually is layout related, where I am adjusting the max-width
, or changing the font-size
, or margin
and padding
properties.
My go to is @media screen and (min-width: *some break point*) {}
and it will contain styles for after that break.
I like to begin with a mobile layout and then expand it. It is more code and a slower process to begin with a wide viewport and try to make it smaller. If I am thinking of a UI as made up of many, many components anyways, why not start with the smaller screen?
Retina Graphics
Retina describes really sharp, clear screens that can cram in lots of pixels.
- I like to use SVGs when I can.
- Can an image be reproduced with CSS? Do that.
- When I use JPEG, I try to use a minimal quality image but double the max-size that it will be. This results in a small and good looking image for awesome screens.
- DPI doesn’t matter for screens.
The Display Property
The display
property determines the type of rendering box to use for an element. The initial values for elements are provided by HTML.
The Most Common Display Values
inline
(like <a>
elements)
block
(like <p>
, <div>
, <article>
, etc)
inline-block
(like <button>
, <textarea>
, <input>
, and <select>
)
flex
(the element is essentially block
but its containing element layout is according to the flexbox model)
inline-flex
(the element is essentially inline
but its containing element layout is the flexbox model)
list-item
(the element essentially behaves like a <li>
)
table
(the element is a block-level box that behaves like a <table>
)
inline-table
(same as above but an inline-block element)
inline-list-item
(same as a list-item
but inline-block)
More Table Styles
table-caption
, like <caption>
HTML elements.
table-cell
, like <td>
HTML elements.
table-column
, like <col>
HTML elements.
table-column-group
, like <colgroup>
HTML elements.
table-footer-group
, like <tfoot>
HTML elements.
table-header-group
, like <thead>
HTML elements.
table-row
, like <tr>
HTML elements.
table-row-group
, like <tbody>
HTML elements
How Browsers Match CSS Selectors
Browsers match CSS selectors from right to left. If a browser has an element it is trying to to style, say a <span>
and there are a lot (thousands) of rules in the stylesheet, many of those selectors in the stylesheet do/will not match the <span>
. So the browser wants to determine if a selector does not match as quickly as it can.
Continuing with this, if the browser starts by matching the rightmost part of the selector against the <span>
, then chances are they will not match, and it is done and can move on to the next. When it does match, it just has to move to the left and continue the search.
But what about starting from the left? Wouldn’t that be more efficient?
No.
If the browser starts with the leftmost part of the selector, and the end result is to style the <span>
, it would have to match it against DOM nodes just to find a place to start. This would take a long time.
It’s all about a starting point
Starting from the right gives the browser a place to start matching selectors and getting rid of candidates very quickly.
Advantages and Disadvantages of Using CSS Pre-Processors
My experience is mainly with Sass, which I love to use. Here are my thoughts.
Disadvantages
There are few, so lets get them out of the way.
- There are multiple so you have to learn the different syntaxes.
- It is easy to add superfluous code when you don’t know the how to write efficient CSS and understand the importance of OOCSS.
- You have to set it up. Although this is pretty straightforward, you still need to have a development environment that would allow you to set up auto updating your Sass.
- You need to have some sort of structure that everyone knows to use to keep your code from getting all confusing (files everywhere). I find it important to keep a style guide for styles, variables, functions, and directory/file layout.
Advantages
Nesting
- Nesting creates descendant selectors and property values. So you could next a
p
in a .class
and have .class p
be the output. Also, you can nest size
, weight
, and family
under font
to get the correct output. Very cool!
- Using an
&:
you can create a parent selector reference in your nesting. Examples include writing &:hover
nested in an a
.
- You can nest media queries in a selector and the output will be the media query with the selector inside it.
Variables
Variables can be used to easily switch out values. I usually use variables by creating a _variables.scss
partial and storing commonly re-used values like fonts, weights, line-heights, colors, etc. This way I have a reference to quickly and easily change values.
Syntactic Tools
Using the @extend
keyword followed by a selector will cause selector inheritance. You’re basically saying, “hey, use properties and values from that other selector on this one.”
You can also define a “placeholder” using %some-name
and giving it properties to be added to selectors in the future with @extend %some-name
.
@mixin
s are great for adding properties to a selector with arguments. A great example is using a mixin for adding common styles to a button but leave the colors and fonts arguments that are either set to a default or not.
The idea is that you can create a style component that can be reused and customized. Very cool.
Note that you can use variables as default arguments for mixins if you want.
Scripting
- You can do operations within a properties value (
font-size: 12 / 16 * 1em;
).
- You can create
@function
s that @return
values for calculating or easier syntax for Sass maps.
- You can us
@if
to make conditional styles
- You can create ranges with the
@for
keyword
Optimizing Webpages for Print
The @media print
media type and Paged Media properties allow us to use CSS to optimize styles for print, when necessary.
How it works is we create a code block with @media print {}
and include properties necessary for the section to print appropriately.
Formatting issues can be eliminated by including:
- The
page-break-before
property to adjust page breaks before the current element.
- The
page-break-after
property to adjust page breaks after the current element.
- The
page-break-inside
property adjusts page breaks inside the current element.
- The
orphans
property to refer to the minimum number of lines in a block container that must be left at the bottom of the page. Used to control how page breaks occur.
- The
windows
property to define the minimum number of lines left at the top of the second page. Allows the prevention of single-line windows.
Tips for print media blocks
- You could eliminate the header and footer, if they are not necessary.
- Changing the image size, or eliminating them.
- Hiding video and other interactive elements.
- Define page margins with the
@page
rule.
- Adjust
font-size
and margin
s and other layout.
CSS Sprites
A sprite of images is a collection put into a single image (file). Get the image one, shift it around to only display part of it.
Sprite
The term “sprites” comes from a technique in computer graphics where the computer can fetch a graphic into memory and then only display parts of that image at a time.
Why?
The reason to use sprites is to increase page load time since the number of server requests decrease and you save bandwidth, like minifying CSS and JavaScript.
How?
Create one file of images that will be used.
- Set the image to a
background-image
and then adjust the background-position
and height
to show the proper image in the proper element.
Alternatives
- Data URIs, which allow you to embed data directly into a stylesheet.
- Icon Fonts, which work like sprites
- SVGs Sprites
Positioning
position: relative;
Adding this property and value to an element makes it as though the element were not positioned, but you can then adjust it without changing the layout.
Leave space for the element.
position: fixed;
Will position the element at a specified position relative to the screen's viewport and not move it when scrolled.
Do not leave space for element.
position: absolute;
Will position the element at a specified position relative to its closest positioned ancestor or to the containing block. Boxes can have margins.
Do not leave space for element.
position: static;
This is an elements default positioning. The element is in its current position in the flow and top
, right
, bottom
, left
, and z-index
properties do not affect it.
The Cascade
The CSS Cascade is an algorithm feature that determines how to find the value to apply for each property for each document element.
The Order of Things
Least User Agent (browser)
Kind of User Styles (think accessiblity)
Most Author Styles
The Cascade first filters all the rules from different sources whose selector matches the given element and appropriate media at-rule
.
Then, the Cascade sorts the rules according to importance which is defined by an origin’s importance—either normal or !important
.
- User Agent - Normal
- User Agent - !important
- User - Normal
- Author - Normal
- CSS Animations
- Author - !important
- User - !important
Specificity
- Most specific selector overrides least specific selectors
- Inline (most), ID selectors, Class selectors, Element tag
Priority is based on order that they appear and last style takes precedence over previous.
An example:
User-agent CSS (which each browser has its own)
li { margin-left: 10px }
Author CSS Reset
li { margin-left: 0 }
Author CSS
media screen {
li { margin-left: 3px }
}
The last one gets selected even though it has the same selector as the reset since it is most important.
CSS Grid Systems
Grid systems are considered a best practice for rapid layout scaffolding.
My preference would be creating my own grid system, but that is project and team dependent. If a team wants to use Bootstrap, that is totally fine. Creating your own system means you have control over constructing the grid of rows of columns.
For me, having a command for using Flexbox as a layout tool is much better than a grid system.
Pseudo-elements
Pseudo-elements are syntax added to selectors to style certain parts of a document.
Say you want to style the first line of a paragraph different than the rest? There is the :first-line
pseudo-element.
Other pseudo-elements I use a lot are :before
and :after
. These are great for adding a .clear-fix
class to clear floats or adding design elements that aren’t necessarily a part of the document.
Browser Specific Styling Issues
I use a few techniques to keep styles consistent across browser and mostly avoiding issues.
CSS Reset
I reset CSS so that I am starting from a blank slate on all browsers. No default browser styles are going to surprise me.
Prefixing and Auto-Prefixer
I like to use auto-prefixer and set it to date back a few browsers depending on features I’ll be implementing (i.e. will there be a lot of flexbox?). If there are some styles that are borderline not accepted on some browsers, I’ll be sure to make sure they are prefixed.
Mobile First
I take a responsive and mobile first approach to implementing the presentation layer.
Responsive vs Adaptive Design
Methods for dealing with the fact that websites are viewed on different devices and different contexts.
Responsive
Responsive design is a means of becoming device agnostic — optimized for any screen. This means flexible assets, fluid measurements, and media queries defining where content breaks.
Adaptive
Adaptive design is thinking about specific points at which to adapt. It isn’t a fluid approach, but one that simply takes into account the possible best break points and adjusts the design.