Skip to content

Latest commit

 

History

History
2189 lines (1932 loc) · 46.2 KB

7.-advanced-css-and-sass.md

File metadata and controls

2189 lines (1932 loc) · 46.2 KB

6. Advanced CSS & Sass

Theory

Three pillars

  • Responsive design
    • Fluid layouts
    • Media queries
    • Responsive images
    • Correct units
    • Desktop-first vs mobile-first
  • Maintainable and scalable code
    • Clean
    • Easy-to-understand
    • Growth
    • Reusable
    • How to organise files
    • How to name classes
    • How to structure HTML
  • Web performance
    • Less HTTP requests
    • Less code
    • Compress code
    • Use a CSS preprocessor (like Sass)
    • Less images
    • Compress images

What happens to CSS when we load up a webpage

!Important should not be used instead specificity is important thing to understand.

Project - Natours

Header 1

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <link
      href="https://fonts.googleapis.com/css?family=Lato:100,300,400,700,900"
      rel="stylesheet"
    />

    <link rel="stylesheet" href="css/icon-font.css" />
    <link rel="stylesheet" href="css/style.css" />
    <link rel="shortcut icon" type="image/png" href="img/favicon.png" />

    <title>Natours | Exciting tours for adventurous people</title>
  </head>
  <body>
    <header class="header">Some text...</header>
  </body>
</html>
  • (*) is universal selector it will select all elements (not a good idea to put font in it though use body and inherit every element through it)
  • In cover (size mode) image doesn't stretch it gets cropped background-position tells from where it should be so top means it gets cropped from bottom and top remains static.
  • Background image has gradient first then below it an image
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: "Lato", sans-serif;
  font-weight: 400;
  font-size: 16px;
  line-height: 1.7;
  color: #777;
  padding: 30px;
}

.header {
  height: 95vh;
  background-image: linear-gradient(
      to right bottom,
      rgba(126, 213, 111, 0.8),
      rgb(40, 180, 133, 0.8)
    ),
    url(../img/hero.jpg);
  background-size: cover;
  background-position: top;
  clip-path: polygon(0 0, 100% 0, 100% 75vh, 0 100%);
}

Header 2

Both main and sub-heading are kept inside h1 because h1 is taken by search engines so it's a good practice.

<body>
  <header class="header">
    <div class="logo-box">
      <img src="img/logo-white.png" alt="Logo" class="logo" />
    </div>

    <div class="text-box">
      <h1 class="heading-primary">
        <span class="heading-primary-main">Outdoors</span>
        <span class="heading-primary-sub">is where life happens</span>
      </h1>
    </div>
  </header>
</body>
  • Absolute position takes top and left with-respect to the parent relative element (here we made .header as relative for that purpose)
.header {
  ...
  position: relative;
}

.logo-box {
  position: absolute;
  top: 40px;
  left: 40px;
}

.logo {
  height: 35px;
}

.text-box {
  position: absolute;
  top: 40%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.heading-primary {
  color: #fff;
  text-transform: uppercase;
}

.heading-primary-main {
  display: block;
  font-size: 60px;
  font-weight: 400;
  letter-spacing: 35px;
}

.heading-primary-sub {
  display: block;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: 17.4px;
}

Heading Animation

Animate heading-primary-main and heading-primary-sub

@keyframes moveInLeft {
  0% {
    opacity: 0;
    transform: translateX(-100px);
  }
  80% {
    transform: translateX(10px);
  }
  100% {
    opacity: 1;
    transform: translateX(0px);
  }
}

@keyframes moveInRight {
  0% {
    opacity: 0;
    transform: translateX(100px);
  }
  80% {
    transform: translateX(-10px);
  }
  100% {
    opacity: 1;
    transform: translateX(0px);
  }
}

Then in css selector for heading-primary-main and sub add animation: moveInLeft 1s ease-out; and moveInRight. Ease-out is basically a function telling start fast then slow.

Also put backface-visibility: hidden; inside heading-primary. This basically fix some glitches due to animation (always put inside parent of animated element)

Button Animation 1

<a href="#" class="btn btn-white">Discover our tours</a>
.btn:link,
.btn:visited {
  text-transform: uppercase;
  text-decoration: none;
  padding: 15px 40px;
  display: inline-block;    // without this padding was not applied properly
  border-radius: 100px;
  transition: all 0.2s;    // transition all states with animation
}

.btn:hover {
  transform: translateY(-3px);
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
}

.btn:active {
  transform: translateY(-1px);
  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
}

.btn-white {
  background-color: #fff;
  color: #777;
}

Button Animation 2

<a href="#" class="btn btn-white btn-animated">Discover our tours</a>
@keyframes moveInBottom {
  0% {
    opacity: 0;
    transform: translateY(30px);
  }
  100% {
    opacity: 1;
    transform: translateX(0px);
  }
}

.btn:link,
.btn:visited {
  text-transform: uppercase;
  text-decoration: none;
  padding: 15px 40px;
  display: inline-block;
  border-radius: 100px;
  transition: all 0.2s;
  position: relative;
}

.btn:hover {
  transform: translateY(-3px);
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
}

.btn:active {
  transform: translateY(-1px);
  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
}

.btn-white {
  background-color: #fff;
  color: #777;
}

.btn::after {
  content: "";
  display: inline-block;
  height: 100%;
  width: 100%;
  border-radius: 100px;
  position: absolute;
  top: 0;
  left: 0;
  z-index: -1;
  transition: all 0.4s;
}

.btn-white::after {
  background-color: #fff;
}

.btn:hover::after {
  transform: scaleX(1.4) scaleY(1.6);
  opacity: 0;
}

.btn-animated {
  animation: moveInBottom 0.5s ease-out 0.75s;
  animation-fill-mode: backwards;
}

after creates same button, we are putting it absolute (so need to make original button relative) after has z-index -1 so it will be at back creating an scaling animation effect

Easy trick to make responsive

Refractor every pixel unit to rem and define rem in html selector

html {
  font-size: 10px;
}

Change every px unit (divide it by 10 and add rem). Benefit of this is, for smaller screen just add media query to change this 10px and everything will resize accordingly so this is the best practice.

Instead of 10px put 100/16 * 10 = 62.5%.
100% means 16px (default font size) we want 10 so 62.5%

BEM naming convention

Body__Entity--Modifier

Refractored HTML

<body>
  <header class="header">
    <div class="header__logo-box">
      <img src="img/logo-white.png" alt="Logo" class="header__logo" />
    </div>

    <div class="header__text-box">
      <h1 class="heading-primary">
        <span class="heading-primary--main">Outdoors</span>
        <span class="heading-primary--sub">is where life happens</span>
      </h1>

      <a href="#" class="btn btn--white btn--animated">Discover our tours</a>
    </div>
  </header>
</body>

Sass

Sass is a CSS preprocessor, an extension of CSS that adds power and elegance to the basic language. Sass compiler gives compiled CSS code. so instead of writing css for larger project write sass.

There's Sass and SCSS. Sass is indent specific like python SCSS (called sassy css) have braces much better to visualize.

// Use variables
$color-primary: #f9ed69
nav {
    background-color: $color-primary;
}

// Nested selector (selecting .navigation li)
.navigation {
    li {
        ...
        // this is .navigation li:last-child
        &:last-child {    // or first-child
        }
    }
    li:first-child {        // or last-child
        ...
    }
}

If there's a element (say nav) which has 2 child divs one is float left other is float right then the height of parent element becomes zero (so any background color style is reset now) to fix this.

nav {
    ...
    &::after {
        content: "";
        clear: both;
        display: table;
    }
}

In general use case above clearfix might be applied multiple places, so code duplication is a mess therefore create a mixin & reuse it

@mixin clearfix {
    &::after {
        content: "";
        clear: both;
        display: table;
    }
}

nav {
    ...
    @include clearfix;
}

/* It can be done for inside properties of selector aswell in same way.
We can also pass arguments to mixin like: */
@mixin style-link-text($color) {
    text-decoration: none;
    text-transform: uppercase;
    color: $color;
}

a:link {
    ...
    @include style-link-text($color-text-dark);
}

Sass has built in darken & lighten function

background-color: darken($color-secondary, 15%);

We can create our own functions

@function divide($a, $b) {
    @return $a / $b;
}

Using Sass through npm

run npm initi then install npm i node-sass --save-dev say if you want jQuery npm i jquery --save

Add this script then run it (-w flag will watch changes and generate css

"scripts": {
    "compile:sass": "node-sass sass/main.scss css/style.css -w"
},

sudo npm i live-server -g Then run live-server

Nested Sass vs Without nested

Without nested

$color-primary: #55c57a;
$color-primary-light: #7ed56f;
$color-primary-dark: #28b485;
$color-dark-grey: #777;
$color-white: #fff;
$color-black: #000;

* {
  margin: 0;
  padding: 0;
  box-sizing: inherit;
}

html {
  font-size: 62.5%;
}

body {
  font-family: "Lato", sans-serif;
  font-weight: 400;
  font-size: 1.6rem;
  line-height: 1.7;
  color: $color-dark-grey;
  padding: 3rem;
  box-sizing: border-box;
}

.header {
  height: 95vh;
  background-image: linear-gradient(
      to right bottom,
      rgba($color-primary-light, 0.8),
      rgba($color-primary-dark, 0.8)
    ),
    url(../img/hero.jpg);
  background-size: cover;
  background-position: top;
  clip-path: polygon(0 0, 100% 0, 100% 75vh, 0 100%);
  position: relative;
}

.header__logo-box {
  position: absolute;
  top: 4rem;
  left: 4rem;
}

.header__logo {
  height: 3.5rem;
}

.header__text-box {
  position: absolute;
  top: 40%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
}

.heading-primary {
  color: $color-white;
  text-transform: uppercase;
  backface-visibility: hidden;
  margin-bottom: 6rem;
}

.heading-primary--main {
  display: block;
  font-size: 6rem;
  font-weight: 400;
  letter-spacing: 3.5rem;
  animation: moveInLeft 1s ease-out;
}

.heading-primary--sub {
  display: block;
  font-size: 2rem;
  font-weight: 700;
  letter-spacing: 1.75rem;
  animation: moveInRight 1s ease-out;
}

@keyframes moveInLeft {
  0% {
    opacity: 0;
    transform: translateX(-10rem);
  }
  80% {
    transform: translateX(1rem);
  }
  100% {
    opacity: 1;
    transform: translateX(0rem);
  }
}

@keyframes moveInRight {
  0% {
    opacity: 0;
    transform: translateX(10rem);
  }
  80% {
    transform: translateX(-1rem);
  }
  100% {
    opacity: 1;
    transform: translateX(0rem);
  }
}

@keyframes moveInBottom {
  0% {
    opacity: 0;
    transform: translateY(3rem);
  }
  100% {
    opacity: 1;
    transform: translateX(0rem);
  }
}

.btn:link,
.btn:visited {
  text-transform: uppercase;
  text-decoration: none;
  padding: 1.5rem 4rem;
  display: inline-block;
  border-radius: 10rem;
  transition: all 0.2s;
  position: relative;
}

.btn:hover {
  transform: translateY(-0.3rem);
  box-shadow: 0 1rem 2rem rgba($color-black, 0.2);
}

.btn:active {
  transform: translateY(-0.1rem);
  box-shadow: 0 0.5rem 1rem rgba($color-black, 0.2);
}

.btn--white {
  background-color: $color-white;
  color: $color-dark-grey;
}

.btn::after {
  content: "";
  display: inline-block;
  height: 100%;
  width: 100%;
  border-radius: 10rem;
  position: absolute;
  top: 0;
  left: 0;
  z-index: -1;
  transition: all 0.4s;
}

.btn--white::after {
  background-color: $color-white;
}

.btn:hover::after {
  transform: scaleX(1.4) scaleY(1.6);
  opacity: 0;
}

.btn--animated {
  animation: moveInBottom 0.5s ease-out 0.75s;
  animation-fill-mode: backwards;
}

With nested, there's a 5 folder rule so create these folder inside sass folder and main.scss file

mkdir abstracts && cd abstracts && touch _functions.scss _mixins.scss _variables.scss && cd ../
mkdir base && cd base && touch _animations.scss _base.scss _typography.scss _utilities.scss && cd ../
mkdir components layout pages
/////////////////////// main.scss ///////////////////////

@import "abstracts/functions";
@import "abstracts/mixins";
@import "abstracts/variables";

@import "base/animations";
@import "base/base";
@import "base/typography";
@import "base/utilities";

@import "components/button";

@import "layout/header";

@import "pages/home.scss";

/////////////////////// _variables.scss ///////////////////////
$color-primary: #55c57a;
$color-primary-light: #7ed56f;
$color-primary-dark: #28b485;

$color-dark-grey: #777;
$color-white: #fff;
$color-black: #000;

/////////////////////// _animations.scss ///////////////////////
@keyframes moveInLeft {
  0% {
    opacity: 0;
    transform: translateX(-10rem);
  }
  80% {
    transform: translateX(1rem);
  }
  100% {
    opacity: 1;
    transform: translateX(0rem);
  }
}

@keyframes moveInRight {
  0% {
    opacity: 0;
    transform: translateX(10rem);
  }
  80% {
    transform: translateX(-1rem);
  }
  100% {
    opacity: 1;
    transform: translateX(0rem);
  }
}

@keyframes moveInBottom {
  0% {
    opacity: 0;
    transform: translateY(3rem);
  }
  100% {
    opacity: 1;
    transform: translateX(0rem);
  }
}

/////////////////////// _base.scss ///////////////////////
*,
*::after,
*::before {
  margin: 0;
  padding: 0;
  box-sizing: inherit;
}

html {
  font-size: 62.5%;
}

body {
  box-sizing: border-box;
}

/////////////////////// _typography.scss ///////////////////////
body {
  font-family: "Lato", sans-serif;
  font-weight: 400;
  font-size: 1.6rem;
  line-height: 1.7;
  color: $color-dark-grey;
  padding: 3rem;
}

.heading-primary {
  color: $color-white;
  text-transform: uppercase;
  backface-visibility: hidden;
  margin-bottom: 6rem;

  &--main {
    display: block;
    font-size: 6rem;
    font-weight: 400;
    letter-spacing: 3.5rem;
    animation: moveInLeft 1s ease-out;
  }
  &--sub {
    display: block;
    font-size: 2rem;
    font-weight: 700;
    letter-spacing: 1.75rem;
    animation: moveInRight 1s ease-out;
  }
}

/////////////////////// components/_button.scss ///////////////////////
.btn {
  &:link,
  &:visited {
    text-transform: uppercase;
    text-decoration: none;
    padding: 1.5rem 4rem;
    display: inline-block;
    border-radius: 10rem;
    transition: all 0.2s;
    position: relative;
  }
  &:hover {
    transform: translateY(-0.3rem);
    box-shadow: 0 1rem 2rem rgba($color-black, 0.2);

    &::after {
      transform: scaleX(1.4) scaleY(1.6);
      opacity: 0;
    }
  }
  &:active {
    transform: translateY(-0.1rem);
    box-shadow: 0 0.5rem 1rem rgba($color-black, 0.2);
  }
  &--white {
    background-color: $color-white;
    color: $color-dark-grey;

    &::after {
      background-color: $color-white;
    }
  }
  &::after {
    content: "";
    display: inline-block;
    height: 100%;
    width: 100%;
    border-radius: 10rem;
    position: absolute;
    top: 0;
    left: 0;
    z-index: -1;
    transition: all 0.4s;
  }
  &--animated {
    animation: moveInBottom 0.5s ease-out 0.75s;
    animation-fill-mode: backwards;
  }
}

/////////////////////// layout/_header.scss ///////////////////////
.header {
  height: 95vh;
  background-image: linear-gradient(
      to right bottom,
      rgba($color-primary-light, 0.8),
      rgba($color-primary-dark, 0.8)
    ),
    url(../img/hero.jpg);
  background-size: cover;
  background-position: top;
  clip-path: polygon(0 0, 100% 0, 100% 75vh, 0 100%);
  position: relative;

  &__logo-box {
    position: absolute;
    top: 4rem;
    left: 4rem;
  }
  &__logo {
    height: 3.5rem;
  }
  &__text-box {
    position: absolute;
    top: 40%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
  }
}

Projects - Natours (Continuted)

Custom Bootstrap style .row .col

layout/_grid.scss

.row {
  max-width: $grid-width;
  background-color: #eee;
  margin: 0 auto;

  &:not(:last-child) {
    margin-bottom: $gutter-vertical;
  }

  @include clearfix;
  // use ^ for starting with, * contains, $ ends with
  [class^="col-"] {  // this selects all class with name starting with col-
    background-color: red;
    float: left;

    &:not(:last-child) {
      margin-right: $gutter-horizontal;
    }
  }

  .col-1-of-2 {
    width: calc((100% - #{$gutter-horizontal}) / 2);
  }
  .col-1-of-3 {
    width: calc((100% - 2 * #{$gutter-horizontal}) / 3);
  }
  .col-2-of-3 {
    width: calc(
      2 * ((100% - 2 * #{$gutter-horizontal}) / 3) + #{$gutter-horizontal}
    );
  }
  .col-1-of-4 {
    width: calc((100% - 3 * #{$gutter-horizontal}) / 4);
  }
  .col-2-of-4 {
    width: calc(
      2 * ((100% - 3 * #{$gutter-horizontal}) / 4) + #{$gutter-horizontal}
    );
  }
  .col-3-of-4 {
    width: calc(
      3 * ((100% - 3 * #{$gutter-horizontal}) / 4) + 2 * #{$gutter-horizontal}
    );
  }
}

_mixins.scss

@mixin clearfix {
  &::after {
    content: "";
    display: table;
    clear: both;
  }
}

About Section

  • main, section tag is good for SEO
<main>
  <section class="section-about">
    <div class="u-center-text u-margin-bottom-large">
      <h2 class="heading-secondary">
        Exciting tours for adventurous peoples
      </h2>
    </div>

    <div class="row">
      <div class="col-1-of-2">
        <h3 class="heading-tertiary u-margin-bottom-small">
          You're going to fall in love with nature
        </h3>
        <p class="paragraph">
          Lorem, ipsum dolor sit amet consectetur adipisicing elit. Ratione
          corrupti nam, eligendi repellendus rerum sequi pariatur! Omnis
          quas eius illum odit, commodi ea facere atque nemo alias veniam,
          quibusdam ipsam!
        </p>

        <h3 class="heading-tertiary u-margin-bottom-small">
          Live adventures like never before
        </h3>
        <p class="paragraph">
          Lorem ipsum dolor sit amet consectetur adipisicing elit.
          Veritatis, accusantium a nam repellat molestias dolorem soluta
          reprehenderit recusandae.
        </p>

        <a href="#" class="btn-text">Learn more &rarr;</a>
      </div>
      <div class="col-1-of-2">
        <div class="composition">
          <img
            src="img/nat-1-large.jpg"
            alt="Photo 1"
            class="composition__photo composition__photo--p1"
          />
          <img
            src="img/nat-2-large.jpg"
            alt="Photo 2"
            class="composition__photo composition__photo--p2"
          />
          <img
            src="img/nat-3-large.jpg"
            alt="Photo 3"
            class="composition__photo composition__photo--p3"
          />
        </div>
      </div>
    </div>
  </section>
</main>

_composition.scss

.composition {
  position: relative;

  &__photo {
    width: 55%;
    box-shadow: 0 1.5rem 4rem rgba($color-black, 0.4);
    border-radius: 2px;
    position: absolute;
    z-index: 10;
    transition: all 0.2s;
    outline-offset: 2rem;

    &--p1 {
      left: 0;
      top: -2rem;
    }
    &--p2 {
      right: 0;
      top: 2rem;
    }
    &--p3 {
      left: 20%;
      top: 10rem;
    }
    &:hover {
      outline: 1.5rem solid $color-primary;
      transform: scale(1.05);
      box-shadow: 0 2.5rem 4rem rgba($color-black, 0.5);
      z-index: 20;
    }
  }

  &:hover &__photo:not(:hover) {
    transform: scale(0.95);
  }
}

_typography.scss

body {
  font-family: "Lato", sans-serif;
  font-weight: 400;
  font-size: $default-font-size;
  line-height: 1.7;
  color: $color-dark-grey;
  padding: 3rem;
}

.heading-primary {
  color: $color-white;
  text-transform: uppercase;
  backface-visibility: hidden;
  margin-bottom: 6rem;

  &--main {
    display: block;
    font-size: 6rem;
    font-weight: 400;
    letter-spacing: 3.5rem;
    animation: moveInLeft 1s ease-out;
  }
  &--sub {
    display: block;
    font-size: 2rem;
    font-weight: 700;
    letter-spacing: 1.75rem;
    animation: moveInRight 1s ease-out;
  }
}

.heading-secondary {
  font-size: 3.5rem;
  text-transform: uppercase;
  font-weight: 700;
  display: inline-block;
  background-image: linear-gradient(
    to right,
    $color-primary-light,
    $color-primary-dark
  );
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
  letter-spacing: 0.2rem;
  transition: all 0.2s;

  &:hover {
    transform: skewY(2deg) skewX(15deg) scale(1.1);
    text-shadow: 0.5rem 1rem 2rem rgba($color-black, 0.2);
  }
}

.heading-tertiary {
  font-size: $default-font-size;
  font-weight: 700;
  text-transform: uppercase;
}

.paragraph {
  font-size: $default-font-size;

  &:not(:last-child) {
    margin-bottom: 3rem;
  }
}

Features Section

<section class="section-features">
  <div class="row">
    <div class="col-1-of-4">
      <div class="feature-box">
        <i class="feature-box__icon icon-basic-world"></i>
        <h3 class="heading-tertiary u-margin-bottom-small">
          Explore the world
        </h3>
        <p class="feature-box__text">
          Lorem ipsum, dolor sit amet consectetur adipisicing elit. Magnam
          ad, iure suscipit quo qui ipsum maxime praesentium illo non.
        </p>
      </div>
    </div>

    <div class="col-1-of-4">
      <div class="feature-box">
        <i class="feature-box__icon icon-basic-compass"></i>
        <h3 class="heading-tertiary u-margin-bottom-small">
          Meet Nature
        </h3>
        <p class="feature-box__text">
          Lorem ipsum, dolor sit amet consectetur adipisicing elit. Magnam
          ad, iure suscipit quo qui ipsum maxime praesentium illo non.
        </p>
      </div>
    </div>

    <div class="col-1-of-4">
      <div class="feature-box">
        <i class="feature-box__icon icon-basic-map"></i>
        <h3 class="heading-tertiary u-margin-bottom-small">
          Find Your Way
        </h3>
        <p class="feature-box__text">
          Lorem ipsum, dolor sit amet consectetur adipisicing elit. Magnam
          ad, iure suscipit quo qui ipsum maxime praesentium illo non.
        </p>
      </div>
    </div>

    <div class="col-1-of-4">
      <div class="feature-box">
        <i class="feature-box__icon icon-basic-heart"></i>
        <h3 class="heading-tertiary u-margin-bottom-small">
          Live a Healthier Life
        </h3>
        <p class="feature-box__text">
          Lorem ipsum, dolor sit amet consectetur adipisicing elit. Magnam
          ad, iure suscipit quo qui ipsum maxime praesentium illo non.
        </p>
      </div>
    </div>
  </div>
</section>

_feature-box.scss

.feature-box {
  background-color: rgba($color-white, 0.8);
  font-size: 1.5rem;
  padding: 2.5rem;
  text-align: center;
  border-radius: 3px;
  box-shadow: 0 1.5rem 4rem rgba($color-black, 0.15);
  transition: transform 0.3s;

  &__icon {
    font-size: 6rem;
    margin-bottom: 0.5rem;
    display: inline-block;
    background-image: linear-gradient(
      to right,
      $color-primary-light,
      $color-primary-dark
    );
    background-clip: text;
    -webkit-background-clip: text;
    color: transparent;
  }
  &:hover {
    transform: translateY(-1.5rem) scale(1.03);
  }
}

_home.scss

.section-features {
  padding: 20rem 0;
  background-image: linear-gradient(
      to right bottom,
      rgba($color-primary-light, 0.8),
      rgba($color-primary-dark, 0.8)
    ),
    url(../img/nat-4.jpg);
  background-size: cover;
  transform: skewY(-7deg);
  margin-top: -10rem;

  & > * {    // selects all direct child  
    transform: skewY(7deg);
  }
}

Tours section

<section class="section-tours">
  <div class="u-center-text u-margin-bottom-large">
    <h2 class="heading-secondary">Most popular tours</h2>
  </div>

  <div class="row">
    <div class="col-1-of-3">
      <div class="card">
        <div class="card__side card__side--front">
          <div class="card__picture card__picture--1">&nbsp;</div>
          <h4 class="card__heading">
            <span class="card__heading-span card__heading-span--1">
              The Sea Explorer
            </span>
          </h4>
          <div class="card__details">
            <ul>
              <li>3 day tours</li>
              <li>Up to 30 people</li>
              <li>2 tour guides</li>
              <li>Sleep in cozy hotels</li>
              <li>Difficulty: easy</li>
            </ul>
          </div>
        </div>
        <div class="card__side card__side--back card__side--back-1">
          <div class="card__cta">
            <div class="card__price-box">
              <p class="card__price-only">Only</p>
              <p class="card__price-value">$297</p>
            </div>
            <a href="#" class="btn btn--white">Book now!</a>
          </div>
        </div>
      </div>
    </div>
    <div class="col-1-of-3">
      <div class="card">
        <div class="card__side card__side--front">
          <div class="card__picture card__picture--2">&nbsp;</div>
          <h4 class="card__heading">
            <span class="card__heading-span card__heading-span--2">
              The Forest Hiker
            </span>
          </h4>
          <div class="card__details">
            <ul>
              <li>7 day tours</li>
              <li>Up to 40 people</li>
              <li>6 tour guides</li>
              <li>Sleep in provided tents</li>
              <li>Difficulty: medium</li>
            </ul>
          </div>
        </div>
        <div class="card__side card__side--back card__side--back-2">
          <div class="card__cta">
            <div class="card__price-box">
              <p class="card__price-only">Only</p>
              <p class="card__price-value">$497</p>
            </div>
            <a href="#" class="btn btn--white">Book now!</a>
          </div>
        </div>
      </div>
    </div>
    <div class="col-1-of-3">
      <div class="card">
        <div class="card__side card__side--front">
          <div class="card__picture card__picture--3">&nbsp;</div>
          <h4 class="card__heading">
            <span class="card__heading-span card__heading-span--3">
              The Snow Adventurer
            </span>
          </h4>
          <div class="card__details">
            <ul>
              <li>5 day tours</li>
              <li>Up to 15 people</li>
              <li>3 tour guides</li>
              <li>Sleep in provided tents</li>
              <li>Difficulty: hard</li>
            </ul>
          </div>
        </div>
        <div class="card__side card__side--back card__side--back-3">
          <div class="card__cta">
            <div class="card__price-box">
              <p class="card__price-only">Only</p>
              <p class="card__price-value">$897</p>
            </div>
            <a href="#" class="btn btn--white">Book now!</a>
          </div>
        </div>
      </div>
    </div>
  </div>

  <div class="u-center-text u-margin-top-huge">
    <a href="#" class="btn btn--green">Discover all tours</a>
  </div>
</section>

_card.scss

.card {
  perspective: 150rem;
  -moz-perspective: 150rem;
  position: relative;
  height: 50rem;

  &__side {
    transition: all 0.8s ease;
    position: absolute;
    height: 100%;
    top: 0;
    left: 0;
    width: 100%;
    backface-visibility: hidden;
    border-radius: 3px;
    box-shadow: 0 1.5rem 4rem rgba($color-black, 0.15);
    overflow: hidden;

    &--front {
      background-color: $color-white;
    }
    &--back {
      transform: rotateY(180deg);

      &-1 {
        background-image: linear-gradient(
          to right bottom,
          $color-secondary-light,
          $color-secondary-dark
        );
      }
      &-2 {
        background-image: linear-gradient(
          to right bottom,
          $color-primary-light,
          $color-primary-dark
        );
      }
      &-3 {
        background-image: linear-gradient(
          to right bottom,
          $color-tertiary-light,
          $color-tertiary-dark
        );
      }
    }
  }

  &:hover &__side--front {
    transform: rotateY(-180deg);
  }
  &:hover &__side--back {
    transform: rotateY(0);
  }
  &__picture {
    background-size: cover;
    height: 23rem;
    background-blend-mode: screen;
    -webkit-clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%);
    clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%);
    border-top-left-radius: 3px;
    border-top-right-radius: 3px;

    &--1 {
      background-image: linear-gradient(
          to right bottom,
          $color-secondary-light,
          $color-secondary-dark
        ),
        url(../img/nat-5.jpg);
    }
    &--2 {
      background-image: linear-gradient(
          to right bottom,
          $color-primary-light,
          $color-primary-dark
        ),
        url(../img/nat-6.jpg);
    }
    &--3 {
      background-image: linear-gradient(
          to right bottom,
          $color-tertiary-light,
          $color-tertiary-dark
        ),
        url(../img/nat-7.jpg);
    }
  }

  &__heading {
    font-size: 2.8rem;
    font-weight: 300;
    text-transform: uppercase;
    text-align: right;
    color: $color-white;
    position: absolute;
    top: 12rem;
    right: 2rem;
    width: 75%;
  }
  &__heading-span {
    padding: 1rem 1.5rem;
    -webkit-box-decoration-break: clone;
    box-decoration-break: clone;

    &--1 {
      background-image: linear-gradient(
        to right bottom,
        $color-secondary-light,
        $color-secondary-dark
      );
    }
    &--2 {
      background-image: linear-gradient(
        to right bottom,
        $color-primary-light,
        $color-primary-dark
      );
    }
    &--3 {
      background-image: linear-gradient(
        to right bottom,
        $color-tertiary-light,
        $color-tertiary-dark
      );
    }
  }
  &__details {
    padding: 3rem;

    ul {
      list-style: none;
      width: 80%;
      margin: 0 auto;

      li {
        text-align: center;
        font-size: 1.5rem;
        padding: 1rem;

        &:not(:last-child) {
          border-bottom: 1px solid $color-light-grey-2;
        }
      }
    }
  }
  &__cta {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 90%;
    text-align: center;
  }
  &__price-box {
    text-align: center;
    color: $color-white;
    margin-bottom: 8rem;
  }
  &__price-only {
    font-size: 1.4rem;
    text-transform: uppercase;
  }
  &__price-value {
    font-size: 6rem;
    font-weight: 100;
  }
}

_home.scss

.section-tours {
  background-color: $color-light-grey-1;
  padding: 25rem 0 15rem 0;
  margin-top: -10rem;
}

Stories section

Background video, round image, text is curved, blur image on hover

<section class="section-stories">
  <div class="bg-video">
    <video class="bg-video__content" autoplay muted loop>
      <source src="img/video.mp4" type="video/mp4" />
      <source src="img/video.webm" type="video/webm" />
      Your browser is not supported!
    </video>
  </div>

  <div class="u-center-text u-margin-bottom-large">
    <h2 class="heading-secondary">We make people genuinely happy</h2>
  </div>
  <div class="row">
    <div class="story">
      <figure class="story__shape">
        <img
          class="story__img"
          src="img/nat-8.jpg"
          alt="Person on a tour"
        />
        <figcaption class="story__caption">Mary Smith</figcaption>
      </figure>
      <div class="story__text">
        <h3 class="heading__tertiary u-margin-bottom-small">
          I had a best week with my family
        </h3>
        <p>
          Lorem, ipsum dolor sit amet consectetur adipisicing elit.
          Deserunt ut omnis doloremque vel veniam maxime earum,
          perspiciatis magni expedita obcaecati eos repellendus
          voluptates, a sapiente molestias rem dolorem ullam alias!
        </p>
      </div>
    </div>
  </div>
  <div class="row">
    <div class="story">
      <figure class="story__shape">
        <img
          class="story__img"
          src="img/nat-9.jpg"
          alt="Person on a tour"
        />
        <figcaption class="story__caption">Jack Wilson</figcaption>
      </figure>
      <div class="story__text">
        <h3 class="heading__tertiary u-margin-bottom-small">
          Wow my life is completely different now
        </h3>
        <p>
          Lorem, ipsum dolor sit amet consectetur adipisicing elit.
          Deserunt ut omnis doloremque vel veniam maxime earum,
          perspiciatis magni expedita obcaecati eos repellendus
          voluptates, a sapiente molestias rem dolorem ullam alias!
        </p>
      </div>
    </div>
  </div>

  <div class="u-center-text u-margin-top-huge">
    <a href="" class="btn-text">Read all stories &rarr;</a>
  </div>
</section>

_bg-video.scss

.bg-video {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  opacity: 0.15;
  overflow: hidden;

  &__content {
    height: 100%;
    width: 100%;
    object-fit: cover;
  }
}

_home.scss

.section-stories {
  position: relative;
  padding: 15rem 0;
}

_story.scss

.story {
  width: 75%;
  margin: 0 auto;
  box-shadow: 0 3rem 6rem rgba($color-black, 0.1);
  background-color: rgba($color-white, 0.6);
  border-radius: 3px;
  padding: 6rem;
  padding-left: 9rem;
  font-size: $default-font-size;
  transform: skewX(-12deg);

  &__shape {
    width: 15rem;
    height: 15rem;
    float: left;
    -webkit-shape-outside: circle(50% at 50% 50%);
    shape-outside: circle(50% at 50% 50%);
    -webkit-clip-path: circle(50% at 50% 50%);
    clip-path: circle(50% at 50% 50%);
    transform: translateX(-3rem) skewX(12deg);
    overflow: hidden;
  }
  &__img {
    height: 100%;
    width: 100%;
    transform: scale(1.4);
    transition: all 0.5s;
  }
  &__text {
    transform: skewX(12deg);
  }
  &__caption {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, 20%);
    color: $color-white;
    text-transform: uppercase;
    font-size: 1.7rem;
    text-align: center;
    opacity: 0;
    transition: all 0.5s;
    backface-visibility: hidden;
  }
  &:hover &__caption {
    opacity: 1;
    transform: translate(-50%, -50%);
  }
  &:hover &__img {
    transform: scale(1);
    filter: blur(3px) brightness(80%);
  }
}

Booking Section

<section class="section-booking">
  <div class="row">
    <div class="book">
      <div class="book__form">
        <form action="#" class="form">
          <div class="u-margin-bottom-large">
            <h2 class="heading-secondary">Start booking now</h2>
          </div>

          <div class="form__group">
            <input
              type="text"
              class="form__input"
              placeholder="Full Name"
              id="name"
              required
            />
            <label for="name" class="form__label">Full Name</label>
          </div>
          <div class="form__group">
            <input
              type="email"
              class="form__input"
              placeholder="Email address"
              id="email"
              required
            />
            <label for="email" class="form__label">Email address</label>
          </div>

          <div class="form__group u-margin-bottom-medium">
            <div class="form__radio-group">
              <input
                type="radio"
                class="form__radio-input"
                id="small"
                name="size"
              />
              <label for="small" class="form__radio-label">
                <span class="form__radio-button"></span>
                Small tour group
              </label>
            </div>
            <div class="form__radio-group">
              <input
                type="radio"
                class="form__radio-input"
                id="large"
                name="size"
              />
              <label for="large" class="form__radio-label">
                <span class="form__radio-button"></span>
                Large tour group
              </label>
            </div>
          </div>

          <div class="form__group">
            <button class="btn btn--green">Next step &rarr;</button>
          </div>
        </form>
      </div>
    </div>
  </div>
</section>

_form.scss

.form {
  &__group:not(:last-child) {
    margin-bottom: 2rem;
  }
  &__input {
    display: block;
    font-size: 1.5rem;
    font-family: inherit;
    color: inherit;
    padding: 1.5rem 2rem;
    border-radius: 2px;
    background-color: rgba($color-white, 0.5);
    border: none;
    border-bottom: 3px solid transparent;
    width: 90%;
    transition: all 0.3s;

    &:focus {
      outline: none;
      box-shadow: 0 1rem 2rem rgba($color-black, 0.1);
      border-bottom: 3px solid $color-primary;
    }
    &:focus:invalid {
      border-bottom: 3px solid $color-secondary-dark;
    }
    &::-webkit-input-placeholder {
      color: #999;
    }
  }
  &__label {
    font-size: 1.2rem;
    font-weight: 700;
    margin-left: 2rem;
    margin-top: 0.7rem;
    display: block;
    transition: all 0.3s;
  }
  &__input:placeholder-shown + &__label {
    opacity: 0;
    visibility: hidden;
    transform: translateY(-4rem);
  }
  &__radio-group {
    width: 40%;
    display: inline-block;
  }
  &__radio-input {
    display: none;
  }
  &__radio-label {
    font-size: $default-font-size;
    cursor: pointer;
    position: relative;
    padding-left: 4.5rem;
  }
  &__radio-button {
    height: 3rem;
    width: 3rem;
    border: 5px solid $color-primary;
    border-radius: 50%;
    display: inline-block;
    position: absolute;
    left: 0;
    top: -0.4rem;

    &::after {
      content: "";
      display: block;
      height: 1.3rem;
      width: 1.3rem;
      border-radius: 50%;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background-color: $color-primary;
      opacity: 0;
      transition: opacity 0.2s;
    }
  }
  &__radio-input:checked ~ &__radio-label &__radio-button::after {
    opacity: 1;
  }
}

Navigation

Checkbox hack, full screen navigation animation

https://easings.net/

<div class="navigation">
  <input type="checkbox" class="navigation__checkbox" id="navi-toggle" />
  <label for="navi-toggle" class="navigation__button">
    <span class="navigation__icon">&nbsp;</span>
  </label>
  <div class="navigation__background">&nbsp;</div>
  <nav class="navigation__nav">
    <ul class="navigation__list">
      <li class="navigation__item">
        <a href="#" class="navigation__link"><span>01</span>About Natous</a>
      </li>
      <li class="navigation__item">
        <a href="#" class="navigation__link"
          ><span>02</span>Your benefits</a
        >
      </li>
      <li class="navigation__item">
        <a href="#" class="navigation__link"
          ><span>03</span>Popular tours</a
        >
      </li>
      <li class="navigation__item">
        <a href="#" class="navigation__link"><span>04</span>Stories</a>
      </li>
      <li class="navigation__item">
        <a href="#" class="navigation__link"><span>05</span>Book now</a>
      </li>
    </ul>
  </nav>
</div>

_navigation.scss

.navigation {
  &__checkbox {
    display: none;
  }
  &__button {
    background-color: $color-white;
    height: 7rem;
    width: 7rem;
    position: fixed;
    top: 6rem;
    right: 6rem;
    border-radius: 50%;
    z-index: 2000;
    box-shadow: 0 1rem 3rem rgba($color-black, 0.1);
    text-align: center;
    cursor: pointer;
  }
  &__background {
    height: 6rem;
    width: 6rem;
    border-radius: 50%;
    position: fixed;
    top: 6.5rem;
    right: 6.5rem;
    background-image: radial-gradient(
      $color-primary-light,
      $color-primary-dark
    );
    z-index: 1000;
    transition: transform 0.8s cubic-bezier(0.83, 0, 0.17, 1);
  }
  &__nav {
    height: 100vh;
    width: 100%;
    position: fixed;
    top: 0;
    right: 0;
    z-index: 1500;
    opacity: 0;
    width: 0;
    transition: all 0.8s;
  }
  &__list {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    list-style: none;
    text-align: center;
  }
  &__item {
    margin: 1rem;
  }
  &__link {
    &:link,
    &:visited {
      display: inline-block;
      font-size: 3rem;
      font-weight: 300;
      color: $color-white;
      padding: 1rem 2rem;
      text-decoration: none;
      text-transform: uppercase;
      background-image: linear-gradient(
        120deg,
        transparent 0%,
        transparent 50%,
        $color-white 50%
      );
      background-size: 250%;
      transition: all 0.4s;

      span {
        margin-right: 1rem;
        display: inline-block;
      }
    }
    &:hover,
    &:active {
      background-position: 100%;
      color: $color-primary;
      transform: translateX(1rem);
    }
  }
  &__checkbox:checked ~ &__background {
    transform: scale(80);
  }
  &__checkbox:checked ~ &__nav {
    opacity: 1;
    width: 100%;
  }
  &__icon {
    position: relative;
    margin-top: 3.5rem;

    &,
    &::before,
    &::after {
      width: 3rem;
      height: 2px;
      background-color: #333;
      display: inline-block;
    }
    &::before,
    &::after {
      content: "";
      position: absolute;
      left: 0;
      transition: all 0.2s;
    }
    &::before {
      top: -0.8rem;
    }
    &::after {
      top: 0.8rem;
    }
  }
  &__button:hover &__icon::before {
    top: -1rem;
  }
  &__button:hover &__icon::after {
    top: 1rem;
  }
  &__checkbox:checked + &__button &__icon {
    background-color: transparent;
  }
  &__checkbox:checked + &__button &__icon::before {
    top: 0;
    transform: rotate(135deg);
  }
  &__checkbox:checked + &__button &__icon::after {
    top: 0;
    transform: rotate(-135deg);
  }
}

Book now popup

<div class="popup" id="popup">
  <div class="popup__content">
    <div class="popup__lef">
      <img src="img/nat-8.jpg" alt="Tour photo" class="popup__img" />
      <img src="img/nat-9.jpg" alt="Tour photo" class="popup__img" />
    </div>
    <div class="popup__right">
      <a href="#section-tours" class="popup__close">&times;</a>
      <h2 class="heading-secondary u-margin-bottom-small">Start booking</h2>
      <h3 class="heading-tertiary u-margin-bottom-small">
        Important &ndash; Please read these terms before booking
      </h3>
      <p class="popup__text">
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est fuga
        cupiditate, minus sunt veritatis, nobis odio veniam provident eos
        illo repellat nostrum quasi, officiis quas accusantium voluptatem
        eligendi eveniet! Iure. Lorem ipsum dolor sit amet consectetur
        adipisicing elit. Quidem optio dignissimos alias officiis pariatur.
        Doloremque et nihil repellendus ab molestias commodi odio asperiores
        unde atque iusto, distinctio illum officiis obcaecati!
      </p>
      <a href="#" class="btn btn--green">Book now</a>
    </div>
  </div>
</div>

_popup.scss

.popup {
  height: 100vh;
  width: 100vw;
  position: fixed;
  top: 0;
  left: 0;
  background-color: rgba($color-black, 0.8);
  z-index: 9999;
  opacity: 0;
  visibility: hidden;
  transition: all 0.3s;

  &__content {
    @include absCenter;
    width: 75%;
    background-color: $color-white;
    box-shadow: 0 2rem 4rem rgba($color-black, 0.2);
    border-radius: 3px;
    display: table;
    overflow: hidden;
    opacity: 0;
    transform: translate(-50% -50%) scale(0.5);
    transition: all 0.4s;
  }
  &__left {
    width: 33.3333%;
    display: table-cell;
  }
  &__right {
    width: 66.6667%;
    display: table-cell;
    vertical-align: middle;
    padding: 3rem 5rem;
  }
  &__img {
    display: block;
    width: 100%;
  }
  &__text {
    font-size: 1.4rem;
    margin-bottom: 4rem;
    column-count: 2;
    column-gap: 4rem;
    column-rule: 1px solid $color-light-grey-2;
    hyphens: auto;
  }
  &:target {
    opacity: 1;
    visibility: visible;
  }
  &:target &__content {
    opacity: 1;
    transform: translate(-50% -50%) scale(0.5);
  }
  &__close {
    &:link,
    &:visited {
      color: #777;
      position: absolute;
      top: 2.5rem;
      right: 2.5rem;
      font-size: 3rem;
      text-decoration: none;
      display: inline-block;
      transition: all 0.2s;
      line-height: 1;
    }
    &:hover {
      color: $color-primary;
    }
  }
}

Responsiveness

_mixin.scss

// MEDIA QUERY MANAGER
/*
0-600px:      Phone
600-900px:    Tablet portrait
900-1200px:   Tablet landscape
1200-1800px:  Is where our normal style apply
1800px+:      Big desktop
1em = 16px

$breakpoint argument choices:
- phone
- tab-port
- tab-land
- big-desktop

ORDER: Base + typography > general layout + grid > page layout > components
*/
@mixin respond($breakpoint) {
  @if $breakpoint == phone {
    // 600px
    @media (max-width: 37.5em) {
      @content;
    }
  }
  @if $breakpoint == tab-port {
    // 900px
    @media (max-width: 56.25em) {
      @content;
    }
  }
  @if $breakpoint == tab-land {
    // 1200px
    @media (max-width: 75em) {
      @content;
    }
  }
  @if $breakpoint == big-desktop {
    // 1800px
    @media (min-width: 112.5em) {
      @content;
    }
  }
}

Responsive Images

<img src="img/logo-green-2x.png" alt="Full logo" class="footer__logo" />

change it to this, for density switching

<img
    srcset="img/logo-green-1x.png 1x, img/logo-green-2x.png 2x"
    alt="Full logo"
    class="footer__logo"
/>

for art switching aswell use

<picture class="footer__logo">
    <source
        srcset="img/logo-green-small-1x.png 1x, img/logo-green-small-2x.png 2x"
        media="(max-width: 37.5em)" />
    <img
        srcset="img/logo-green-1x.png 1x, img/logo-green-2x.png 2x"
        alt="Full logo"
        class="footer__logo"
    />
</picture>