Skip to content

Latest commit

 

History

History
198 lines (163 loc) · 8.43 KB

readme.md

File metadata and controls

198 lines (163 loc) · 8.43 KB

Exercise 1 - The cascade, selectors, and specificity

This exercise will focus on tackling one of the most common challenges of CSS: selector specificity and the cascade. Since CSS by nature has a global scope, understanding specificity is fundamental in order to contol it.

The Cascade

The "cascade" part of the name cascading style sheet is in itself pretty simple: the order in which CSS rules are declared matter. The rules defined last in a stylesheet take precedence over the ones defined earlier.

selector1 {
  color: red;
}

selector2 {
  color: green;
}

selector3 {
  color: blue;
}

If all these selectors would target the same element, it's text color would be blue since the declarations in selector3 take precedence over the others due to it being applied last.

❗ However, the type of selector you use can override the order in which rules are specified.

In order to talk about selector specificity we should first talk about the main groups of selectors:

  • Element
  • Class
  • Pseudo class
  • Attribute
  • ID
  • Style attribute

Element

An element selctor is the most basic form of selector. Use the name of the corresponding HTML-element type you want to target, like <div>, <p>, <span>, <body> etc.

p {
  /* I target all paragraphs. But remember, I can be overwritten by declarations later in the style sheet */
}

Class

A class selector is something that is applied to an HTML-element using the class attribute: <div class="fancy-class">I have a class</div>. We use the "dot"(.) notation to target them in CSS. Different types of elements (<p>, <h1>, <div>) can have the same class slector, this is useful so that we can apply general styles to these elements cutting down the amount of css needed.

.fancy-class {
  // I'm a class rule!
}

.blue-background {
  background-color: blue; // I'm a class that makes all elements that utilize me have a blue background color!
}

Pseudo class

Pseudo classes are most often used to trigger specific styles on element states like when you hover over a link or focus on an element using tab on your keyboard. But a pseudo class can also target more abstract element properties like the first or last child within a parent element, or if the element is an "only-child", or even if the element does NOT contain another selector. Pseudo classes can be used by themselves, but are usually used in conjunction with another selector in order to not be too general. We use "colon"(:) notation to specify pseudo classes.

:hover {
  /* This is not a good, idea since this rule will apply to every element that you hover, 
     including the html document itself */
}

a:hover {
  /* This will apply to all links that are hovered */
}

.header:last-child {
  /* This will apply to the last element within a parent element with the class name ".header" */
}

.header:nth-child(odd) {
  /* This will apply to all odd child elements of a parent, useful for example to make zebra stripes on list items */
}

.header:not(.footer) {
  /* This rule will only apply to an element with the class ".header" if it does NOT also 
     have the class ".footer" */
}

Handy reference of all available pseudo classes

Attribute

Attribute selectors can be targeted towards all other HTML-element attributes than class (explained above) and id (explained later). Some common attributes to style would be the disabled attribute on a button element

<button disabled>Disabled button</button>

or a link based on the content of it's href attribute. Since we in HTML5 are allowed to create our own attributes on any element using the data- prefix

<div data-my-magic-attribute="I also have a value!">I have a custom attribute</div>

We could essentially use attributes like we would use classes (but please don't). We target attributes in CSS using "bracket"([]) notation. :exclamation: In attribute selectors we can even use pseudo-regular expressions to target attribute values

button[disabled] {
  /* Targets all button elements that have a disabled attribute */
}

a[href*="https://"] {
  /* Targets all external links that use the HTTPS protocol
     (* sybolises that "string starts with") */
}

[data-my-magic-attribute$="!"] {
  /* Targets all elements that have the custom attribute "data-my-magic-attribute"
     that has a value that ends with an exclamation point
     ($ sybolises that "string ends with") */
}

Id

The id selector are meant to target all HTML-elements that are unique. For the id tag to be considered valid by the browser the id must be unique to the whole HTML document. An example of an element with a id tag: <div id="unique-item">This item is unique</div>

Elements that tend to have ids are main sections of webpages such as the header, main content or the footer. Other specific elements such as input fields may have unique id's so that javascript functions can target them.

button#submit {
  /* Targets a button element that have a id="submit" -> <button id="submit">Submit</button> */
}

#menu li {
  /* Targets all li elements that are children to an element with the id="menu" */
}

The Id tag is more specific than targeting a class or element, and will overwrite previous styles applied to those elements. In the example below the second css rule that points towars p elements with the id "red-text" will overrule the previous one and turn that specific element red, while all other p elements will be blue.

p {
  color: blue;
}

p#red-text {
  color: red;
}

Style attribute

When styling HTML-elements you do not necessarily need to have a stylesheet, you can write (inline) styles inside a "style" attribute directly on the element itself, such as this: <p style="color: red">This text is red</p> This type of styling is regarded as bad practice, because the markup and content of the site should be separated from the styling.

  <div id="main-content">
    <h1 style="font-size: 64px; text-decoration: underline;">Underlined title element with font size of 64px</h1>
    <p style="color: red; font-weight: bold">A paragraph that is colored red and have font weight bold.</p>
  </div>

The example above contains a div with two elements "h1" and "p", separating the styles form the html would make the HTML more readable:

  <div id="main-content">
    <h1>Underlined title element with font size of 64px</h1>
    <p>A paragraph that is colored red and have font weight bold.</p>
  </div>
  h1 {
    font-size: 64px;
    text-decoration: underline;
  }
  
  p {
    color: red; 
    font-weight: bold;
  }

✏️ Tasks

First open index.html and styles.css in IntelliJ or another editor. Then, navigate to index.html in your standard file browser (e.g., Windows Explorer or Finder), and double click it to open the file in a web browser.

Remember to ask if you are stuck on these tasks, also MDN is a good resource.

Task 1

Change the color of the h1 element to red.

  h1 {
    /* insert color properties here */
  }

Task 2

Make another identical selector for h1 below the previous one and set the color to blue. See that it overrides the existing css rule above it. You should have two h1 selector at this point. :exclamation: this is not best practise but only for illustrating how the cascade works.

Task 3

Change the font for the entire HTML document to "Arial". Hint: use the property font-family.

Task 4

Notice that all images in the HTML have a class "image", create a new css rule for "image" at the bottom of the css window. Make the width and height 100px;

  .image {
    /* Create a rule like this and type your properties */
  }

Task 5

Make it so when you hover the checkboxes <input>, the cursor changes to a pointer 👆 , if you are unsure read the section on pseudo classes above. You can either target them by targeting all "input" elements or more specifically targeting elements with the attribute [type="checkbox"].

Task 6

Add a inline style attribute to the h1 header and add a property that puts the font-size at 50px;