CSS

Submitted by sylvia.wong@up… on Mon, 01/31/2022 - 17:13
Sub Topics

Sass is an extension of CSS that adds power and elegance to the basic language.

Sass has features that do not currently exist in CSS, such as:

  • nesting
  • mixins
  • inheritance.

Sass basics 2020 explains when you use Sass, it will take your preprocessed Sass file and save it as a standard CSS file that you can use on your website.

Let’s explore what Sass is in 100 seconds with the video below.

To use Sass:

  1. Install
  2. Compile Sass to CSS using sass command by:
    • Telling Sass where to build from
    • Telling Sass where to output CSS to.

For example, running sass input.scss output.css from your terminal would take a single Sass file, input.scss, and compile that file to output.css.

Sass: Set up.

Use VSCode Live Sass Compiler extension, use a task runner or download a software tool like Prepros or Codekit.
sass-lang.com/install

You can watch individual files or directories with the –watch flag. The watch flag tells Sass to watch your source files for changes and re-compiles CSS:

Watch flag command Result
sass –watch input.scss output.css Watch your input.scss file.
sass –watch app/sass:public/stylesheets Watch your app/sass directory.

Nesting

HTML has a clear nested and visual hierarchy. CSS does not.

That is where nesting comes in. Nesting allows you to nest your CSS selectors in the same way HTML follows a visual hierarchy.

SCSS Sass CSS
nav {
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  li {
    display: inline-block;
  }

  a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;
  }
}
nav
  ul
    margin: 0
    padding: 0
    list-style: none


  li
    display: inline-block


  a
    display: block
    padding: 6px 12px
    text-decoration: none
nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

nav li {
  display: inline-block;
}

nav a {
  display: block;
  padding: 6px 12px;
  text-decoration: none;
}

Mixins

It can be tiresome to write some things in CSS. Mixins allow you to make a group of declarations that you want to reuse throughout your site.

You use the @mixin directive to create a mixin and give it a name. The example below has used theme.

SCSS Sass CSS
@mixin theme($theme: darkgray) {
  background: $theme;
  box-shadow: 0 0 1px rgba($theme, 0.25);
  color: #fff;
}

.info {
  @include theme;
}

.alert {
  @include theme(darkred);
}

.success {
  @include theme(darkgreen);
}
@mixin theme($theme: darkgray)
  background: $theme
  box-shadow: 0 0 1px rgba($theme, 0.25)
  color: #fff

.info
  @include theme

.alert
  @include theme(darkred)

.success
  @include theme(darkgreen)
.info {
  background: darkgray;
  box-shadow: 0 0 1px rgba(169, 169, 169, 0.25);
  color: #fff;
}

.alert {
  background: darkred;
  box-shadow: 0 0 1px rgba(139, 0, 0, 0.25);
  color: #fff;
}

.success {
  background: darkgreen;
  box-shadow: 0 0 1px rgba(0, 100, 0, 0.25);
  color: #fff;

}

Inheritance/extend

@extend allows you to share a set of CSS properties from one selector to another. A placeholder class is a special type of class that only prints when it is extended. It can help keep your CSS neat and clean.

Below is an example of simple series of messaging for errors, warnings and successes using another feature. This feature goes hand in hand with extend, placeholder classes.

SCSS Sass CSS
/* 
 * This CSS will print because
 * %message-shared is extended.
 */
%message-shared {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
}

// This CSS won't print because
// %equal heights isn't extended.
%equal-heights {
  display: flex;
  flex-wrap: wrap;
}

.message {
  @extend %message-shared;
}

.success {
  @extend %message-shared;
  border-color: green;
}

.error {
  @extend %message-shared;
  border-color: red;
}

.warning {
  @extend %message-shared;
  border-color: yellow;
}
/* 
 * This CSS will print because
 * %message-shared is extended.
 */
%message-shared
  border: 1px solid #ccc
  padding: 10px
  color: #333

// This CSS won't print because
// %equal heights isn't extended.
%equal-heights
  display: flex
  flex-wrap: wrap

.message
  @extend %message-shared

.success
  @extend %message-shared
  border-color: green

.error
  @extend %message-shared
  border-color: red

.warning
  @extend %message-shared
  border-color: yellow
/* 
 * This CSS will print because
 * %message-shared is extended.
 */
.message,
.success,
.error,
.warning {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
}

.success {
  border-color: green;
}

.error {
  border-color: red;
}

.warning {
  border-color: yellow;
}

Watch the video below to learn how to organise Sass when building a website.

Folder Structure

Use the project you have been working on and in the project’s public directory (the same place you have your css/js/etc. folders):

  1. Create an "scss" folder with folders (i.e. scss > abstracts, base, modules, layout, pages, themes, vendors ).
  2. Create main Sass file (i.e. scss > main.scss).
  3. Add an index partial file to each folder (i.e. _index.scss).
  4. Add imports for each index partial file to the scss > main.scss file (i.e. @import "abstracts/index";)
  5. Add scss files to each folder.
  6. In each folder’s index file, import the other scss files in the folder.

See sass-guidelin.es/#architecture to learn more about the 7 and 1 pattern.

Re-engineering a project to include Sass: Part 1

  1. Make sure the name of your main css file has the same name as your main scss file (i.e. "css/main.css" will correspond to the scss > main.scss file).
  2. Comment out the includes in scss > main.scss (we’ll use them later) and copy and paste the contents of the freelancer.css file below the comments.
  3. Use your transpiler (Koala, Prepros, Codekit, etc) to transpile the main.scss contents into the main.css file. The website should now show the styling.

Re-engineering a project to include Sass: Part 2

  1. Modularise the CSS in the scss > main.scss file into the the relevant scss files.
  2. Now, use Sass’s features to create a cleaner, more scalable and more maintainable code base (as you go, create variables in abstracts > variables.scss out of any globally used values.):
    1. Extract base styles to base folder.
    2. Extract main modules to the “modules” folder.
    3. Extract page (or main section if one page website) styles into pages folder.
    4. And so on…
    5. Create mixins, use nesting where appropriate, etc.
A close up of large CSS files in a developer's text editor

With CSS3 you can find an element based on (position, attribute, and state):

Position

Relational Selectors:

  • Descendant: E F
  • Child: E > F
  • Adjacent Sibling: E + F
  • General Sibling: E ~ F
Structural Pseudo-classes
:root The root element, which is always the html element.
E F:nth-child(n) The element F that is the nth child of its parent E.
E F:nth-last-child(n) The element F that is the nth child of its parent E, counting backwards from the last one. li:nth-last-child(1) would match the last item in any list - this is the same as li:last-child (see below).
E:nth-of-type(n) The element that is the nth element of its type in a given parent element.
E:nth-last-of-type(n) Like :nth-of-type(n), except counting backwards from the last element in a parent.
E:first-child The element E that is the first child E of its parent. This is the same as :nth-child(1).
E:last-child The element E that is the last child E of its parent, same as :nth-last-child(1).
E:first-of-type Same as :nth-of-type(1).
E:last-of-type Same as :nth-last-of-type(1).
E:only-child An element that’s the only child of its parent.
E:only-of-type An element that’s the only one of its type inside its parent element.
E:empty An element that has no children; this includes text nodes, so <p>hello</p> will not be matched.
E:not(exception) This is a particularly useful one: it will select elements that don’t match the selector in the parentheses. Selectors with the :not pseudo-class match everything to the left of the colon, and then exclude from that matched group the elements that also match what’s to the right of the colon. The left-hand side matching goes first. For example, p:not(.copyright) will match all the paragraphs in a document first, and then exclude all the paragraphs from the set that also have the class of copyright. You can string several :not pseudo-classes together. h2:not(header > h2):not(.logo) will match all h2 elements on a page except those that are in a header and those that have a class of .logo.1
Attributes
E[attr] Matches any element E that has the attribute attr with any value. We made use of this back in Chapter 4 to style required inputs—input:required works in 122 HTML5 & CSS3 for the Real World the latest browsers, but input[required] has the same effect and works in some slightly older ones.
E[attr="val"] Matches any element E that has the attribute attr with the exact, case-insensitive value val. While not new, it’s helpful in targeting form input types—for instance, target checkboxes with input[type="checkbox"].
E[attr|="val"] Matches any element E whose attribute attr either has the value "val" or begins with "val-". This is most commonly used for the lang attribute (as in lang="en-US"). For example, p[lang|="en"] would match any paragraph that has been defined as being in English, whether it be UK or US English.
E[attr~="val"] Matches any element E whose attribute attr has within its value the full word "val", surrounded by whitespace. For example, .info[title~="more"] would match any element with the class info that had a title attribute containing the word "more", such as "Click here for more information."
E[attr^="val"]
(IE8+, WebKit, Opera, Mozilla)
Matches any element E whose attribute attr starts with the value "val". In other words, the "val" matches the beginning of the attribute value.
E[attr$="val"]
(IE8+, WebKit, Opera, Mozilla)
Matches any element E whose attribute attr ends in "val". In other words, the "val" matches the end of the attribute value.
E[attr*="val"]
(IE8+, WebKit, Opera, Mozilla)
Matches any element E whose attribute attr matches val anywhere within the attribute. In other words, the string val is matched anywhere in the attribute value. It is similar to E[attr~="val"] above, except the val can be part of a word. Using the same example as above, .fakelink[title~="info"] would match any element with the class .fakelink that has a title attribute containing the string "info", such as "Click here for more information."1

State

CSS2 and below

:link, :visited, :hover, :active, and :focus.

CSS3

Pseudo-classes
:enabled A user interface element that’s enabled.
:disabled Conversely, a user interface element that’s disabled.
:checked Radio buttons or checkboxes that are selected or ticked.
:indeterminate Form elements that are neither checked nor unchecked. This pseudo-class is still being considered, and may be included in the specification in the future.
:target This selector singles out the element that is the target of the currently active intrapage anchor. That sounds more complicated than it is: you already know you can have links to anchors within a page by using the # character with the id of the target. For example, you may have href="#content">Skip tocontent</a> link in your page that, when clicked, will jump to the element with an id of content. This changes the URL in the address bar to thispage.html#content—and the :target selector now matches the #content element, as if you had included, temporarily, the selector #content. We say “temporarily” because as soon as the user clicks on a different anchor, :target will match the new target.
:default Applies to one or more UI elements that are the default among a set of similar elements.
:valid Applies to elements that are valid, based on the type or pattern attributes.
:invalid Applies to empty required elements, and elements failing to match the requirements defined by the type or pattern attributes.
:in-range Applies to elements with range limitations, where the value is within those limitations. This applies, for example, to number and range input types with min and max attributes.
:out-of-range The opposite of :in-range: elements whose value is outside the limitations of their range.
:required Applies to form controls that have the required attribute set.
:optional Applies to all form controls that do not have the required attribute.
:read-only Applies to elements whose contents are unable to be altered by the user. This is usually most elements other than form fields.
:read-write Applies to elements whose contents are user-alterable, such as text input fields.

Part of an element

Pseudo-elements
E::first-letter Match the first letter of a text node.
E::first-line Match the first line of a text node.

Insert content at a specific location

Pseudo-elements
E::before
E::after

Because you can absolutely position pseudo elements relative to their parent element, you can think of them as two extra layers to play with for every element. To generate content for a pseudo-element, use the content property: content: "";

To access an attribute of the selected element (CSS2) use attr(). For example:

<!-- HTML -->
<p data-foo="Hello">world!</p>

/* CSS */
p::before {
  content: attr(data-foo) " ";
}

Having easy to use navigation is an aspect that is look at from a UX design perspective. Navigation is about the easy of use and persuading users to go where the business needs them to go.

With CSS, you can transform HTML menus into cool navigation bars.
Navigation Bar = List of Links
A navigation bar needs standard HTML as a base.
A navigation bar is basically a list of links – using the ul and li elements makes sense.

<ul>
  <li><a href="default.asp">Home</a></li>
  <li><a href="news.asp">News</a></li>
  <li><a href="contact.asp">Contact</a></li>
  <li><a href="about.asp">About</a></li>
</ul>

Next, the bullets, margins and padding are removed from the list.

ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
}

list-style-type: none; - Removes the bullets. A navigation bar does not need list markers.

Set margin: 0; and padding: 0; to remove browser default settings.2

Now that we have covered the standard navigation code, we can be creative with vertical and horizontal navigation.

Vertical Navigation Bar

In addition to the code above, you can style the a elements inside the list to build a vertical navigation bar.

li a {
  display: block;
  width: 60px;
}

display: block; - Displaying the links as block elements makes the whole link area clickable (not just the text), and it allows us to specify the width (and padding, margin, height, etc. if you want)

width: 60px; - Block elements take up the full width available by default. We want to specify a 60px; width

You can set the width of <ul>, and remove the width of <a>. They will take up the full width available when displayed as block elements.

ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
  width: 60px;
}

li a {
  display: block;
}

Below is a basic vertical navigation bar with a grey background colour. The links will change colour when the user moves the mouse over.2

ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
  width: 200px;
  background-color: #f1f1f1;
}

li a {
  display: block;
  color: #000;
  padding: 8px 16px;
  text-decoration: none;
}

li a:hover {
  background-color: #555;
  color: white;
}

Horizontal navigation bar

A horizontal navigation bar can be created using inline or floating list items.

Inline List Items

Specify the <li> elements as inline. This in addition to the standard code explained above. display: inline; - By default, <li> elements are block elements. The example below removes the line breaks before and after each list item. This displays them on one line.

li {
  display: inline;
}

Floating List Items

Below is an example of how to float the <li> elements, and specify a layout for the navigation links.2

  • float: left; - Use float to get block elements to float next to each other
  • display: block; - Allows us to specify padding and height, width, margins.
  • padding: 8px; - Specify some padding between each <a> element, to make them look good
  • background-color: #ddd; - Add a gray background-color to each <a> element
ul {
  backround-color: #ddd;
}

Watch and try the tutorial below on building a responsive navigation bar.

A dual monitor setup on a desk, in a dimly-lit office

Chrome Developer Tools – Getting started

This project will be a chance for us to practice our technical skills. Imagine that you are a web designer in an agency and have been handed a project from the UX team.

The earlier stages of the UX process have been completed and you have access to the documentation.

For this documentation, use one of the UX Portfolios from

Behance or UXFolio, etc.

From a technical standpoint, the CSS in your project should:

  • have a browser reset and any default styles
  • be well commented and structured (generic to specific
  • follow a CSS methodology (be modular and reusable)
  • have a low specificity
  • have no unnecessarily repeated styles
  • use CSS3 Flexbox or Grid for layout

The HTML should:

  • be initially generated from boilerplate
  • be formatted
  • use HTML5 semantic tags (like "section", "footer", etc.)

The site/app should:

  • be responsive (if it's a mobile app, design for tablets as well)
  • contain some micro-interactions

 

CSS Grid is a two-dimensional layout for the web. It allows you to layout columns and grids by defining their relationships (in terms of size, position, and layer).

The horizontal and vertical lines create a pattern that can align design elements. This means your elements will not move around and change as you move from page to page. 

A grid will have columns, rows, and then gaps between each row and column. These gaps are called gutters.

A diagram depicting CSS Grids
Adapted from 'Grids by MDN Web Docs', ©Mozilla.
  1. Columns
  2. Gutters

Grid Layout

The first step is to decide on the grid that your design needs. The grid is created on 12 columns. To begin, you need to decide how many columns your content will take up (out of 12).

Columns should be nested in a row class, or you may choose to nest rows in a container class. 

Below is an example code of 3, 6 and 9 out of 12 columns.

<div class="container">
  <div class="col-3">
    <!-- This content will take up 3/12 (or 1/4) of the container -->
  </div>
  <div class="col-6">
    <!-- This content will take up 6/12 (or 1/2) of the container -->
  </div>
  <div class="col-9">
    <!-- This content will take up 9/12 (or 3/4) of the container -->
  </div>
</div>

Below is an example of a three-column track grid with new rows created at a minimum of 100px and a maximum of auto. 

HTML

<div class="wrapper">
  <div class="one">One</div>
  <div class="two">Two</div>
  <div class="three">Three</div>
  <div class="four">Four</div>
  <div class="five">Five</div>
  <div class="six">Six</div>
</div>

CSS

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  grid-auto-rows: minmax(100px, auto);
}

.one {
  grid-column: 1 / 3;
  grid-row: 1;
}

.two {
  grid-column: 2 / 4;
  grid-row: 1 / 3;
}

.three {
  grid-column: 1;
  grid-row: 2 / 5;
}

.four {
  grid-column: 3;
  grid-row: 3;
}

.five {
  grid-column: 2;
  grid-row: 2;
}

.six {
  grid-column: 3;
  grid-row: 4;
}

All CSS grid properties

Property Description
column-gap Specifies the gap between the columns
gap A shorthand property for the row-gap and the column-gap properties
grid A shorthand property for the grid-template-rows, grid-template-columns, grid-template-areas, grid-auto-rows, grid-auto-columns, and the grid-auto-flow properties
grid-area Either specifies a name for the grid item, or this property is a shorthand property for the grid-row-start, grid-column-start, grid-row-end, and grid-column-end properties
grid-auto-columns Specifies a default column size
grid-auto-flow Specifies how auto-placed items are inserted in the grid
grid-auto-rows Specifies a default row size
grid-column A shorthand property for the grid-column-start and the grid-column-end properties
grid-column-end Specifies where to end the grid item
grid-column-gap Specifies the size of the gapbetween columns
grid-column-start Specifies where to start the grid item
grid-gap A shorthand property for the grid-row-gap and grid-column-gap properties
grid-row A shorthand property for the grid-row-start and the grid-row-end properties
grid-row-end Specifies where to end the grid item
grid-row-gap Specifies the size of the gap between rows
grid-row-start Specifies where to start the grid item
grid-template A shorthand property for the grid-template-rows, grid-template-columns and grid-areas properties
grid-template-areas Specifies how to display columns and rows, using named grid items
grid-template-columns Specifies the size of the columns, and how many columns are in a grid layout
grid-template-rows Specifies the size of the rows in a grid layout
row-gap Specifies the gap between the grid rows

Defining a grid

Begin with this code:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="uf-8">
  <title>CSS Grid starting point</title>
  <style>
    body {
      width: 90%;
      max-width: 900px;
      margin: 2em auto;
      font: 0.9em / 1.2 Arial, Helvetica, sans-serif;
    }

    .container > div {
      grid-column: 1 / 3;
      border-radius: 5px;
      padding: 10px;
      background-color: rgb(207, 232, 220);
      border: 2px auto rgb(79, 185, 227);
    }
  </style>
</head>

<body>
  <div class="container">
    <h1>Simple grid example</h1>
    <div>One</div>
    <div>Two</div>
    <div>Three</div>
    <div>Four</div>
    <div>Five</div>
    <div>Six</div>
  </div>
</body>

</html>

The example above has a container, with child items.

By default, these will display the normal flow.

We use the grid value of the display property to define a grid. This enables Grid Layout. Meaning all the direct children of the container become grid items.

Add the CSS file:

.container {
  display: grid;
}

These items will not look different immediately. Declaring display: grid; gives you a one-column grid.

Add more columns to see something resembling the grid. Add the CSS below to create three 200px columns.3

.container {
  display: grid;
  grid-template-columns: 200px 200px 200px;
}

Flexible Grids

Flexible grids create a responsive site. Previously a site was built to a particular size, such as a desktop. If that site was accessed via a mobile, it would look disorientated and magnified.

That was before Ethan Marcotte invented the term responsive design in 2010.

This term describes a combination of three techniques:

  1. Fluid grids
  2. Fluid images
  3. Media query.

A flexible grid means that you do not need to manually add every screen size your site will be viewed on. Instead you input a percentage.

Marcotte developed the formula to convert the normal pixels layout design, and convert it into a percentage.

For example:

target / context = result
}

If the target column size is 60px, and the container it is in is 960px, you divide 60 by 960 to work out the value that will be used in the CSS.

For example:

.col {
  width: 6.25%; /* 60 / 960 = 0.0625 */
}

Follow along with the video below to try out building a grid. 

There are layout methods that are responsive by default. They create an easier way to make a flexible grid.

There are three modern layout methods that do this:

  1. Flexbox
  2. Multiple-column layout (multicol)
  3. Grid.

Flexbox

The flexbox, or flexible box layout module, allows you to create a responsive layout without using float or positioning.

Flexbox is used to create a row or a column axis layout.

The content will shrink and distribute space between the items according to the space in their container.

You can indicate how you would like the items to behave towards the space around them with the values:

  1. flex-grow
  2. flex-shrink

To begin, set up a special value of display on the parent element you want to affect.

The example below is set on <section>:

section {
  display: flex;
}

The section element will become a flex container and its children will become flex items.

Multiple-column layout (Multicol)

Multicol allows you to take a lump of content and spread it across multiple columns. Think of it like a newspaper.

A column-count can indicate how many columns you want to spread your content across.

The browser will adjust the size of the column to the user's screen size.

.container {
  column-count: 3;
}

A column-width indicates the minimum width. The browser will automatically create as many columns at your specified width, to comfortably fit into the container. The remaining space will be shared out between all columns. The number of columns will change according to how much space there is.

.container {
  column-width: 10em;
}

Grid

As explained above, grids allow content to be distributed across the grid tracks.  

Jen Simmons

Jen is the creator of an experimental layout lab.

Jen explores what is possible with graphic design on the web.

Explore her channel below for inspiration.

Module Linking
Main Topic Image
A developer working through the presentation layer of a new website feature, using CSS
Is Study Guide?
Off
Is Assessment Consultation?
Off