Display

CSS Box Model

A Browser's rendering engine represents each element as a rectangular box when laying out a document.

CSS determines the size, position, and properties (color, background, border size, etc.) of these boxes. Every box is composed of four parts (or areas), defined by their respective edges: the content edge, padding edge, border edge, and margin edge.



CSS Box Model

The content area is bounded by the content edge and contains the "real" content of the element such as text or an image. It can have a background colour or image. The content area's size are defined with width, min-width, max-width, height, min-height, and max-height properties.

box-sizing: content-box; is the default in the CSS box model. The width and height you assign to an element is applied only to the element's content area. If you set an element's width to 100 pixels, then the element's content area will be 100 pixels wide, and the width of any border or padding will be added to the final rendered width. If box-sizing: border-box; is set, this tells the browser to account for any border and padding in the values you specify for width and height. So If you set an element's width to 100 pixels, that 100 pixels will include any border or padding you added, and the content box will shrink to absorb that extra width.

The padding area is bounded by the padding edge. The thickness of the padding is determined by the padding-top, padding-right, padding-bottom, padding-left, and shorthand padding properties.

The border area is bounded by the border edge. The thickness of the borders are determined by the border-width and shorthand border properties. If the box-sizing property is set to border-box, the border area's size can be explicitly defined with the width, min-width, max-width, height, min-height, and max-height properties.

The margin area, bounded by the margin edge, extends the border area to include an empty area used to separate the element from its neighbors. Its dimensions are the margin-box width and the margin-box height. The size of the margin area is determined by the margin-top, margin-right, margin-bottom, margin-left, and shorthand margin properties. When margin collapsing occurs, the margin area is not clearly defined since margins are shared between boxes.

Resources

CSS box model

Less.js

Less.js is a CSS pre-processor with a CSS-like syntax.

Variables

Variables allow commonly used values to be controlled from a single location.

// Variables
@link-color:        #428bca; // sea blue
@link-color-hover:  darken(@link-color, 10%);
@my-selector:       banner;
@images:            "../img";
@themes:            "../../src/themes";
@property:          color;


// Usage

@import "@{themes}/tidal-wave.less";

a,
.link {
color: @link-color;
}
a:hover {
color: @link-color-hover;
}
.widget {
color: #fff;
background: @link-color;
}

// the below compiles to .banner{
.@{my-selector} {
    font-weight: bold;
    line-height: 40px;
    margin: 0 auto;
}

body {
    color: #444;
    background: url("@{images}/white-sand.png");
}

.widget {
    @{property}: #0ee; // compiles to color: #0ee;
    background-@{property}: #999;
}

                    

Nested Rules

Nesting allows you to cascade your CSS properties with inheriting children where & operator represents the parent selectors of a nested rule.

Below is an example of a nested rule and what it will compile to:

// Variables
// ---------

@textColor: #232323;
@textHighlight: #00214D;
@fontFamily: Helvetica, Arial, sans-serif;
@fontSize: 14px;
@lineHeight: 21px;

@introSize: 16px;
@introLineHeight: 24px;
@introFontVariant: small-caps;

// LESS for Paragraph
// ------------------

p {
    color: @textColor;
    font-family: @fontFamily;
    font-size: @fontSize;
    line-height: @lineHeight;

    .intro {
        font-variant: @introFontVariant;
        font-size: @introSize;
        line-height: @introLineHeight;
    } // End of .intro class

    .highlight {
        color: @textHighlight;
        font-weight: bold;
    } // End of .highlight class

} // End of paragraph rule

// Gets compiled to the following:
p {
    color: #222222;
    font-family: Helvetica, Arial, sans-serif;
    font-size: 14px;
    line-height: 21px;
}
p .intro {
    font-variant: small-caps;
    font-size: 16px;
    line-height: 24px;
}
p .highlight {
    color: #00214d;
    font-weight: bold;
}

                    

Using &

In the above example, if the CSS needs to read p.intro instead of p .intro, an ampersand (&) can be added prior to your nested rule. (when you want to target a .intro that is a paragraph element instead of targetting a .intro that is a descendant of a paragraph element).

// LESS for Paragraph
// ------------------

p {
    color: @textColor;
    font-family: @fontFamily;
    font-size: @fontSize;
    line-height: @lineHeight;

    &.intro {
        font-variant: @introFontVariant;
        font-size: @introSize;
        line-height: @introLineHeight;
    }

    .highlight {
        color: @textHighlight;
        font-weight: bold;
    }

}

// Results in the below when compiled
p {
    color: #222222;
    font-family: Helvetica, Arial, sans-serif;
    font-size: 14px;
    line-height: 21px;
}
p.intro {
    font-variant: small-caps;
    font-size: 16px;
    line-height: 24px;
}
p .highlight {
    color: #00214d;
    font-weight: bold;
}

                    

& is also used to assign pseudo-classes, like :hover

@link-color: #999;
@link-hover: #229ed3;

ul {
    margin: 0;

    li {
        float: left;
    }

    a {
        color: @link-color;

        &:hover {
            color: @link-hover;
        }
    }
}

//compiles to
ul { margin: 0; }
ul li { float: left; }
ul a { color: #999; }
ul a:hover { color: #229ed3; }

                    

Mixins

We can use Mixins to reuse whole declarations in a CSS rule set in another rule set.

// Variables
@baseFontSize: 14px;
@baseLineHeight: 21px;

.serif {
    font-family: Georgia, 'Times New Roman', serif;
}

p {
    font-size: @baseFontSize;
    line-height: @baseLineHeight;
    .serif;
}

                    

Gets compiled to the following:

.serif {
    font-family: Georgia, 'Times New Roman', serif;
}

p {
    font-size: 14px;
    line-height: 21px;
    font-family: Georgia, 'Times New Roman', serif;
}

                    

Parametric Mixins

Parametric Mixins can accept parameters.

.bordered (@width) {
    border: @width solid #ddd;

    &:hover {
        border-color: #999;
    }
}

h1 {
    .bordered(5px);
}

                    

Gets compiled to:

h1 { border: 5px solid #ddd; }
h1:hover { border-color: #999; }
                    

elements.less

If you are using CSS3 a lot in your website, you can use LESS Elements to make your job much easier. LESS Elements is a collection of common CSS3 Mixins that we may use often in stylesheets, such as border-radius, gradients, drop-shadow and so on. To use LESS Elements, simply add the @import rule in your LESS stylesheet after downloading it and adding it into your working directory.

@import "elements.less";

div {
    .rounded(3px);
}

                    

Operations

Less can bring math and calculations to your CSS. You can do operations on the numbers, colours and variables.

// Number
h1 {
    margin-bottom: 10px - 5px;
    margin-bottom: 10px - 5;
}

// Color
h1 {
    color: #888888 / 2;
}

// Variable
@h1-default-margin-bottom:  25px;
h1.tight {
    margin-bottom: @h1-default-margin-bottom - 10px
}

                    

Below are some colour functions built into Less.

lighten(@color, 10%);     // return a color which is 10% *lighter* than @color
darken(@color, 10%);      // return a color which is 10% *darker* than @color

saturate(@color, 10%);    // return a color 10% *more* saturated than @color
desaturate(@color, 10%);  // return a color 10% *less* saturated than @color

fadein(@color, 10%);      // return a color 10% *less* transparent than @color
fadeout(@color, 10%);     // return a color 10% *more* transparent than @color
fade(@color, 50%);        // return @color with 50% transparency

spin(@color, 10);         // return a color with a 10 degree larger in hue than @color
spin(@color, -10);        // return a color with a 10 degree smaller hue than @color

mix(@color1, @color2);    // return a mix of @color1 and @color2

                    

For a ful list of functions available in Less, visit http://lesscss.org/functions/

Extends

Extends are useful for sharing a generic definition with selectors rather than copying it in.

The following:

.block { margin: 10px 5px; }

p {
    &:extend(.block);
    border: 1px solid #eee;
}

ul, ol {
    &:extend(.block);
    color: #333;
    text-transform: uppercase;
}

                    

Gets compiled into the following:

.block, p, ul, ol { margin: 10px 5px; }

p { border: 1px solid #eee; }
ul, ol { color: #333; text-transform: uppercase; }

                    

Resources:

Less.js.org
An Introduction to CSS Pre-Processors
Learn LESS in 10 Minutes
Getting Started with Less

Block Element Modifier (BEM)

The Block, Element, Modifier methodology also known as BEM is a popular methodology for naming classes in HTML and CSS. In CSS everything is in the same, global scope which can cause problems and make CSS hard to maintain.

With BEM, instead of having random classes throughout the CSS file, you start organising your styles in Blocks. You can think of these blocks as objects or modules and the way encapsulation is achieved is by using -- or __ prefixes in the naming conventions.

In BEM, the B represents a Block of design e.g. container, form, sidebar. The E stands for Elements that are tied to its block e.g. header, title, form input. The M stands for Modifier which changes the styles or behaviour of the block or element.

Below is an example of using BEM style for writing CSS:

/* Block component, the parent */

.sidebar{
  /*styles in here */
}

/* Element, child items. Denoted by two underscores following the name of the block */

.sidebar__title{
  /*styles in here */
}

.sidebar__text{
  /*styles in here */
}

/* Modifier that changes the style of the block. Denoted by two hyphens following the name of the block */

.sidebar--left{
  /*styles in here */
}

.sidebar--right{
  /*styles in here */
}

.sidebar--big{
  /*styles in here */
}

.sidebar__text--red{
  /*styles in here */
}
                    

The following HTML uses the above CSS.

                      
<div class="sidebar sidebar--big sidebar--right">
    <h2 class="sidebar__title sidebar__text--red">Big Red Sidebar</h2>
    <p class="sidebar__text--red">Red Text here</p>
</div>
                      
                    

Resources

A practical introduction to the BEM CSS methodology
Quick start with BEM methodology
Learn CSS; BEM Methodology

PostCSS

PostCSS is a tool for processing CSS with JavaScript plugins. There are currently more than 200 plugins for PostCSS, many of which are listed on the PostCSS GitHub page. PostCSS can be integrated in most the build tools including Gulp, Grunt, webpack or npm.

PostCSS AutoPrefixer

Autoprefixer is one of the most popular PostCSS plugins. It is a CSS post processor that goes through (compiled) CSS files and adds or removes vendor prefixes after checking the code against caniuse.com. This means that you don’t have to write any vendor prefixes while writing CSS code.

Vendor prefixes are a way for browser makers to add support for newer CSS features that are still being experimented with. Once testing is done, browser makers will automatically remove the need for prefixes for that particular CSS property.

Autoprefixer By default, Autoprefixer will support the 2 latest versions of major browsers but you can easily set which browsers and versions to support in the configuration file.

a {
background: linear-gradient(to top, black, white);
display: flex
}

Is Transformed To:

a {
background: -webkit-linear-gradient(bottom, black, white);
background: linear-gradient(to top, black, white);
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex
}

                    

Gulp and PostCSS

Below is an example of how PostCSS can be used with Gulp.

// gulpfile.js
var cssnano = require('cssnano');
var postcss = require('gulp-postcss');
var gulp = require('gulp');
var autoprefixer = require('autoprefixer');

gulp.task('serve', ['css'], function() {
gulp.watch("./css/*.css", ['css']);
});

gulp.task('css', function() {
var plugin = [
autoprefixer(),
cssnano()
];
return gulp.src('./css/*.css')
.pipe(postcss(plugin))
.pipe(gulp.dest('./dest'));
});

gulp.task('default', ['serve']);

                    

Resources

PostCSS autoprefixer
An introduction to PostCSS
A PostCSS Tutorial to Empower your CSS

User Interface And Interaction Design

The goal of user interface design is to make the user's interaction as simple, pleasurable and efficient as possible.

Interface Elements

When designing your interface, try to be consistent and predictable in your choice of interface elements, users have become familiar with interface elements acting in a certain way.

Input Controls Include:

  • Checkboxes: usually best to presented in a vertical list. If the list is too long that scrolling is required or if comparison is required between items then it would be best to consider having more than one column.
  • Radio Buttons: allows users to select one item at a time.
  • Dropdown Lists: lets users to select one item at a time like radio buttons but allows you to save space. It is worth considering adding text to the first field like 'Select one' so users recognises the necessary action.
  • List boxes: like checkboxes it allows users to select multiple items but are more compact and can support a longer list of options.
  • Buttons: indicates an action upon touch and is typically labeled using text, an icon, or both.
  • Text fields: allow users to enter a single line or multiple lines of text.
  • Date Picker: allows users to select a date and/or time. By using the picker, the information is consistently formatted and input into the system.

Navigational Components include

  • Search Field: typically are single-line text boxes and are often accompanied by a search button.
  • Breadcrumbs: allow users to identify their current location within the system by providing a clickable trail of proceeding pages to navigate by.
  • Pagination: divides content up between pages, and allows users to skip between pages or go in order through the content.
  • Icons: simplified image serving as an intuitive symbol that is used to help users to navigate the system, typically hyperlinked.

Designing an Interface

  • Keep the interface simple as possible. Avoid unnecessary elements and use clear language on labels and messaging.
  • Use common UI elements so users feel more comfortable and are able to get things done more efficiently.
  • Consistency: create patterns in language, layout and design throughout the site. Once a user learns how to do something, they should be able to transfer that skill to other parts of the site.
  • Page layout: consider the spatial relationships between items on the page and structure the page based on importance. Careful placement of items can help draw attention to the most important pieces of information and can aid scanning and readability.
  • Colour and texture: You can direct attention towards items using color, light, contrast, and texture and use it to your advantage.
  • Use typography to create hierarchy and clarity: Different sizes, fonts, and arrangement of the text to help increase 'scanability' and readability.
  • System communication: Keep users informed of location, actions, changes in state, or errors. Use UI elements to communicate status and, if necessary, next steps can reduce frustration for your user.
  • Defaults: set defaults where possible to reduce burden on the user. This becomes particularly important when it comes to form design where you might have an opportunity to have some fields pre-chosen or filled out.

Resources

User Interface Design
Complete Beginner’s Guide to Interaction Design
Introducing Interaction Design

Website accessibility

Accessibility should be considered as part of every web project. As well as increasing availability to the widest possible audience, it is a legal requirement in many countries. In the UK for example, web accessibility falls under the Disability Discrimination Act and if your website fails to comply, legal action could be brought against you.

Some ways to improve accessibilty

Colours and contrast

Contrast ratio between the text and the background should be considered to increase readability. You can check the contrast ratio of multiple elements on a site using Juicy Studio’s Color Contrast Analyser Firefox extension. It will analyse each element on the page and provide a report on whether or not it conforms to the WAI’s guidelines.

A simple text link, styled red with no other decoration may be hard to see if it is within a block of grey or black text. You don’t need to stick with default link styling, but it is helpful to use more than one type of decoration such as an underline or background-color. A useful tool can be found at Colorblind Web Page Filter which provides several different filters that mimic how different types of colour-blind users would perceive a website.

Images

Images should all have descriptive alt text unless they are purely decorative where they should have either empty alt text or should be set as a CSS background image.

Site Navigation

All page functionality should be available using just the keyboard. When a user tabs through the web page, make sure that each section can be reached, and all possible user actions can be performed with the keyboard. The user should be able to navigate your site freely, without getting stuck in a loop, where they cannot navigate out or away.

By default, the order you list your elements on the page will be order of navigation. If you wish to change the order without changing the page structure, you can add tabindex on the element of your choice, and assign a number value to indicate the order in which this element should receive focus.

Links with an empty href attribute (or href="#") are not accessible by keyboard. This pattern is sometimes used in dropdown menus, etc. but because the links do not lead anywhere (they link to the current page) they are ignored in keyboard navigation.

Alt text for links should be included and a concise descriptor that clearly describes where the link leads should be chosen instead of ambiguous language like “click here”. If there is a validation error on any form field input, suggestions for how to correct the error should be provided to the user. All form inputs should have appropriate labels to indicate their purpose.

Users that use screen readers will often have the option to navigate a web page by skipping through the links to find something of interest. In the case of text links, the user would simply hear the word in isolation, regardless of the content that surrounds it. It is therefore extremely unhelpful when all that the user hears is ‘click here’ or ‘more’ – these types of links provide no information of where they direct the user or to what they are referring to. A much better option is to provide a more descriptive link. E.g. ‘learn more about S.E.O’ or ‘click here for the full article on S.E.O’.

Focus Indicators

All links, buttons, form fields, tool tips, menu items, etc. should include a focus indicator to allow users to navigate through your site with a keyboard. If you want to have control over when the focus indicator appears (for instance, only for keyboard users), the page Removing that ugly :focus ring (and keeping it too) outlines how to achieve this effect.

Skip Navigation Links

If a page contained a side bar with loads of links, without a skip navigation link, people using just the keyboard or screen readers to navigate would need to tab through each link in the sidebar every time the page reloads. Since there’s a lot links available, navigating through this section would be cumbersome. A skip navigation link is usually the first item in the DOM (Document Object Model) and when clicked, the keyboard focus is sent to the page element which contains the primary content of the page.

Resources

intro to web accessibility
accessibility freecodecamp guide
improving website accessibility
Chrome Accessibility Developer Tools

Cross Browser Testing

There is no way you can test on every combination of browser and device but instead you should try and make sure your site works on the most important target browsers and devices.

You should try and code "defensively" and build in intelligent fall-backs so that if a feature or style doesn't work in a browser, the site will be able to downgrade to something less exciting that still provides an acceptable user experience.

You can build up a chart of browsers and/devices and a common approach is to have multiple grades of support level. For example:

  • A grade: Common/modern browsers — known to be capable. Test thoroughly and provide full support.
  • B grade: Older/less capable browsers — known not to be capable. Test, and provide a more basic experience that gives full access to core information and services.
  • C grade: Rare/unknown browsers — don't test, but assume they are capable. Serve the full site, which should work, at least with the fallbacks provided by our defensive coding.
So, if you site is likely to get most views in Western Europe or North America, your chart could look like the following:
  • A grade: Chrome and Firefox for Windows/Mac, Safari for Mac, Edge and IE for Windows (last two versions of each), iOS Safari for iPhone/iPad, Android stock browser (last two versions) on phone/tablet, Chrome and Firefox for Android (last two versions) on phone/tablet
  • B grade: IE 9 for Windows.
  • C grade: n/a

Google Analytics

Google Analytics will give you accurate stats on exactly what browsers people are using to browse your site. Analytics history can be useful for finding support stats to influence say a new version of a company's site, or new features you are adding to an existing site.

Resources

MDN web docs Cross browser testing