Advanced HTML & CSS

Nordnet Academy

View on CodePen

You can do some pretty amazing stuff with only HTML & CSS today

HTML

Semantic HTML?

semantics (adj.)

  • of or relating to meaning, especially in language

  • the meaning or relationship of meanings of a sign or set of signs

Semantic html is using html to reinforce structural meaning. It’s about using tags, class names, and ids that reinforce the meaning of the content within the tags.

Why semantic HTML is important

Semantic html is an additional layer of communication. When you use semantic html you communicate more than when you use non-semantic html.

  • Cleaner code (Avoids divititis)

  • Easier to maintain said code

  • More accessible to a wider range of devices

  • Search engine friendly (Debatable)

An example

<div id="navWrapper">
  <div id="navList">
    <ul class="nav">
      <li class="navItem">Nav item 1</li>
      <li class="navItem">Nav item 2</li>
      <li class="navItem">Nav item 3</li>
      <li class="navItem">Nav item 4</li>
    </ul>
  </div>
</div>
<nav class="navigation-list">
  <ul>
    <li class="active">List item 1</li>
    <li>List item 2</li>
    <li>List item 3</li>
    <li>List item 4</li>
  </ul>
</nav>

Bad

Good

  • camelCase is for javascript!
  • Only use ID's if you're certain that ID will never ever occur on the same page.
  • Unnecessary wrappers.
  • spinal-case is for HTML.
  • Style nested elements to reduce collision risk when the same class names or ID's are used elsewhere.
  • Less classes keeps HTML clean and readable.

Class names and ID's should be structural, never presentational.

An example

.text-red {
  color: red;
}
.text-red {
  color: blue;
}
.text-danger {
  color: red;
}
.text-danger {
  color: blue;
}

6 months later...

Naming conventions

Concepts like BEM or SMACSS provide a good structure for the way you code. However, they can seem a bit complex and raise the barrier to entry.

.component {…}
.component-name {…}
.component-name-variant {…}

.component-name-variant.modifier {…}
.graph {…}
.graph-price {…}
.graph-price-volume {…}

.graph-price-volume.disabled {…}

These are some great general naming conventions:

CSS

Understanding the cascade

The CSS cascade assigns a weight to each style rule. When several rules apply, the one with the greatest weight takes precedence.

 

Order of preference for various styles:

  • Default browser style sheet (weakest)
  • Useragent style sheet
  • Author style sheet
  • Author embedded styles
  • Author inline styles (strongest)

Later styles over-rule earlier styles

If you define a style property, and later define an alternative style property for the same thing, the later definition over-rules the earlier one.

Styles can be inherited from a parent

Some styles, like font family, text-alignment etc., are automatically inherited by child elements from their parent element (i.e. by an element contained inside another one).

Others are not automatically inherited.

Style attribute

ID

Class and pseudo-class

Element

!important

Selector precedence

Selectors

There's a lot of them...

.class

.intro
// Selects all elements with class="intro"

#id

#firstname
// Selects the element with id="firstname"

*

*
// Selects all elements

element

p
// Selects all <p> elements

element, element

div, p
// Selects all <div> elements and all <p> elements

element element

div p
// Selects all <p> elements inside <div> elements

element > element

div > p
// Selects all <p> elements where the parent is a <div> element

element + element

div + p
// Selects all <p> elements that are placed immediately after <div> elements

element ~ element

p ~ ul
// Selects every <ul> element that is preceded by a <p> element

[attribute=value]

[target=_blank]
// Selects all elements with the target="_blank" attribute

[attribute~=value]

[title~=flower]
// Selects all elements with a title attribute containing the word "flower"

[attribute|=value]

[lang|=en]
// Selects all elements with a lang attribute value starting with "en"

[attribute^=value]

a[href^="https"]
// Selects every <a> element whose href attribute value begins with "https"

[attribute$=value]

a[href$=".pdf"]
// Selects every <a> element whose href attribute value ends with ".pdf"

[attribute*=value]

a[href*="nordnet"]
// Selects every <a> element whose href attribute value contains the substring "nordnet"

Pseudo-class Selectors

There's a lot of those too...

:active

a:active
// Selects the active link

::after

p::after
// Insert content after every <p> element

::before

p::before
// Insert content before the content of every <p> element

:checked

input:checked
// Selects every checked <input> element

:disabled

input:disabled
// Selects every disabled <input> element

:empty

p:empty
//Selects every <p> element that has no children (including text nodes)

:enabled

input:enabled
// Selects every enabled <input> element

:first-child

p:first-child
// Selects every <p> element that is the first child of its parent

::first-letter

p::first-letter
// Selects the first letter of every <p> element

::first-line

p::first-line
// Selects the first line of every <p> element

:first-of-type

p:first-of-type
// Selects every <p> element that is the first <p> element of its parent

:focus

input:focus
// Selects the input element which has focus

:hover

a:hover
// Selects links on mouse over

:in-range

input:in-range
// Selects input elements with a value within a specified range

:invalid

input:invalid
// Selects all input elemets with an invalid value

:lang(language)

p:lang(sv)
// Selects every <p> element with a lang attribute equal to "sv" (Swedish)

:last-child

p:last-child
// Selects every <p> element that is the last child of its parent

:last-of-type

p:last-of-type
// Selects every <p> element that is the last <p> element of its parent

:link

a:link
// Selects all unvisited links

:not(selector)

:not(p)
// Selects every element that is not a <p> element

:nth-child(an+b)

tr:nth-child(2n)
// Selects the even rows of a HTML table

:nth-last-child(an+b)

tr:nth-last-child(-n+4)
// Selects the last four rows of an HTML table.

:nth-last-of-type(an+b)

li:nth-last-of-type(2)
// Select the second-last list item

:nth-of-type(an+b)

p:nth-of-type(2)
// Selects every <p> element that is the second <p> element of its parent

:only-of-type

p:only-of-type
// Selects every <p> element that is the only <p> element of its parent

:only-child

p:only-child
// Selects every <p> element that is the only child of its parent

:optional

input:optional
// Selects input elements with no "required" attribute

:out-of-range

input:out-of-range
// Selects input elements with a value outside a specified range

:read-only

input:read-only
// Selects input elements with the "readonly" attribute specified

:read-write

input:read-write
// Selects input elements with the "readonly" attribute NOT specified

:required

input:required
// Selects input elements with the "required" attribute specified

:root

:root
// Selects the document's root element

:selection

::selection
// Selects the portion of an element that is selected by a user

:target

:target
// Selects a an element with and id when a URL ends in a hash with the same id

:valid

input:valid
// Selects all input elements with a valid value

:visited

a:visited
// Selects all visited links

Why did I show you all these?

Because you probably don't need javascript for that.

CSS with superpowers

Syntactically Awesome Style Sheets

CSS on its own can be fun, but stylesheets are getting larger, more complex, and harder to maintain.

This is where a preprocessor can help. Sass lets you use features that don't exist in CSS yet like variables, nesting, mixins, inheritance and other nifty goodies that make writing CSS easier and much more fun.

What does Sass give you?

A real world example

We needed UI components like these when building a winners & losers view in our new mobile apps.

View on CodePen

.list-item.indicator-positive-0:before {
  background: rgba(0, 168, 239, 0.9);
}
.list-item.indicator-positive-1:before {
  background: rgba(0, 168, 239, 0.8);
}
.list-item.indicator-positive-2:before {
  background: rgba(0, 168, 239, 0.7);
}
.list-item.indicator-positive-3:before {
  background: rgba(0, 168, 239, 0.6);
}
.list-item.indicator-positive-4:before {
  background: rgba(0, 168, 239, 0.5);
}
.list-item.indicator-negative-0:before {
  background: rgba(255, 104, 91, 0.9);
}
.list-item.indicator-negative-1:before {
  background: rgba(255, 104, 91, 0.8);
}
.list-item.indicator-negative-2:before {
  background: rgba(255, 104, 91, 0.7);
}
.list-item.indicator-negative-3:before {
  background: rgba(255, 104, 91, 0.6);
}
.list-item.indicator-negative-4:before {
  background: rgba(255, 104, 91, 0.5);
}

This would normally be a lot of CSS...

@mixin indicator-level($direction, $color) {
  @for $i from 0 through 4 {
    &.indicator-#{$direction}-#{$i} {
      &:before {
        background: rgba($color, (1 - (($i + 1) * 0.1)));
      }
    }
  }
}
.list-item {
  @include indicator-level(positive, #00a8ef);
  @include indicator-level(negative, #ff685b);
}

Sass mixin to the rescue!

Benefits of the mixin

  • Easier to maintain

  • Easier to generate more levels or other colours if necessary

  • Keeps the template for the rules in one place which inhibits inconsistencies between selectors

  • You can pass the mixin a hex colour and it converts it to rgba which saves you the headache of converting it

Questions?

Made with Slides.com