tutorials/css - the complete guide/3. diving_deeper.md

9.6 KiB

Diving Deeper Into CSS

Introducing the CSS Box Model

 _______________________________________
|                                       |
|           margin (transparent)        |
|   _________________________________   |
|  |                                 |  |
|  |        border                   |  |
|  |   ___________________________   |  |
|  |  |                           |  |  |
|  |  |     padding               |  |  |
|  |  |   _____________________   |  |  |
|  |  |  |                     |  |  |  |
|  |  |  |  content            |  |  |  |
|  |  |  |_____________________|  |  |  |
|  |  |___________________________|  |  |
|  |_________________________________|  |
|_______________________________________|

          |    element width    |
|               box width               |

Understanding the CSS Box Model

#product-overview {
    background: red;
    padding: 20px;
    border-style: solid;
    border-color: black;
    border-width: 5px;
    margin: 20px;
}

Understanding Margin Collapsing And Removing Default Margins

To remove default margin applied by browser to body, we can set margin to 0 on body selector:

body {
    margin: 0px;
}

Margin Collapsing

If you have two elements beside each other, the margins between them collapses into single margin, the bigger margin gets prioritized.

Theory Time - Working With Shorthand Properties

Shorthand properties combine values of multiple properties in a single property (the shorthand property).

Shorthand for border property:

border: 2px dashed orange;

margin has couple of shorthands:

margin: 5px 10px 5px 10px;
margin: 5px 10px;
margin: 10px;

There are also a lot more shorthand properties that we use in the CSS.

Diving Into height And width Properties

Block level elements always takes the full width by default. We can change it using the width property:

width: 50%;

Height of an element is relative to the height of its container. So setting the height property to 100% won't make the element fill the whole screen.

We can use the %, px and other units with width and height properties that we will cover later.

Understanding Box Sizing

All elements by default happen to have a certain way of calculating width and height, which is called content box. By default if we set width and height, we set the width and height of the content, not including padding and border.

This is because the property box-sizing has the value content-box, we can change it to include padding and border by changing it's value to border-box.

box-sizing: border-box;

This property is so useful that it is often set as a default style for all the elements using the universal * selector. We don't apply this rule on body tag that applies the rules to all the child elements through inheritance because it is overriden by the browser. The universal selector targets every element on its own, overriding inheritance.

Adding Header to Our Project

Lets start by adding basic HTML elements to style as our header or navigation bar.

<header class="main-header">
    <div>
        <a href="index.html">
            uHost
        </a>
    </div>
    <nav>
        <ul>
            <li>
                <a href="packages/index.html">Packages</a>
            </li>
            <li>
                <a href="customers/index.html">Customers</a>
            </li>
            <li>
                <a href="start-hosting/index.html">Start Hosting</a>
            </li>
        </ul>
    </nav>
</header>

And now we can start styling it:

.main-header {
    width: 100%;
    background: #2ddf5c;
    padding: 8px 16px;
}

Understanding the display Property

The display property allows us to change the behavior of an element from block to inline or even to inline-block which is a mixture, we can also set it to none and the element will be removed from visible document flow.

inline-block mixes the behavior of inline and block level elements. Like inline elements, these elements can go next to each other now but they still behave like block level elemtents when it comes to setting top and bottom margin, setting paddings, things that are not possible on inline elements.

We will assign a class named main-nav__item to our list item <li> and add some styling to it to make it inline-block.

.main-nav__item {
    display: inline-block;
}

Applying display Property And Styling Our Navigation Bar

<body>
    <header class="main-header">
        <div>
            <a href="index.html">
                uHost
            </a>
        </div>
        <nav class="main-nav">
            <ul class="main-nav__items">
                <li class="main-nav__item">
                    <a href="packages/index.html">Packages</a>
                </li>
                <li class="main-nav__item">
                    <a href="customers/index.html">Customers</a>
                </li>
                <li class="main-nav__item">
                    <a href="start-hosting/index.html">Start Hosting</a>
                </li>
            </ul>
        </nav>
    </header>
    <main>
        <section id="product-overview">
            <h1>Get the freedom you deserve.</h1>
        </section>
        <section id="plans">
            <h1 class="section-title">Choose Your Plan</h1>
            <p>Make sure you get the most for your money!</p>
        </section>
    </main>
</body>
.main-header {
    width: 100%;
    background: #2ddf5c;
    padding: 8px 16px;
}

.main-header > div {
    display: inline-block;
}

.main-nav {
    display: inline-block;
    text-align: right;
    width: calc(100% - 49px);
}

.main-nav__items {
    margin: 0;
    padding: 0;
    list-style: none;
}

.main-nav__item {
    display: inline-block;
}

Understanding the inline-block Behavior

To display uHost and main-nav inlined blocks in the same line, we need to set the width of main-nav to calc(100% - 54px), which simply means the available width after subracting the width of uHost's div element. If we don't do this, even after setting their display property to inline-block, they will be displayed on different lines because of a stupid white space issue that we'll properly handler later.

.main-nav {
    display: inline-block;
    text-align: right;
    width: calc(100% - 54px);
}

Working With Text Decoration And Vertical Align

We can remove the default text decoration applied by the browser by using text-decoration: none;, which removes any default styles applied by the browser.

We can increase the font weight by using font-weight: bold; and the font size by using the font size property font-size: 22px;

The brand text and nav are now not vertically aligned because of the increased font size of brand text. We can vertically align the brand text and nav by setting the vertical-align property to middle on BOTH ELEMENTS.

.main-header > div {
    display: inline-block;
    vertical-align: middle;     // BRAND TEXT CONTAINER
}

.main-header__brand {
    color: #0e4f1f;
    text-decoration: none;
    font-weight: bold;
    font-size: 22px;
}

.main-nav {
    display: inline-block;
    text-align: right;
    width: calc(100% - 74px);
    vertical-align: middle;     // NAV BAR CONTAINER
}

.main-nav__items {
    margin: 0;
    padding: 0;
    list-style: none;
}

.main-nav__item {
    display: inline-block;
}

Styling Anchor Tags

We can use a combinator to apply the style to our anchor tags inside the list items.

.main-nav__item a {
    text-decoration: none;
    color: #0e4f1f;
}

Adding Pseudo Classes

We use pseudo classes to styles events like mouse hover or a click. For example to styles the anchor tag when hovered or clicked we can use the following rules:

.main-nav__item a:hover {
    color: white;
}

.main-nav__item a:active {
    color: white;
}

Theory Time - Pseudo Classes And Pseudo Elements

Pseudo Classes Pseudo Elements
Defines the style of a special state of an element Defines the style of a specific part of an element
:class name ::element name

Pseudo Classes

Used to style a special state of the element. For example :hover, :active and :focus etc.

Pseudo Elements

Used to style a specific part of an element. For example ::first-letter, ::after, etc.

Grouping Rules

We can group or combine multiple rules with same code into one to increase reusability:

.main-nav__item a:hover {
    color: white;
}

.main-nav__item a:active {
    color: white;
}

// CAN BE WRITTEN AS

.main-nav__item a:hover,
.main-nav__item a:active {
    color: white;
}

We can group as many rules as we need separated by a comma.

Working With Font Weight And Border

.main-nav__item a {
    font-weight: bold;
}

.main-nav__item a:hover,
.main-nav__item a:active {
    color: white;
    border-bottom: 5px solid white;
}

Adding And Styling A Call To Action Button

.main-nav__item--cta a {
    color: white;
    background: #ff1b68;
    padding: 8px 16px;
    border-radius: 8px;
}

.main-nav__item--cta a:hover,
.main-nav__item--cta a:active {
    color: #ff1b68;
    background: white;
    border: none;
}

Adding A Background Image To Our Project

Use the url("") function on background property to set a image. url takes in a string, which can be path to local file or a link to an image on internet.

background: url("image.jpg");

Properties Worth To Remember

color, background-color, display, padding, border, margin, width, height.