Nordnet Academy

View on CodePen

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.
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)
<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
.text-red {
color: red;
}.text-red {
color: blue;
}.text-danger {
color: red;
}.text-danger {
color: blue;
}6 months later...
.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:

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:
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.
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
.intro
// Selects all elements with class="intro"#firstname
// Selects the element with id="firstname"*
// Selects all elementsp
// Selects all <p> elementsdiv, p
// Selects all <div> elements and all <p> elementsdiv p
// Selects all <p> elements inside <div> elementsdiv > p
// Selects all <p> elements where the parent is a <div> elementdiv + p
// Selects all <p> elements that are placed immediately after <div> elementsp ~ ul
// Selects every <ul> element that is preceded by a <p> element[target=_blank]
// Selects all elements with the target="_blank" attribute[title~=flower]
// Selects all elements with a title attribute containing the word "flower"[lang|=en]
// Selects all elements with a lang attribute value starting with "en"a[href^="https"]
// Selects every <a> element whose href attribute value begins with "https"a[href$=".pdf"]
// Selects every <a> element whose href attribute value ends with ".pdf"a[href*="nordnet"]
// Selects every <a> element whose href attribute value contains the substring "nordnet"a:active
// Selects the active linkp::after
// Insert content after every <p> elementp::before
// Insert content before the content of every <p> elementinput:checked
// Selects every checked <input> elementinput:disabled
// Selects every disabled <input> elementp:empty
//Selects every <p> element that has no children (including text nodes)
input:enabled
// Selects every enabled <input> elementp:first-child
// Selects every <p> element that is the first child of its parentp::first-letter
// Selects the first letter of every <p> elementp::first-line
// Selects the first line of every <p> elementp:first-of-type
// Selects every <p> element that is the first <p> element of its parentinput:focus
// Selects the input element which has focusa:hover
// Selects links on mouse overinput:in-range
// Selects input elements with a value within a specified rangeinput:invalid
// Selects all input elemets with an invalid valuep:lang(sv)
// Selects every <p> element with a lang attribute equal to "sv" (Swedish)p:last-child
// Selects every <p> element that is the last child of its parentp:last-of-type
// Selects every <p> element that is the last <p> element of its parenta:link
// Selects all unvisited links:not(p)
// Selects every element that is not a <p> elementtr:nth-child(2n)
// Selects the even rows of a HTML tabletr:nth-last-child(-n+4)
// Selects the last four rows of an HTML table.
li:nth-last-of-type(2)
// Select the second-last list itemp:nth-of-type(2)
// Selects every <p> element that is the second <p> element of its parentp:only-of-type
// Selects every <p> element that is the only <p> element of its parentp:only-child
// Selects every <p> element that is the only child of its parentinput:optional
// Selects input elements with no "required" attributeinput:out-of-range
// Selects input elements with a value outside a specified rangeinput:read-only
// Selects input elements with the "readonly" attribute specifiedinput:read-write
// Selects input elements with the "readonly" attribute NOT specifiedinput:required
// Selects input elements with the "required" attribute specified:root
// Selects the document's root element::selection
// Selects the portion of an element that is selected by a user:target
// Selects a an element with and id when a URL ends in a hash with the same idinput:valid
// Selects all input elements with a valid valuea:visited
// Selects all visited linksBecause you probably don't need javascript for that.

CSS with superpowers
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.
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);
}@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);
}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