项目作者: chesterheng

项目描述 :
Advanced CSS and Sass: Flexbox, Grid, Animations and More!
高级语言: CSS
项目地址: git://github.com/chesterheng/advanced-css-and-sass.git
创建时间: 2020-08-04T02:09:51Z
项目社区:https://github.com/chesterheng/advanced-css-and-sass

开源协议:

下载


Advanced CSS and Sass: Flexbox, Grid, Animations and More!

Table of Contents

Section 1: Welcome, Welcome, Welcome!

⬆ back to top

Section 2: Natours Project — Setup and First Steps (Part 1)

4. Section Intro

Natours

⬆ back to top

5. Project Overview

Starter

⬆ back to top

6. Building the Header - Part 1

The best way to perform a basic reset using the universal selector

  1. <body>
  2. <header class="header">
  3. </header>
  4. </body>
  1. * {
  2. margin: 0;
  3. padding: 0;
  4. box-sizing: border-box;
  5. }

⬆ back to top

How to set project-wide font definitions?

  1. body {
  2. font-family: "Lato", sans-serif;
  3. font-weight: 400;
  4. font-size: 16px;
  5. line-height: 1.7;
  6. color: #777;
  7. padding: 30px;
  8. }

⬆ back to top

How to clip parts of elements using clip-path?

⬆ back to top

7. Building the Header - Part 2

  1. <body>
  2. <header class="header">
  3. <div class="logo-box">
  4. <img src="img/logo-white.png" alt="Logo" class="logo">
  5. </div>
  6. <div class="text-box">
  7. <h1 class="heading-primary">
  8. <span class="heading-primary-main">Outdoors</span>
  9. <span class="heading-primary-sub">is where life happens</span>
  10. </h1>
  11. </div>
  12. </header>
  13. </body>
  1. .header {
  2. position: relative;
  3. }
  4. .logo-box {
  5. position: absolute;
  6. top: 40px;
  7. left: 40px;
  8. }
  9. .logo {
  10. height: 35px;
  11. }
  12. /* The easiest way to center anything with the transform, top and left properties. */
  13. .text-box {
  14. position: absolute;
  15. top: 40%;
  16. left: 50%;
  17. transform: translate(-50%, -50%);
  18. }
  19. .heading-primary {
  20. color: #fff;
  21. text-transform: uppercase;
  22. }
  23. .heading-primary-main {
  24. display: block;
  25. font-size: 60px;
  26. font-weight: 400;
  27. letter-spacing: 35px;
  28. }
  29. .heading-primary-sub {
  30. display: block;
  31. font-size: 20px;
  32. font-weight: 700;
  33. letter-spacing: 17.4px;
  34. }

⬆ back to top

8. Creating Cool CSS Animations

How to create CSS animations using @keyframes and the animation property?

  1. .heading-primary {
  2. backface-visibility: hidden;
  3. }
  4. .heading-primary-main {
  5. animation-name: moveInLeft;
  6. animation-duration: 1s;
  7. animation-timing-function: ease-out;
  8. }
  9. .heading-primary-sub {
  10. animation: moveInRight 1s ease-out;
  11. }
  12. @keyframes moveInLeft {
  13. 0% {
  14. opacity: 0;
  15. transform: translateX(-100px);
  16. }
  17. 80% {
  18. transform: translateX(10px);
  19. }
  20. 100% {
  21. opacity: 1;
  22. transform: translate(0);
  23. }
  24. }
  25. @keyframes moveInRight {
  26. 0% {
  27. opacity: 0;
  28. transform: translateX(100px);
  29. }
  30. 80% {
  31. transform: translateX(-10px);
  32. }
  33. 100% {
  34. opacity: 1;
  35. transform: translate(0);
  36. }
  37. }

⬆ back to top

9. Building a Complex Animated Button - Part 1

What pseudo-classes are?

A CSS pseudo-class is a keyword added to a selector that specifies a special state of the selected element(s)

For example, :link, :visited, :hover, :active

⬆ back to top

How to create a creative hover animation effect using the transition property?

  1. <a href="" class="btn btn-white">Discover our tours</a>
  1. .btn:link,
  2. .btn:visited {
  3. text-transform: uppercase;
  4. text-decoration: none;
  5. padding: 15px 40px;
  6. display: inline-block;
  7. border-radius: 100px;
  8. transition: all .2s;
  9. }
  10. .btn:hover {
  11. transform: translateY(-3px);
  12. box-shadow: 0 10px 20px rgba(0, 0, 0, .2);
  13. }
  14. .btn:active {
  15. transform: translateY(-1px);
  16. box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
  17. }
  18. .btn-white {
  19. background-color: #fff;
  20. color: #777;
  21. }

⬆ back to top

10. Building a Complex Animated Button - Part 2

What pseudo-elements are?

A CSS pseudo-element is a keyword added to a selector that lets you style a specific part of the selected element(s).

For example, ::after

⬆ back to top

How and why to use the ::after pseudoelement;

In CSS, ::after creates a pseudo-element that is the last child of the selected element. It is often used to add cosmetic content to an element with the content property. It is inline by default.

  1. @keyframes moveInBottom {
  2. 0% {
  3. opacity: 0;
  4. transform: translateY(30px);
  5. }
  6. 100% {
  7. opacity: 1;
  8. transform: translate(0);
  9. }
  10. }
  11. .btn:link,
  12. .btn:visited {
  13. position: relative;
  14. }
  15. .btn::after {
  16. content: "";
  17. display: inline-block;
  18. height: 100%;
  19. width: 100%;
  20. border-radius: 100px;
  21. position: absolute;
  22. top: 0;
  23. left: 0;
  24. z-index: -1;
  25. transition: all .4s;
  26. }
  27. .btn-white::after {
  28. background-color: #fff;
  29. }
  30. .btn:hover::after {
  31. transform: scaleX(1.4) scaleY(1.6);
  32. opacity: 0;
  33. }
  34. .btn-animated {
  35. animation: moveInBottom .5s ease-out .75s;
  36. animation-fill-mode: backwards;
  37. }

⬆ back to top

Section 3: How CSS Works: A Look Behind the Scenes

12. Three Pillars of Writing Good HTML and CSS (Never Forget Them!)

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

⬆ back to top

13. How CSS Works Behind the Scenes: An Overview

⬆ back to top

14. How CSS is Parsed, Part 1: The Cascade and Specificity




Maintainable and scalable code

  • CSS declarations marked with !important have the highest priority;
  • But, only use !important as a last resource. It’s better to use correct specificities — more maintainable code!
  • Inline styles will always have priority over styles in external stylesheets;
  • A selector that contains 1 ID is more specific than one with 1000 classes;
  • A selector that contains 1 class is more specific than one with 1000 elements;
  • The universal selector * has no specificity value (0, 0, 0, 0);
  • Rely more on specificity than on the order of selectors;
  • But, rely on order when using 3rd-party stylesheets — always put your author stylesheet last.

⬆ back to top

15. Specificity in Practice

  1. <nav id="nav">
  2. <div class="pull-right">
  3. <a class="button button-danger" href="link.html">Don't click here!</a>
  4. </div>
  5. </nav>
  1. body {
  2. padding: 50px;
  3. }
  4. .button {
  5. font-size: 20px;
  6. color: white;
  7. background-color: blue e
  8. }
  9. a {
  10. background-color: purple;
  11. }
  12. /* (Inline, IDs, Classes, Elements) */
  13. /* (0, 1, 2, 2) */
  14. #nav div.pull-right a.button {
  15. background-color: orangered;
  16. }
  17. /* (0, 1, 3, 2) */
  18. #nav div.pull-right a.button:hover {
  19. background-color: green;
  20. }
  21. /* (0, 1, 2, 1) */
  22. #nav a.button:hover {
  23. background-color: yellow;
  24. }

⬆ back to top

16. How CSS is Parsed, Part 2: Value Processing

How CSS values are processed?

⬆ back to top

How units are converted from relative to absolute?

⬆ back to top

  • Each property has an initial value, used if nothing is declared (and if there is no inheritance — see next lecture);
  • Browsers specify a root font-size for each page (usually 16px);
  • Percentages and relative values are always converted to pixels;
  • Percentages are measured relative to their parent’s font-size, if used to specify font-size;
  • Percentages are measured relative to their parent’s width, if used to specify lengths;
  • em are measured relative to their parent font-size, if used to specify font-size;
  • em are measured relative to the current font-size, if used to specify lengths;
  • rem are always measured relative to the document’s root font-size;
  • vh and vw are simply percentage measurements of the viewport’s height and width.

⬆ back to top

17. How CSS is Parsed, Part 3: Inheritance

Inheritance in CSS

  • Inheritance passes the values for some specific properties from parents to children — more maintainable code;
  • Properties related to text are inherited: font-family, font-size, color, etc;
  • The computed value of a property is what gets inherited, not the declared value.
  • Inheritance of a property only works if no one declares a value for that property;
  • The inherit keyword forces inheritance on a certain property;
  • The initial keyword resets a property to its initial value.

⬆ back to top

18. Converting px to rem: An Effective Workflow

  1. html {
  2. font-size: 62.5%;
  3. }
  4. body {
  5. font-family: "Lato", sans-serif;
  6. font-weight: 400;
  7. /* font-size: 16px; */
  8. line-height: 1.7;
  9. color: #777;
  10. padding: 3rem;
  11. }
  • The inherit keyword specifies that a property should inherit its value from its parent element.
  • The * selector selects all elements.
  • All element will have the property box-sizing: inherit;
  • All Child elements will inherit the property box-sizing: border-box; from parent element body
  1. *,
  2. *::after,
  3. *::before {
  4. margin: 0;
  5. padding: 0;
  6. box-sizing: inherit;
  7. }
  8. body {
  9. box-sizing: border-box;
  10. }

⬆ back to top

19. How CSS Renders a Website: The Visual Formatting Model

The Visual Formatting Model

Algorithm that calculates boxes and determines the layout of theses boxes, for each element in the render tree, in order to determine the final layout of the page.

  • Dimensions of boxes: the box model;
  • Box type: inline, block and inline-block;
  • Positioning scheme: floats and positioning;
  • Stacking contexts;
  • Other elements in the render tree;
  • Viewport size, dimensions of images, etc.

⬆ back to top

The box model

  • Content: text, images, etc;
  • Padding: transparent area around the content, inside of the box;
  • Border: goes around the padding and the content;
  • Margin: space between boxes;
  • Fill area: area that gets filled with background color or background image.

The box model - Heights and Widths (default)

  • total width = right border + right padding + specified width + left padding + left border
  • total height = top border + top padding + specified height + bottom padding + bottom border
  • Example: height = 0 + 20px + 100px + 20px + 0 = 140px

The box model - Heights and Widths (box-sizing: border-box)

⬆ back to top

Box types

Block-level boxes Inline-block boxes Inline boxes
Elements formatted visually as blocks A mix of block and inline Content is distributed in lines
100% of parent’s width Occupies only content’s space Occupies only content’s space
Vertically, one after another No line-breaks No line-breaks
Box-model applies as showed Box-model applies as showed No heights and widths
Paddings and margins only horizontal (left and right)
display: block display: inline-block display: inline
display: flex
display: list-item
display: table

⬆ back to top

Positioning Schemes

Normal flow Floats Absolute positioning
Default positioning scheme; Element is removed from the normal flow; Element is removed from the normal flow
NOT floated; Text and inline elements will wrap around the floated element; No impact on surrounding content or elements;
NOT absolutely positioned; The container will not adjust its height to the element. We use top, bottom, left and right to offset the element from its relatively positioned container.
Elements laid out according to their source order.
default float: left position: absolute
position: relative float: right position: fixed

⬆ back to top

Stacking Contexts

⬆ back to top

20. CSS Architecture, Components and BEM

The Think - Build - Architect Mindset

Responsive design Maintainable and scalable code Web performance
Clean
Modular
Reusable
Ready for growth

Think -> Build -> Architect

  • Think about the layout of your webpage or web app before writing code.
  • Build your layout in HTML and CSS with a consistent structure for naming classes.
  • Create a logical architecture for your CSS with files and folders.

⬆ back to top

Thinking about the layout

Component-driven design

  • Modular building blocks that make up interfaces;
  • Held together by the layout of the page;
  • Re-usable across a project, and between different projects;
  • Independent, allowing us to use them anywhere on the page.

⬆ back to top

Building with meaningful class names

⬆ back to top

Architecting with files and folders

The 7-1 pattern

  • 7 different folders for partial Sass files, and 1 main Sass file to import all other files into a compiled CSS stylesheet.

The 7 Folders

  • base/
  • components/
  • layout/
  • pages/
  • themes/
  • abstracts/
  • vendors/

⬆ back to top

21. Implementing BEM in the Natours Project

  1. <header class="header">
  2. <div class="header__logo-box">
  3. <img src="img/logo-white.png" alt="Logo" class="header__logo">
  4. </div>
  5. <div class="header__text-box">
  6. <h1 class="heading-primary">
  7. <span class="heading-primary--main">Outdoors</span>
  8. <span class="heading-primary--sub">is where life happens</span>
  9. </h1>
  10. <a href="" class="btn btn--white btn--animated">Discover our tours</a>
  11. </div>
  12. </header>
  1. .header {
  2. height: 95vh;
  3. background-image: linear-gradient(to right bottom, rgba(126, 213, 111, 0.8), rgba(40, 180, 133, 0.8)), url(../img/hero.jpg);
  4. background-size: cover;
  5. background-position: top;
  6. position: relative;
  7. clip-path: polygon(0 0, 100% 0, 100% 75vh, 0 100%);
  8. }
  9. .header__logo-box {
  10. position: absolute;
  11. top: 4rem;
  12. left: 4rem;
  13. }
  14. .header__logo {
  15. height: 3.5rem;
  16. }
  17. .header__text-box {
  18. position: absolute;
  19. top: 40%;
  20. left: 50%;
  21. transform: translate(-50%, -50%);
  22. text-align: center;
  23. }
  24. .heading-primary {
  25. color: #fff;
  26. text-transform: uppercase;
  27. backface-visibility: hidden;
  28. margin-bottom: 6rem;
  29. }
  30. .heading-primary--main {
  31. display: block;
  32. font-size: 6rem;
  33. font-weight: 400;
  34. letter-spacing: 3.5rem;
  35. animation-name: moveInLeft;
  36. animation-duration: 1s;
  37. animation-timing-function: ease-out;
  38. /* animation-delay: 3s; */
  39. }
  40. .heading-primary--sub {
  41. display: block;
  42. font-size: 2rem;
  43. font-weight: 700;
  44. letter-spacing: 1.75rem;
  45. animation: moveInRight 1s ease-out;
  46. }
  47. .btn:link,
  48. .btn:visited {
  49. text-transform: uppercase;
  50. text-decoration: none;
  51. padding: 1.5rem 4rem;
  52. display: inline-block;
  53. border-radius: 10rem;
  54. transition: all .2s;
  55. position: relative;
  56. font-size: 1.6rem;
  57. }
  58. .btn:hover {
  59. transform: translateY(-.3rem);
  60. box-shadow: 0 1rem 2rem rgba(0, 0, 0, .2);
  61. }
  62. .btn:active {
  63. transform: translateY(-.1rem);
  64. box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .2);
  65. }
  66. .btn--white {
  67. background-color: #fff;
  68. color: #777;
  69. }
  70. .btn--white::after {
  71. background-color: #fff;
  72. }
  73. .btn--animated {
  74. animation: moveInBottom .5s ease-out .75s;
  75. animation-fill-mode: backwards;
  76. }

⬆ back to top

Section 4: Introduction to Sass and NPM

22. Section Intro

⬆ back to top

23. What is Sass?

Sass is a CSS preprocessor, an extension of CSS that adds power and elegance to the basic language.

Main SASS features

  • Variables: for reusable values such as colors, font-sizes, spacing, etc;
  • Nesting: to nest selectors inside of one another, allowing us to write less code;
  • Operators: for mathematical operations right inside of CSS;
  • Partials and imports: to write CSS in different files and importing them all into one single file;
  • Mixins: to write reusable pieces of CSS code;
  • Functions: similar to mixins, with the difference that they produce a value that can than be used;
  • Extends: to make different selectors inherit declarations that are common to all of them;
  • Control directives: for writing complex code using conditionals and loops (not covered in this course).

⬆ back to top

24. First Steps with Sass: Variables and Nesting

  1. <nav>
  2. <ul class="navigation">
  3. <li><a href="#">About us</a></li>
  4. <li><a href="#">Pricing</a></li>
  5. <li><a href="#">Contact</a></li>
  6. </ul>
  7. <div class="buttons">
  8. <a class="btn-main" href="#">Sign up</a>
  9. <a class="btn-hot" href="#">Get a quote</a>
  10. </div>
  11. </nav>
  1. * {
  2. margin: 0;
  3. padding: 0;
  4. }
  5. // SaSS variables
  6. $color-primary: #f9ed69; //yellow color
  7. $color-secondary: #f08a5d; //orange color
  8. $color-tertiary: #b83b5e; //pink color
  9. $color-text-dark: #333; //dark grey
  10. $color-text-light: #eee; //light grey
  11. $width-button: 150px;
  12. nav {
  13. margin: 30px;
  14. background-color: $color-primary;
  15. // Fix for displaying no background when using floats
  16. &:after {
  17. content: "";
  18. clear: both;
  19. display: table;
  20. }
  21. }
  22. .navigation {
  23. list-style: none;
  24. float: left;
  25. // Nested selector
  26. li {
  27. display: inline-block;
  28. margin-left: 30px;
  29. // No limit on how many nested selectors you have
  30. // &: === .nagivation li
  31. &:first-child {
  32. margin: 0;
  33. }
  34. a:link,
  35. a:active {
  36. text-decoration: none;
  37. text-transform: uppercase;
  38. color: $color-text-dark;
  39. }
  40. }
  41. }
  42. .buttons {
  43. float: right;
  44. }
  45. .btn-main:link,
  46. .btn-hot:link {
  47. padding: 10px;
  48. display: inline-block;
  49. text-align: center;
  50. border-radius: 100px;
  51. text-decoration: none;
  52. text-transform: uppercase;
  53. width: $width-button;
  54. color: $color-text-light;
  55. }
  56. .btn-main {
  57. &:link {
  58. background-color: $color-secondary;
  59. }
  60. &:hover {
  61. background-color: darken($color-secondary, 15%);
  62. }
  63. }
  64. .btn-hot {
  65. &:link {
  66. background-color: $color-tertiary;
  67. }
  68. &:hover {
  69. background-color: lighten($color-tertiary, 15%);
  70. }
  71. }

⬆ back to top

25. First Steps with Sass: Mixins, Extends and Functions

  • Mixins allow you to define styles that can be re-used throughout your stylesheet.
  • Extends allows you to share styles between two selectors.
  • Functions allow you to define complex operations on SassScript values that you can re-use throughout your stylesheet.
  1. $color-text-dark: #333; //dark grey
  2. $color-text-light: #eee; //light grey
  3. @mixin clearfix {
  4. &::after{
  5. content:"";
  6. clear:both;
  7. display:table;
  8. }
  9. }
  10. @mixin style-link-text($color) {
  11. text-decoration: none;
  12. text-transform: uppercase;
  13. color: $color;
  14. }
  15. @function divide($a, $b) {
  16. @return $a / $b;
  17. }
  18. nav {
  19. margin: divide(60, 2) * 1px; // 30px
  20. background-color: $color-primary;
  21. @include clearfix
  22. }
  23. .navigation {
  24. list-style: none;
  25. float: left;
  26. li {
  27. a:link,
  28. a:active {
  29. @include style-link-text($color-text-dark)
  30. }
  31. }
  32. }
  33. // both .btn-main:link, .btn-hot:link will share styles
  34. %btn-placeholder {
  35. padding: 10px;
  36. display: inline-block;
  37. text-align: center;
  38. border-radius: 100px;
  39. width: $width-button;
  40. @include style-link-text($color-text-light)
  41. }
  42. .btn-main {
  43. &:link {
  44. @extend %btn-placeholder;
  45. background-color: $color-secondary;
  46. }
  47. }
  48. .btn-hot {
  49. &:link {
  50. @extend %btn-placeholder;
  51. background-color: $color-tertiary;
  52. }
  53. }

⬆ back to top

27. NPM Packages: Let’s Install Sass Locally

node-sass

⬆ back to top

28. NPM Scripts: Let’s Write and Compile Sass Locally

  1. npm run compile:sass

⬆ back to top

29. The Easiest Way of Automatically Reloading a Page on File Changes

Live Server

  1. npm i live-server -g
  2. live-server

⬆ back to top

Section 5: Natours Project — Using Advanced CSS and Sass (Part 2)

31. Converting Our CSS Code to Sass: Variables and Nesting

  1. $color-primary: #55c57a;
  2. $color-primary-light: #7ed56f;
  3. $color-primary-dark: #28b485;
  4. $color-grey-dark: #777;
  5. $color-white: #fff;
  6. $color-black: #000;
  7. .header {
  8. height: 95vh;
  9. background-image: linear-gradient(to right bottom, rgba($color-primary-light, 0.8), rgba($color-primary-dark, 0.8)), url(../img/hero.jpg);
  10. background-size: cover;
  11. background-position: top;
  12. position: relative;
  13. clip-path: polygon(0 0, 100% 0, 100% 75vh, 0 100%);
  14. &__logo-box {
  15. position: absolute;
  16. top: 4rem;
  17. left: 4rem;
  18. }
  19. &__logo {
  20. height: 3.5rem;
  21. }
  22. &__text-box {
  23. position: absolute;
  24. top: 40%;
  25. left: 50%;
  26. transform: translate(-50%, -50%);
  27. text-align: center;
  28. }
  29. }

⬆ back to top

32. Implementing the 7-1 CSS Architecture with Sass

⬆ back to top

33. Review: Basic Principles of Responsive Design and Layout Types

Basic Responsive Design Principles

  • Fluid Grids And Layouts

To allow content to easily adapt to the current viewport width used to browse the website. Uses % rather than px for all layout-related lengths.

  • Flexible/Responsive Images

Images behave differently than text content, and so we need to ensure that they also adapt nicely to the current viewport.

  • Media Queries

To change styles on certain viewport widths (breakpoints), allowing us to create different version of our website for different widths.

⬆ back to top

34. Building a Custom Grid with Floats

  • How to architect and build a simple grid system;
  • How the attribute selector works;
  • How the :not pseudo-class works;
  • How calc() works, and what’s the difference between calc() and simple Sass operations.

  1. <section class="grid-test">
  2. <div class="row">
  3. <div class="col-1-of-2">Col 1 of 2</div>
  4. <div class="col-1-of-2">Col 1 of 2</div>
  5. </div>
  6. <div class="row">
  7. <div class="col-1-of-3">Col 1 of 3</div>
  8. <div class="col-1-of-3">Col 1 of 3</div>
  9. <div class="col-1-of-3">Col 1 of 3</div>
  10. </div>
  11. <div class="row">
  12. <div class="col-1-of-3">Col 1 of 3</div>
  13. <div class="col-2-of-3">Col 2 of 3</div>
  14. </div>
  15. <div class="row">
  16. <div class="col-1-of-4">Col 1 of 4</div>
  17. <div class="col-1-of-4">Col 1 of 4</div>
  18. <div class="col-1-of-4">Col 1 of 4</div>
  19. <div class="col-1-of-4">Col 1 of 4</div>
  20. </div>
  21. <div class="row">
  22. <div class="col-1-of-4">Col 1 of 4</div>
  23. <div class="col-1-of-4">Col 1 of 4</div>
  24. <div class="col-2-of-4">Col 2 of 4</div>
  25. </div>
  26. <div class="row">
  27. <div class="col-1-of-4">Col 1 of 4</div>
  28. <div class="col-3-of-4">Col 3 of 4</div>
  29. </div>
  30. </section>
  1. .row {
  2. max-width: $grid-width;
  3. background-color: #eee;
  4. // center block element
  5. margin: 0 auto;
  6. // select everything except last child
  7. &:not(:last-child) {
  8. margin-bottom: $gutter-vertical;
  9. }
  10. @include clearfix;
  11. // select all class selector start with "col-"
  12. [class^="col-"] {
  13. background-color: orangered;
  14. float: left;
  15. &:not(:last-child) {
  16. margin-right: $gutter-horizontal;
  17. }
  18. }
  19. .col-1-of-2 {
  20. width: calc((100% - #{$gutter-horizontal}) / 2);
  21. }
  22. .col-1-of-3 {
  23. width: calc((100% - 2 * #{$gutter-horizontal}) / 3);
  24. }
  25. .col-2-of-3 {
  26. width: calc(2 * ((100% - 2 * #{$gutter-horizontal}) / 3) + #{$gutter-horizontal});
  27. }
  28. .col-1-of-4 {
  29. width: calc((100% - 3 * #{$gutter-horizontal}) / 4);
  30. }
  31. .col-2-of-4 {
  32. width: calc(2 * ((100% - 3 * #{$gutter-horizontal}) / 4) + #{$gutter-horizontal});
  33. }
  34. .col-3-of-4 {
  35. width: calc(3 * ((100% - 3 * #{$gutter-horizontal}) / 4) + 2 * #{$gutter-horizontal});
  36. }
  37. }

⬆ back to top

35. Building the About Section - Part 1

Thinking about components

  • Secondary Heading
  • Tertiary Heading
  • Paragraph
  • Text Button
  • Image Composition
  1. <section class="section-about">
  2. <div class="u-center-text u-margin-bottom-big">
  3. <h2 class="heading-secondary">
  4. Exciting tours for adventurous people
  5. </h2>
  6. </div>
  7. <div class="row">
  8. <div class="col-1-of-2"></div>
  9. <div class="col-1-of-2"></div>
  10. </div>
  11. </section>
  1. .section-about {
  2. background-color: $color-grey-light-1;
  3. padding: 25rem 0;
  4. margin-top: -20vh;
  5. }

⬆ back to top

Secondary Heading component

  1. <div class="u-center-text u-margin-bottom-big">
  2. <h2 class="heading-secondary">
  3. Exciting tours for adventurous people
  4. </h2>
  5. </div>
  1. .heading-secondary {
  2. font-size: 3.5rem;
  3. text-transform: uppercase;
  4. font-weight: 700;
  5. display: inline-block;
  6. background-image: linear-gradient(to right, $color-primary-light, $color-primary-dark);
  7. background-clip: text;
  8. -webkit-background-clip: text;
  9. color: transparent;
  10. letter-spacing: .2rem;
  11. transition: all .2s;
  12. &:hover {
  13. transform: skewY(2deg) skewX(15deg) scale(1.1);
  14. text-shadow: .5rem 1rem 2rem rgba($color-black, .2);
  15. }
  16. }

⬆ back to top

How and why to use utility classes?

  1. .u-center-text {
  2. // center inline-block child
  3. text-align: center;
  4. }
  5. .u-margin-bottom-small { margin-bottom: 2rem; }
  6. .u-margin-bottom-medium { margin-bottom: 4rem; }
  7. .u-margin-bottom-big { margin-bottom: 8rem; }

⬆ back to top

How to use the background-clip property?

  1. .heading-secondary {
  2. display: inline-block;
  3. background-image: linear-gradient(to right, $color-primary-light, $color-primary-dark);
  4. -webkit-background-clip: text;
  5. color: transparent;
  6. }

⬆ back to top

How to transform multiple properties simultaneously?

  1. .heading-secondary {
  2. transition: all .2s;
  3. &:hover {
  4. transform: skewY(2deg) skewX(15deg) scale(1.1);
  5. text-shadow: .5rem 1rem 2rem rgba($color-black, .2);
  6. }
  7. }

⬆ back to top

36. Building the About Section - Part 2

  1. <h3 class="heading-tertiary u-margin-bottom-small">You are going to fall in love with nature</h3>
  2. <p class="paragraph">
  3. Lorem ipsum dolor sit, amet consectetur adipisicing elit. Iste rerum ullam accusantium omnis officia, repellendus qui quae, maxime itaque dolores corporis provident. Illo temporibus magnam praesentium, maiores ipsa beatae dolor?
  4. </p>
  5. <h3 class="heading-tertiary u-margin-bottom-small">Live adventures like you never have before</h3>
  6. <p class="paragraph">
  7. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Recusandae quos, reiciendis perspiciatis rem quis velit quae deleniti itaque? Modi harum voluptates minus? Molestiae, id libero impedit consequatur quae amet inventore?
  8. </p>
  9. <a href="#" class="btn-text">
  10. Learn more →
  11. </a>

⬆ back to top

Tertiary Heading component

  1. .heading-tertiary {
  2. font-size: $default-font-size;
  3. font-weight: 700;
  4. text-transform: uppercase;
  5. }

⬆ back to top

Paragraph component

  1. .paragraph {
  2. font-size: $default-font-size;
  3. &:not(:last-child) {
  4. margin-bottom: 3rem;
  5. }
  6. }

⬆ back to top

Text Button component

  1. .btn-text {
  2. &:link,
  3. &:visited {
  4. font-size: $default-font-size;
  5. color: $color-primary;
  6. display: inline-block;
  7. text-decoration: none;
  8. border-bottom: 1px solid $color-primary;
  9. padding: 3px;
  10. transition: all .2s;
  11. }
  12. &:hover {
  13. background-color: $color-primary;
  14. color: $color-white;
  15. box-shadow: 0 1rem 2rem rgba($color-black, .15);
  16. transform: translateY(-2px);
  17. }
  18. &:active {
  19. box-shadow: 0 .5rem 1rem rgba($color-black, .15);
  20. transform: translateY(0);
  21. }
  22. }

⬆ back to top

37. Building the About Section - Part 3

Image Composition component

  1. <div class="composition">
  2. <img src="img/nat-1-large.jpg" alt="Photo 1" class="composition__photo composition__photo--p1">
  3. <img src="img/nat-2-large.jpg" alt="Photo 2" class="composition__photo composition__photo--p2">
  4. <img src="img/nat-3-large.jpg" alt="Photo 3" class="composition__photo composition__photo--p3">
  5. </div>
  1. .composition {
  2. position: relative;
  3. &__photo {
  4. width: 55%;
  5. box-shadow: 0 1.5rem 4rem rgba($color-black, 0.4);
  6. border-radius: 2px;
  7. position: absolute;
  8. z-index: 10;
  9. transition: all .2s;
  10. outline-offset: 2rem;
  11. &--p1 {
  12. left: 0;
  13. top: -2rem;
  14. }
  15. &--p2 {
  16. right: 0;
  17. top: 2rem;
  18. }
  19. &--p3 {
  20. left: 20%;
  21. top: 10rem;
  22. }
  23. &:hover {
  24. outline: 1.5rem solid $color-primary;
  25. transform: scale(1.05) translateY(-.5rem);
  26. box-shadow: 0 2.5rem 4rem rgba($color-black, .5);
  27. z-index: 20;
  28. }
  29. }
  30. // composition:hover composition__photo:not(:hover)
  31. &:hover &__photo:not(:hover) {
  32. transform: scale(0.95);
  33. }
  34. }

⬆ back to top

How to use the outline-offset property together with outline?

  1. .composition {
  2. position: relative;
  3. &__photo {
  4. outline-offset: 2rem;
  5. &:hover {
  6. outline: 1.5rem solid $color-primary;
  7. }
  8. }
  9. }

⬆ back to top

How to style elements that are NOT hovered while others are?

  1. .composition {
  2. position: relative;
  3. &__photo {
  4. &:hover {
  5. outline: 1.5rem solid $color-primary;
  6. transform: scale(1.05) translateY(-.5rem);
  7. box-shadow: 0 2.5rem 4rem rgba($color-black, .5);
  8. z-index: 20;
  9. }
  10. }
  11. // composition:hover composition__photo:not(:hover)
  12. &:hover &__photo:not(:hover) {
  13. transform: scale(0.95);
  14. }
  15. }

⬆ back to top

38. Building the Features Section

  1. <section class="section-features">
  2. <div class="row">
  3. <div class="col-1-of-4">
  4. <div class="feature-box">
  5. <i class="feature-box__icon icon-basic-world"></i>
  6. <h3 class="heading-tertiary u-margin-bottom-small">Explore the world</h3>
  7. <p class="feature-box__text">
  8. Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae rerum commodi atque, natus inventore.
  9. </p>
  10. </div>
  11. </div>
  12. <div class="col-1-of-4">
  13. <div class="feature-box">
  14. <i class="feature-box__icon icon-basic-compass"></i>
  15. <h3 class="heading-tertiary u-margin-bottom-small">Meet nature</h3>
  16. <p class="feature-box__text">
  17. Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae rerum commodi atque, natus inventore.
  18. </p>
  19. </div>
  20. </div>
  21. <div class="col-1-of-4">
  22. <div class="feature-box">
  23. <i class="feature-box__icon icon-basic-map"></i>
  24. <h3 class="heading-tertiary u-margin-bottom-small">Find your way</h3>
  25. <p class="feature-box__text">
  26. Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae rerum commodi atque, natus inventore.
  27. </p>
  28. </div>
  29. </div>
  30. <div class="col-1-of-4">
  31. <div class="feature-box">
  32. <i class="feature-box__icon icon-basic-heart"></i>
  33. <h3 class="heading-tertiary u-margin-bottom-small">Live a healther life</h3>
  34. <p class="feature-box__text">
  35. Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae rerum commodi atque, natus inventore.
  36. </p>
  37. </div>
  38. </div>
  39. </div>
  40. </section>
  1. .section-features {
  2. padding: 20rem 0;
  3. background-image: linear-gradient(to right bottom, rgba($color-primary-light, 0.8), rgba($color-primary-dark, 0.8)), url(../img/nat-4.jpg);
  4. background-size: cover;
  5. transform: skewY(-7deg);
  6. margin-top: -10rem;
  7. // select all direct child: row selector in this case
  8. & > * {
  9. transform: skewY(7deg);
  10. }
  11. }
  1. .feature-box {
  2. background-color: rgba($color-white, .8);
  3. font-size: 1.5rem;
  4. padding: 2.5rem;
  5. text-align: center;
  6. border-radius: 3px;
  7. box-shadow: 0 1.5rem 4rem rgba($color-black, .15);
  8. transition: transform .3s;
  9. &__icon {
  10. font-size: 6rem;
  11. margin-bottom: .5rem;
  12. display: inline-block;
  13. background-image: linear-gradient(to right, $color-primary-light, $color-primary-dark);
  14. -webkit-background-clip: text;
  15. color: transparent;
  16. }
  17. &:hover {
  18. transform: translateY(-1.5rem) scale(1.03);
  19. }
  20. &__text {
  21. }
  22. }

⬆ back to top

How to include and use an icon font?

  • Goto Linea Icon
  • Download linea_complete_1.0.zip
  • Unzip linea_complete_1.0.zip
  • Goto _basic/_ICONFONT/ folder
  • Rename styles.css to icon-font.css
  • Copy fonts folder to css project folder
  • Copy icon-font.css file to css project folder
  • Include icon-font.css in index.html
  • Refer to linea_complete_1.0/_basic/_ICONFONT/icons-reference.html for icon name

⬆ back to top

Another way of creating the “skewed section”

  1. .section-features {
  2. transform: skewY(-7deg);
  3. margin-top: -10rem;
  4. }

⬆ back to top

How and when to use the direct child selector?

  1. <section class="section-features">
  2. <div class="row">
  3. </div>
  4. </section>
  1. .section-features {
  2. // select all direct child of section-features
  3. // Example: row selector
  4. & > * {
  5. transform: skewY(7deg);
  6. }
  7. }

⬆ back to top

39. Building the Tours Section - Part 1

Thinking about components

  • Secondary Heading
  • 3 Cards
    • Front: Picture, Heading, Details
    • Back: CTA
  • Green Button


  1. <section class="section-tours">
  2. <div class="u-center-text u-margin-bottom-big">
  3. <h2 class="heading-secondary">
  4. Most popular tours
  5. </h2>
  6. </div>
  7. <div class="row">
  8. <div class="col-1-of-3">
  9. <div class="card">
  10. <div class="card__side card__side--front">
  11. <div class="card__picture card__picture--1"> </div>
  12. <h4 class="card__heading">
  13. <span class="card__heading-span card__heading-span--1">
  14. The Sea Explorer
  15. </span>
  16. </h4>
  17. <div class="card__details">
  18. <ul>
  19. <li>3 day tours</li>
  20. <li>Up to 30 people</li>
  21. <li>2 tour guides</li>
  22. <li>Sleep in cozy hotel</li>
  23. <li>Difficulty: easy</li>
  24. </ul>
  25. </div>
  26. </div>
  27. <div class="card__side card__side--back card__side--back--1">
  28. <div class="card__cta">
  29. <div class="card__price-box">
  30. <p class="card__price-only">Only</p>
  31. <p class="card__price-value">$297</p>
  32. </div>
  33. <a href="" class="btn btn--white">Book now</a>
  34. </div>
  35. </div>
  36. </div>
  37. </div>
  38. </div>
  39. <div class="u-center-text u-margin-top-huge">
  40. <a href="#" class="btn btn--green">Discover all tours</a>
  41. </div>
  42. </section>
  1. .section-tours {
  2. background-color: $color-grey-light-1;
  3. padding: 25rem 0 15rem 0;
  4. margin-top: -10rem;
  5. }
  6. .card {
  7. // FUNCTIONALITY
  8. perspective: 150rem;
  9. -moz-perspective: 150rem;
  10. position: relative;
  11. height: 52rem;
  12. &__side {
  13. height: 52rem;
  14. transition: all .8s ease;
  15. position: absolute;
  16. top: 0;
  17. left: 0;
  18. width: 100%;
  19. backface-visibility: hidden;
  20. border-radius: 3px;
  21. overflow: hidden;
  22. box-shadow: 0 1.5rem 4rem rgba($color-black, .15);
  23. &--front {
  24. background-color: $color-white;
  25. }
  26. &--back {
  27. transform: rotateY(180deg);
  28. &--1 {
  29. background-image: linear-gradient(to right bottom, $color-secondary-light, $color-secondary-dark);
  30. }
  31. }
  32. }
  33. &:hover &__side--front {
  34. transform: rotateY(180deg);
  35. }
  36. &:hover &__side--back {
  37. transform: rotateY(0);
  38. }
  39. // FRONT SIDE STYLING
  40. &__picture {
  41. background-size: cover;
  42. height: 23rem;
  43. background-blend-mode: screen;
  44. -webkit-clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%);
  45. clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%);
  46. border-top-left-radius: 3px;
  47. border-top-right-radius: 3px;
  48. &--1 {
  49. background-image: linear-gradient(to right bottom, $color-secondary-light, $color-secondary-dark), url(../img/nat-5.jpg);
  50. }
  51. }
  52. &__heading {
  53. font-size: 2.5rem;
  54. font-weight: 300;
  55. text-transform: uppercase;
  56. text-align: right;
  57. color: $color-white;
  58. position: absolute;
  59. top: 12rem;
  60. right: 2rem;
  61. width: 75%;
  62. }
  63. &__heading-span {
  64. padding: 1rem 1.5rem;
  65. -webkit-box-decoration-break: clone;
  66. box-decoration-break: clone;
  67. &--1 {
  68. background-image: linear-gradient(to right bottom, $color-secondary-light, $color-secondary-dark);
  69. }
  70. }
  71. &__details {
  72. padding: 3rem;
  73. ul {
  74. list-style: none;
  75. width: 80%;
  76. margin: 0 auto;
  77. li {
  78. text-align: center;
  79. font-size: 1.5rem;
  80. padding: 1rem;
  81. &:not(:last-child) {
  82. border-bottom: 1px solid $color-grey-light-2;
  83. }
  84. }
  85. }
  86. }
  87. // BACK SIDE STYLING
  88. &__cta {
  89. position: absolute;
  90. top: 50%;
  91. left: 50%;
  92. transform: translate(-50%, -50%);
  93. width: 90%;
  94. text-align: center;
  95. }
  96. &__price-box {
  97. text-align: center;
  98. color: $color-white;
  99. margin-bottom: 8rem;
  100. }
  101. &__price-only {
  102. font-size: 1.4rem;
  103. text-transform: uppercase;
  104. }
  105. &__price-value {
  106. font-size: 6rem;
  107. font-weight: 100;
  108. }
  109. }

⬆ back to top

How to build an amazing, rotating card?

  1. <div class="card">
  2. <div class="card__side card__side--front">
  3. FRONT
  4. </div>
  5. <div class="card__side card__side--back card__side--back--1">
  6. BACK
  7. </div>
  8. </div>
  1. .card {
  2. perspective: 150rem;
  3. -moz-perspective: 150rem;
  4. position: relative;
  5. height: 52rem;
  6. &__side {
  7. height: 52rem;
  8. transition: all .8s ease;
  9. position: absolute;
  10. top: 0;
  11. left: 0;
  12. width: 100%;
  13. backface-visibility: hidden;
  14. border-radius: 3px;
  15. overflow: hidden;
  16. box-shadow: 0 1.5rem 4rem rgba($color-black, .15);
  17. &--front {
  18. background-color: $color-white;
  19. }
  20. &--back {
  21. transform: rotateY(180deg);
  22. }
  23. }
  24. &:hover &__side--front {
  25. transform: rotateY(180deg);
  26. }
  27. &:hover &__side--back {
  28. transform: rotateY(0);
  29. }
  30. }

⬆ back to top

40. Building the Tours Section - Part 2

Front Side Card component: Picture, Heading, Details

  1. <section class="section-tours">
  2. <div class="u-center-text u-margin-bottom-big">
  3. <h2 class="heading-secondary">
  4. Most popular tours
  5. </h2>
  6. </div>
  7. <div class="row">
  8. <div class="col-1-of-3">
  9. <div class="card">
  10. <div class="card__side card__side--front">
  11. <div class="card__picture card__picture--1"> </div>
  12. <h4 class="card__heading">
  13. <span class="card__heading-span card__heading-span--1">
  14. The Sea Explorer
  15. </span>
  16. </h4>
  17. <div class="card__details">
  18. <ul>
  19. <li>3 day tours</li>
  20. <li>Up to 30 people</li>
  21. <li>2 tour guides</li>
  22. <li>Sleep in cozy hotel</li>
  23. <li>Difficulty: easy</li>
  24. </ul>
  25. </div>
  26. </div>
  27. <div class="card__side card__side--back card__side--back--1">
  28. BACK
  29. </div>
  30. </div>
  31. </div>
  32. </div>
  33. <div class="u-center-text u-margin-top-huge">
  34. <a href="#" class="btn btn--green">Discover all tours</a>
  35. </div>
  36. </section>
  1. .card {
  2. &__picture {
  3. background-size: cover;
  4. height: 23rem;
  5. background-blend-mode: screen;
  6. -webkit-clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%);
  7. clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%);
  8. border-top-left-radius: 3px;
  9. border-top-right-radius: 3px;
  10. &--1 {
  11. background-image: linear-gradient(to right bottom, $color-secondary-light, $color-secondary-dark), url(../img/nat-5.jpg);
  12. }
  13. }
  14. &__heading {
  15. font-size: 2.5rem;
  16. font-weight: 300;
  17. text-transform: uppercase;
  18. text-align: right;
  19. color: $color-white;
  20. position: absolute;
  21. top: 12rem;
  22. right: 2rem;
  23. width: 75%;
  24. }
  25. &__heading-span {
  26. padding: 1rem 1.5rem;
  27. -webkit-box-decoration-break: clone;
  28. box-decoration-break: clone;
  29. &--1 {
  30. background-image: linear-gradient(to right bottom, $color-secondary-light, $color-secondary-dark);
  31. }
  32. }
  33. &__details {
  34. padding: 3rem;
  35. ul {
  36. list-style: none;
  37. width: 80%;
  38. margin: 0 auto;
  39. li {
  40. text-align: center;
  41. font-size: 1.5rem;
  42. padding: 1rem;
  43. &:not(:last-child) {
  44. border-bottom: 1px solid $color-grey-light-2;
  45. }
  46. }
  47. }
  48. }
  49. }

⬆ back to top

How to use perspective in CSS?

The perspective CSS property determines the distance between the z=0 plane and the user in order to give a 3D-positioned element some perspective.

The perspective property defines how far the object is away from the user. So, a lower value will result in a more intensive 3D effect than a higher value.

When defining the perspective property for an element, it is the CHILD elements that get the perspective view, NOT the element itself.

  1. .card {
  2. perspective: 150rem;
  3. -moz-perspective: 150rem;
  4. }

⬆ back to top

How to use the backface-visibility property?

The backface-visibility CSS property sets whether the back face of an element is visible when turned towards the user.

This div element has “backface-visibility: hidden”, and the back face of the div element is invisible:

This div element has “backface-visibility: visible”, and the back face of the div element shows a mirror image of the front face:

  1. <div class="card">
  2. <div class="card__side card__side--front">
  3. </div>
  4. <div class="card__side card__side--back card__side--back--1">
  5. </div>
  6. </div>
  1. .card {
  2. &__side {
  3. backface-visibility: hidden;
  4. &--front {
  5. background-color: $color-white;
  6. }
  7. &--back {
  8. transform: rotateY(180deg);
  9. }
  10. }
  11. &:hover &__side--front {
  12. transform: rotateY(180deg);
  13. }
  14. &:hover &__side--back {
  15. transform: rotateY(0);
  16. }
  17. }

⬆ back to top

Using background blend modes?

The background-blend-mode CSS property sets how an element’s background images should blend with each other and with the element’s background color.


  1. .card {
  2. &__picture {
  3. background-size: cover;
  4. height: 23rem;
  5. background-blend-mode: screen;
  6. &--1 {
  7. background-image: linear-gradient(to right bottom, $color-secondary-light, $color-secondary-dark), url(../img/nat-5.jpg);
  8. }
  9. }
  10. }

⬆ back to top

How and when to use box-decoration-break;

The box-decoration-break CSS property specifies how an element’s fragments should be rendered when broken across multiple lines, columns, or pages.

  1. .card {
  2. &__heading-span {
  3. padding: 1rem 1.5rem;
  4. -webkit-box-decoration-break: clone;
  5. box-decoration-break: clone;
  6. &--1 {
  7. background-image: linear-gradient(to right bottom, $color-secondary-light, $color-secondary-dark);
  8. }
  9. }
  10. }

⬆ back to top

41. Building the Tours Section - Part 3

Back Side Card component: CTA

  1. <section class="section-tours">
  2. <div class="u-center-text u-margin-bottom-big">
  3. <h2 class="heading-secondary">
  4. Most popular tours
  5. </h2>
  6. </div>
  7. <div class="row">
  8. <div class="col-1-of-3">
  9. <div class="card">
  10. <div class="card__side card__side--front">
  11. FRONT
  12. </div>
  13. <div class="card__side card__side--back card__side--back--1">
  14. <div class="card__cta">
  15. <div class="card__price-box">
  16. <p class="card__price-only">Only</p>
  17. <p class="card__price-value">$297</p>
  18. </div>
  19. <a href="" class="btn btn--white">Book now</a>
  20. </div>
  21. </div>
  22. </div>
  23. </div>
  24. </div>
  25. </section>
  1. .card {
  2. &__cta {
  3. position: absolute;
  4. top: 50%;
  5. left: 50%;
  6. transform: translate(-50%, -50%);
  7. width: 90%;
  8. text-align: center;
  9. }
  10. &__price-box {
  11. text-align: center;
  12. color: $color-white;
  13. margin-bottom: 8rem;
  14. }
  15. &__price-only {
  16. font-size: 1.4rem;
  17. text-transform: uppercase;
  18. }
  19. &__price-value {
  20. font-size: 6rem;
  21. font-weight: 100;
  22. }
  23. }

⬆ back to top

Green Button

  1. <div class="u-center-text u-margin-top-huge">
  2. <a href="#" class="btn btn--green">Discover all tours</a>
  3. </div>
  1. .btn {
  2. &--green {
  3. background-color: $color-primary;
  4. color: $color-white;
  5. &::after {
  6. background-color: $color-primary;
  7. }
  8. }
  9. }

⬆ back to top

42. Building the Stories Section - Part 1

Thinking about components

  • Secondary Heading
  • Story
    • Shape
    • Text
    • Background video
  • Text button

⬆ back to top

Story component

  1. <section class="section-stories">
  2. <div class="u-center-text u-margin-bottom-big">
  3. <h2 class="heading-secondary">
  4. We make people genuinely happy
  5. </h2>
  6. </div>
  7. <div class="row">
  8. <div class="story">
  9. <figure class="story__shape">
  10. <img src="img/nat-8.jpg" alt="Person on a tour" class="story__img">
  11. </figure>
  12. <div class="story__text">
  13. <h3 class="heading-tertiary u-margin-bottom-small">I had the best week ever with my family</h3>
  14. <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Error, facilis impedit perspiciatis voluptatum iure odio earum in tenetur explicabo beatae, quas minima iste provident omnis quod deleniti sed pariatur quibusdam!</p>
  15. </div>
  16. </div>
  17. </div>
  18. </section>
  1. .section-stories {
  2. padding: 15rem 0;
  3. background-color: $color-grey-light-1;
  4. }
  5. .story {
  6. width: 75%;
  7. margin: 0 auto;
  8. box-shadow: 0 3rem 6rem rgba($color-black, .1);
  9. background-color: $color-white;
  10. border-radius: 3px;
  11. padding: 6rem;
  12. padding-left: 9rem;
  13. font-size: $default-font-size;
  14. transform: skewX(-12deg);
  15. &__shape {
  16. width: 15rem;
  17. height: 15rem;
  18. float: left;
  19. -webkit-shape-outside: circle(50% at 50% 50%);
  20. shape-outside: circle(50% at 50% 50%);
  21. -webkit-clip-path: circle(50% at 50% 50%);
  22. clip-path: circle(50% at 50% 50%);
  23. transform: translateX(-3rem) skewX(12deg);
  24. }
  25. &__img {
  26. height: 100%;
  27. }
  28. &__text {
  29. transform: skewX(12deg);
  30. }
  31. }

⬆ back to top

How to make text flow around shapes with shape-outside and float?

The shape-outside CSS property defines a shape—which may be non-rectangular—around which adjacent inline content should wrap.

  1. .story {
  2. width: 75%;
  3. margin: 0 auto;
  4. box-shadow: 0 3rem 6rem rgba($color-black, .1);
  5. background-color: $color-white;
  6. border-radius: 3px;
  7. padding: 6rem;
  8. padding-left: 9rem;
  9. font-size: $default-font-size;
  10. transform: skewX(-12deg);
  11. &__shape {
  12. width: 15rem;
  13. height: 15rem;
  14. float: left;
  15. -webkit-shape-outside: circle(50% at 50% 50%);
  16. shape-outside: circle(50% at 50% 50%);
  17. -webkit-clip-path: circle(50% at 50% 50%);
  18. clip-path: circle(50% at 50% 50%);
  19. transform: translateX(-3rem) skewX(12deg);
  20. }
  21. &__img {
  22. height: 100%;
  23. }
  24. }

⬆ back to top

43. Building the Stories Section - Part 2

⬆ back to top

Story Shape component - Figure Caption

The HTML <figcaption> or Figure Caption element represents a caption or legend describing the rest of the contents of its parent <figure> element.

  1. <div class="story">
  2. <figure class="story__shape">
  3. <img src="img/nat-8.jpg" alt="Person on a tour" class="story__img">
  4. <figcaption class="story__caption">
  5. Mary Smith
  6. </figcaption>
  7. </figure>
  8. </div>
  1. .story {
  2. &__shape {
  3. position: relative;
  4. overflow: hidden;
  5. }
  6. &__img {
  7. height: 100%;
  8. transform: translateX(-4rem) scale(1.4);
  9. backface-visibility: hidden;
  10. transition: all 0.5s;
  11. }
  12. &__caption {
  13. position: absolute;
  14. top: 50%;
  15. left: 50%;
  16. transform: translate(-50%, 20%);
  17. color: $color-white;
  18. text-transform: uppercase;
  19. font-size: 1.7rem;
  20. text-align: center;
  21. opacity: 0;
  22. transition: all 0.5s;
  23. backface-visibility: hidden;
  24. }
  25. &:hover &__caption {
  26. opacity: 1;
  27. transform: translate(-50%, -50%);
  28. }
  29. &:hover &__img {
  30. transform: translateX(-4rem) scale(1);
  31. filter: blur(3px) brightness(80%);
  32. }
  33. }

⬆ back to top

44. Building the Stories Section - Part 3

⬆ back to top

Story component - Background video

Coverr: Free Stock Footage | Royalty Free Videos for Download

  1. <div class="bg-video">
  2. <video class="bg-video__content" autoplay muted>
  3. <source src="img/video.mp4" type="video/mp4" ></source>
  4. <source src="img/video.webm" type="video/webm" ></source>
  5. Your browser is not supported!
  6. </video>
  7. </div>
  1. .section-stories {
  2. position: relative;
  3. }
  4. .story {
  5. background-color: rgba($color-white, .6);
  6. }
  7. .bg-video {
  8. position: absolute;
  9. top: 0;
  10. left: 0;
  11. height: 100%;
  12. width: 100%;
  13. z-index: -1;
  14. opacity: .15;
  15. overflow: hidden;
  16. &__content {
  17. height: 100%;
  18. width: 100%;
  19. object-fit: cover;
  20. }
  21. }

How to use the

  1. <div class="bg-video">
  2. <video class="bg-video__content" autoplay muted>
  3. <source src="img/video.mp4" type="video/mp4" ></source>
  4. <source src="img/video.webm" type="video/webm" ></source>
  5. Your browser is not supported!
  6. </video>
  7. </div>

⬆ back to top

How to create a background video covering an entire section?

  1. .section-stories {
  2. position: relative;
  3. }
  4. .bg-video {
  5. position: absolute;
  6. top: 0;
  7. left: 0;
  8. height: 100%;
  9. width: 100%;
  10. z-index: -1;
  11. opacity: .15;
  12. overflow: hidden;
  13. &__content {
  14. height: 100%;
  15. width: 100%;
  16. object-fit: cover;
  17. }
  18. }

⬆ back to top

How and when to use the object-fit property?

The object-fit CSS property sets how the content of a replaced element, such as an or

  1. .section-stories {
  2. position: relative;
  3. }
  4. .bg-video {
  5. position: absolute;
  6. top: 0;
  7. left: 0;
  8. height: 100%;
  9. width: 100%;
  10. z-index: -1;
  11. opacity: .15;
  12. overflow: hidden;
  13. &__content {
  14. height: 100%;
  15. width: 100%;
  16. object-fit: cover;
  17. }
  18. }

⬆ back to top

45. Building the Booking Section - Part 1

Thinking about components

  • Form
    • Secondary Heading
    • Input: Full name and Email address
    • Radio button
    • Green button

  1. <section class="section-book">
  2. <div class="row">
  3. <div class="book">
  4. <div class="book__form">
  5. <form action="" class="form">
  6. <div class="u-margin-bottom-medium">
  7. <h2 class="heading-secondary">
  8. Start booking now
  9. </h2>
  10. </div>
  11. <div class="form__group">
  12. <input type="text" class="form__input" placeholder="Full Name" id="name" required>
  13. <label for="name" class="form__label">Full name</label>
  14. </div>
  15. <div class="form__group">
  16. <input type="email" class="form__input" placeholder="Email address" id="email" required>
  17. <label for="email" class="form__label">Email address</label>
  18. </div>
  19. </form>
  20. </div>
  21. </div>
  22. </div>
  23. </section>
  1. .section-book {
  2. padding: 15rem 0;
  3. background-image: linear-gradient(to right bottom, $color-primary-light, $color-primary-dark);
  4. }
  5. .book {
  6. background-image:
  7. linear-gradient(
  8. 105deg,
  9. rgba($color-white, 0.9) 0%,
  10. rgba($color-white, 0.9) 50%,
  11. transparent 50%),
  12. url(../img/nat-10.jpg);
  13. background-size: cover;
  14. border-radius: 3px;
  15. box-shadow: 0 1.5rem 4rem rgba($color-black, 0.2);
  16. height: 50rem;
  17. &__form {
  18. width: 50%;
  19. padding: 6rem;
  20. }
  21. }

⬆ back to top

How to implement “solid-color gradients”?

The linear-gradient() CSS function creates an image consisting of a progressive transition between two or more colors along a straight line. Its result is an object of the <gradient> data type, which is a special kind of <image>.

  1. .book {
  2. background-image:
  3. linear-gradient(
  4. 105deg,
  5. rgba($color-white, 0.9) 0%,
  6. rgba($color-white, 0.9) 50%,
  7. transparent 50%),
  8. url(../img/nat-10.jpg);
  9. background-size: cover;
  10. border-radius: 3px;
  11. box-shadow: 0 1.5rem 4rem rgba($color-black, 0.2);
  12. height: 50rem;
  13. }

⬆ back to top

46. Building the Booking Section - Part 2

Input component: Full name and Email address

  1. .form {
  2. &__group:not(:last-child) {
  3. margin-bottom: 2rem;
  4. }
  5. &__input {
  6. font-size: 1.5rem;
  7. font-family: inherit;
  8. color: inherit;
  9. padding: 1.5rem 2rem;
  10. border-radius: 2px;
  11. background-color: rgba($color-white, .5);
  12. border: none;
  13. border-bottom: 3px solid transparent;
  14. width: 90%;
  15. display: block;
  16. transition: all .3s;
  17. &:focus {
  18. outline: none;
  19. box-shadow: 0 1rem 2rem rgba($color-black, .2);
  20. border-bottom: 3px solid $color-primary;
  21. }
  22. &:focus:invalid {
  23. border-bottom: 3px solid $color-secondary-dark;
  24. }
  25. &::-webkit-input-placeholder {
  26. color: $color-grey-dark-2;
  27. }
  28. }
  29. &__label {
  30. font-size: 1.2rem;
  31. font-weight: 700;
  32. margin-left: 2rem;
  33. margin-top: .7rem;
  34. display: block;
  35. transition: all .3s;
  36. }
  37. &__input:placeholder-shown + &__label {
  38. opacity: 0;
  39. visibility: hidden;
  40. transform: translateY(-4rem);
  41. }
  42. }

⬆ back to top

How the general and adjacent sibling selectors work and why we need them?

The general sibling combinator (~) separates two selectors and matches the second element only if it follows the first element (though not necessarily immediately), and both are children of the same parent element.

The adjacent sibling combinator (+) separates two selectors and matches the second element only if it immediately follows the first element, and both are children of the same parent element.

  1. <form action="" class="form">
  2. <div class="form__group">
  3. <input type="text" class="form__input" placeholder="Full Name" id="name" required>
  4. <label for="name" class="form__label">Full name</label>
  5. </div>
  6. </div>
  1. .form {
  2. // form__input and form__label are adjacent siblings
  3. &__input:placeholder-shown + &__label {
  4. opacity: 0;
  5. visibility: hidden;
  6. transform: translateY(-4rem);
  7. }
  8. }

⬆ back to top

How to use the ::input-placeholder pseudo-element?

  1. .form {
  2. &__input {
  3. // customise placeholder text
  4. &::-webkit-input-placeholder {
  5. color: $color-grey-dark-2;
  6. }
  7. }
  8. }

⬆ back to top

How and when to use the :focus, :invalid, :placeholder-shown?

The :focus CSS pseudo-class represents an element (such as a form input) that has received focus. It is generally triggered when the user clicks or taps on an element or selects it with the keyboard’s “tab” key.

The :invalid CSS pseudo-class represents any <input> or other <form> element whose contents fail to validate.

The :placeholder-shown CSS pseudo-class represents any <input> or <textarea> element that is currently displaying placeholder text.

  1. .form {
  2. &__group:not(:last-child) {
  3. margin-bottom: 2rem;
  4. }
  5. &__input {
  6. &:focus {
  7. outline: none;
  8. box-shadow: 0 1rem 2rem rgba($color-black, .2);
  9. border-bottom: 3px solid $color-primary;
  10. }
  11. &:focus:invalid {
  12. border-bottom: 3px solid $color-secondary-dark;
  13. }
  14. &::-webkit-input-placeholder {
  15. color: $color-grey-dark-2;
  16. }
  17. }
  18. // css property is applied when placeholder is shown
  19. // css property is remove when placeholder is gone, user key in value
  20. &__input:placeholder-shown + &__label {
  21. opacity: 0;
  22. visibility: hidden;
  23. transform: translateY(-4rem);
  24. }
  25. }

⬆ back to top

47. Building the Booking Section - Part 3

Techniques to build custom radio buttons

  1. <div class="form__group u-margin-bottom-medium">
  2. <div class="form__radio-group">
  3. <input type="radio" class="form__radio-input" id="small" name="size">
  4. <label for="small" class="form__radio-label">
  5. <span class="form__radio-button"></span>
  6. Small tour group
  7. </label>
  8. </div>
  9. <div class="form__radio-group">
  10. <input type="radio" class="form__radio-input" id="large" name="size">
  11. <label for="large" class="form__radio-label">
  12. <span class="form__radio-button"></span>
  13. Large tour group
  14. </label>
  15. </div>
  16. </div>
  1. .form {
  2. &__radio-group {
  3. width: 49%;
  4. display: inline-block;
  5. }
  6. &__radio-input {
  7. display: none;
  8. }
  9. &__radio-label {
  10. font-size: $default-font-size;
  11. cursor: pointer;
  12. position: relative;
  13. padding-left: 4.5rem;
  14. }
  15. &__radio-button {
  16. height: 3rem;
  17. width: 3rem;
  18. border: 5px solid $color-primary;
  19. border-radius: 50%;
  20. display: inline-block;
  21. position: absolute;
  22. left: 0;
  23. top: -.4rem;
  24. &::after {
  25. content: "";
  26. display: block;
  27. height: 1.3rem;
  28. width: 1.3rem;
  29. border-radius: 50%;
  30. position: absolute;
  31. top: 50%;
  32. left: 50%;
  33. transform: translate(-50%, -50%);
  34. background-color: $color-primary;
  35. opacity: 0;
  36. transition: opacity .2s;
  37. }
  38. }
  39. // form__radio-input:checked
  40. // form__radio-label is sibling of form__radio-input:checked
  41. // form__radio-button::after is child of form__radio-label
  42. &__radio-input:checked ~ &__radio-label &__radio-button::after {
  43. opacity: 1;
  44. }
  45. }

⬆ back to top

Green button

  1. <div class="form__group">
  2. <button class="btn btn--green">Next step →</button>
  3. </div>
  1. .btn {
  2. // add & for the <button> element
  3. &,
  4. &:link,
  5. &:visited {
  6. ...
  7. // change for the <button> element
  8. border: none;
  9. cursor: pointer;
  10. }
  11. // add :focus for the <button> element
  12. &:active,
  13. &:focus {
  14. outline: none;
  15. ...
  16. }
  17. }

⬆ back to top

How and when to use the :checked pseudo-classes?

The :checked CSS pseudo-class selector represents any radio (<input type="radio">), checkbox (<input type="checkbox">), or option (<option> in a <select>) element that is checked or toggled to an on state.

  1. .form {
  2. // form__radio-input:checked
  3. // form__radio-label is sibling of form__radio-input:checked
  4. // form__radio-button::after is child of form__radio-label
  5. &__radio-input:checked ~ &__radio-label &__radio-button::after {
  6. opacity: 1;
  7. }
  8. }

⬆ back to top

  1. <footer class="footer">
  2. <div class="footer__logo-box">
  3. <img src="img/logo-green-2x.png" alt="Full logo" class="footer__logo">
  4. </div>
  5. <div class="row">
  6. <div class="col-1-of-2">
  7. <div class="footer__navigation">
  8. <ul class="footer__list">
  9. <li class="footer__item"><a href="#" class="footer__link">Company</a></li>
  10. <li class="footer__item"><a href="#" class="footer__link">Contact us</a></li>
  11. <li class="footer__item"><a href="#" class="footer__link">Careers</a></li>
  12. <li class="footer__item"><a href="#" class="footer__link">Privacy policy</a></li>
  13. <li class="footer__item"><a href="#" class="footer__link">Terms</a></li>
  14. </ul>
  15. </div>
  16. </div>
  17. <div class="col-1-of-2">
  18. <p class="footer__copyright">
  19. Built by <a href="#" class="footer__link">Jonas Schmedtmann</a> for his online course <a href="#" class="footer__link">Advanced CSS and Sass</a>.
  20. Copyright © by Jonas Schmedtmann. You are 100% allowed to use this webpage for both personal
  21. and commercial use, but NOT to claim it as your own design. A credit to the original author, Jonas
  22. Schmedtmann, is of course highly appreciated!
  23. </p>
  24. </div>
  25. </div>
  26. </footer>
  1. .footer {
  2. background-color: $color-grey-dark-3;
  3. padding: 10rem 0;
  4. font-size: 1.4rem;
  5. color: $color-grey-light-1;
  6. &__logo-box {
  7. text-align: center;
  8. margin-bottom: 8rem;
  9. }
  10. &__logo {
  11. width: 15rem;
  12. height: auto
  13. }
  14. &__navigation {
  15. border-top: 1px solid $color-grey-dark;
  16. padding-top: 2rem;
  17. display: inline-block;
  18. }
  19. &__list {
  20. list-style: none;
  21. }
  22. &__item {
  23. display: inline-block;
  24. &:not(:last-child) {
  25. margin-right: 1.5rem;
  26. }
  27. }
  28. &__link {
  29. &:link,
  30. &:visited {
  31. color: $color-grey-light-1;
  32. background-color: $color-grey-dark-3;
  33. text-decoration: none;
  34. text-transform: uppercase;
  35. display: inline-block;
  36. transition: all .2s;
  37. }
  38. &:hover,
  39. &:active {
  40. color: $color-primary;
  41. box-shadow: 0 1rem 2rem rgba($color-black, .4);
  42. transform: rotate(5deg) scale(1.3);
  43. }
  44. }
  45. &__copyright {
  46. border-top: 1px solid $color-grey-dark;
  47. padding-top: 2rem;
  48. width: 80%;
  49. float: right;
  50. }
  51. }

⬆ back to top

49. Building the Navigation - Part 1

Think in components

  • Navigation button
  • Navigation list
  • Navigation background

component css selector z-index
Navigation button navigation__button 2000
Navigation list navigation__nav 1500
Navigation background navigation__background 1000
  1. <div class="navigation">
  2. <input type="checkbox" class="navigation__checkbox" id="navi-toggle">
  3. <label for="navi-toggle" class="navigation__button">MENU</label>
  4. <div class="navigation__background"> </div>
  5. <nav class="navigation__nav">
  6. <ul class="navigation__list">
  7. <li class="navigation__item"><a href="#" class="navigation__link"><span>01</span>About Natous</a></li>
  8. <li class="navigation__item"><a href="#" class="navigation__link"><span>02</span>Your benefits</a></li>
  9. <li class="navigation__item"><a href="#" class="navigation__link"><span>03</span>Popular tours</a></li>
  10. <li class="navigation__item"><a href="#" class="navigation__link"><span>04</span>Stories</a></li>
  11. <li class="navigation__item"><a href="#" class="navigation__link"><span>05</span>Book now</a></li>
  12. </ul>
  13. </nav>
  14. </div>
  1. .navigation {
  2. &__checkbox {
  3. display: none;
  4. }
  5. &__button {
  6. background-color: $color-white;
  7. height: 7rem;
  8. width: 7rem;
  9. position: fixed;
  10. top: 6rem;
  11. right: 6rem;
  12. border-radius: 50%;
  13. z-index: 2000;
  14. }
  15. &__background {
  16. height: 6rem;
  17. width: 6rem;
  18. border-radius: 50%;
  19. position: fixed;
  20. top: 6.5rem;
  21. right: 6.5rem;
  22. background-image: radial-gradient($color-primary-light, $color-primary-dark);
  23. z-index: 1000;
  24. transform: scale(80);
  25. }
  26. &__nav {
  27. height: 100vh;
  28. width: 100%;
  29. position: fixed;
  30. top: 0;
  31. left: 0;
  32. z-index: 1500;
  33. }
  34. &__list {
  35. position: absolute;
  36. top: 50%;
  37. left: 50%;
  38. transform: translate(-50%, -50%);
  39. list-style: none;
  40. text-align: center;
  41. }
  42. &__item {
  43. margin: 1rem;
  44. }
  45. &__link {
  46. &:link,
  47. &:visited {
  48. display: inline-block;
  49. font-size: 3rem;
  50. font-weight: 300;
  51. padding: 1rem 2rem;
  52. color: $color-white;
  53. text-decoration: none;
  54. text-transform: uppercase;
  55. background-image: linear-gradient(120deg, transparent 0%, transparent 50%, $color-white 50%);
  56. background-size: 220%;
  57. transition: all .4s;
  58. span {
  59. margin-right: 1.5rem;
  60. display: inline-block;
  61. }
  62. }
  63. &:hover,
  64. &:active {
  65. background-position: 100%;
  66. color: $color-primary;
  67. transform: translateX(1rem);
  68. }
  69. }
  70. }

⬆ back to top

50. Building the Navigation - Part 2

What the “checkbox hack” is and how it works?

  • label element is link to checkbox with id navi-toggle
  • click label element will check/uncheck checkbox with id navi-toggle
  • if checkbox is checked, scale background by 80 times
  • if checkbox is checked, show Navigation list
  1. <div class="navigation">
  2. <input type="checkbox" class="navigation__checkbox" id="navi-toggle">
  3. <label for="navi-toggle" class="navigation__button">MENU</label>
  4. <div class="navigation__background"> </div>
  5. <nav class="navigation__nav">
  6. </nav>
  7. </div>
  1. .navigation {
  2. &__background {
  3. height: 6rem;
  4. width: 6rem;
  5. }
  6. &__nav {
  7. z-index: 1500;
  8. opacity: 0;
  9. width: 0;
  10. }
  11. &__checkbox:checked ~ &__background{
  12. transform: scale(80);
  13. }
  14. &__checkbox:checked ~ &__nav{
  15. opacity: 1;
  16. width: 100%;
  17. }
  18. }

⬆ back to top

How to animate “solid-color gradients”?

  1. <div class="navigation">
  2. <input type="checkbox" class="navigation__checkbox" id="navi-toggle">
  3. <label for="navi-toggle" class="navigation__button"></label>
  4. <div class="navigation__background"> </div>
  5. <div>
  1. .navigation {
  2. &__checkbox {
  3. display: none;
  4. }
  5. &__button {
  6. background-color: $color-white;
  7. height: 7rem;
  8. width: 7rem;
  9. position: fixed;
  10. top: 6rem;
  11. right: 6rem;
  12. border-radius: 50%;
  13. z-index: 2000;
  14. box-shadow: 0 1rem 3rem rgba($color-black, .1);
  15. text-align: center;
  16. cursor: pointer;
  17. }
  18. &__background {
  19. background-image: radial-gradient($color-primary-light, $color-primary-dark);
  20. z-index: 1000;
  21. transition: transform .8s cubic-bezier(0.83, 0, 0.17, 1);
  22. }
  23. &__checkbox:checked ~ &__background {
  24. transform: scale(80);
  25. }
  26. }

⬆ back to top

How to create custom animation timing functions using cubic bezier curves?

  1. .navigation {
  2. &__background {
  3. transition: transform .8s cubic-bezier(0.83, 0, 0.17, 1);
  4. }
  5. &__nav {
  6. transition: all .8s cubic-bezier(0.68, -0.6, 0.32, 1.6);
  7. }
  8. &__checkbox:checked ~ &__background{
  9. transform: scale(80);
  10. }
  11. &__checkbox:checked ~ &__nav{
  12. opacity: 1;
  13. width: 100%;
  14. }
  15. }

⬆ back to top

51. Building the Navigation - Part 3


⬆ back to top

Navigation button animation

  1. <label for="navi-toggle" class="navigation__button">
  2. <span class="navigation__icon"> </span>
  3. </label>
  1. .navigation {
  2. // ICON
  3. &__icon {
  4. position: relative;
  5. margin-top: 3.5rem;
  6. &,
  7. &::before,
  8. &::after {
  9. width: 3.5rem;
  10. height: 2px;
  11. background-color: $color-grey-dark-3;
  12. display: inline-block;
  13. }
  14. &::before,
  15. &::after {
  16. content: "";
  17. position: absolute;
  18. left: 0;
  19. transition: all .2s;
  20. }
  21. &::before { top: -.8rem; }
  22. &::after { top: .8rem; }
  23. }
  24. &__button:hover &__icon::before {
  25. top: -1rem;
  26. }
  27. &__button:hover &__icon::after {
  28. top: 1rem;
  29. }
  30. &__checkbox:checked + &__button &__icon {
  31. background-color: transparent;
  32. }
  33. &__checkbox:checked + &__button &__icon::before {
  34. top: 0;
  35. transform: rotate(135deg);
  36. }
  37. &__checkbox:checked + &__button &__icon::after {
  38. top: 0;
  39. transform: rotate(-135deg);
  40. }
  41. }

⬆ back to top

How and why to use transform-origin?

The transform-origin CSS property sets the origin for an element’s transformations.

⬆ back to top

In general: create an amazingly creative effect?

Using CSS transitions

  1. <div class="box">Sample</div>
  1. .box {
  2. border-style: solid;
  3. border-width: 1px;
  4. display: block;
  5. width: 100px;
  6. height: 100px;
  7. background-color: #0000FF;
  8. transition: width 2s, height 2s, background-color 2s, transform 2s;
  9. }
  10. .box:hover {
  11. background-color: #FFCCCC;
  12. width: 200px;
  13. height: 200px;
  14. transform: rotate(180deg);
  15. }

⬆ back to top

52. Building a Pure CSS Popup - Part 1

Thinking in components

  • Popup container
  • Popup content
    • Left content: 2 tour photos
    • Right content: secondary and tertiary heading, text, green button

⬆ back to top

How to build a nice popup with only CSS?

  1. <div class="popup">
  2. <div class="popup__content">
  3. <div class="popup__left">
  4. <img src="img/nat-8.jpg" alt="Tour photo" class="popup__img">
  5. <img src="img/nat-9.jpg" alt="Tour photo" class="popup__img">
  6. </div>
  7. <div class="popup__right">
  8. <h2 class="heading-secondary u-margin-bottom-small">Start booking now</h2>
  9. <h3 class="heading-tertiary u-margin-bottom-small">Important – Please read these terms before booking</h3>
  10. <p class="popup__text">
  11. Lorem ipsum dolor sit amet consectetur adipisicing elit. Expedita repellendus quos magni voluptas autem corporis perferendis explicabo cum quidem beatae vero itaque, voluptatibus temporibus rerum labore ut soluta praesentium sit. Lorem ipsum dolor, sit amet consectetur adipisicing elit. Expedita explicabo officiis ea minima molestiae dolorem fugit excepturi iste, ratione vitae vel accusamus corporis, ipsum qui iure, odio maxime quasi doloremque.
  12. </p>
  13. <a href="#" class="btn btn--green">Book now</a>
  14. </div>
  15. </div>
  16. </div>
  1. .popup {
  2. height: 100vh;
  3. width: 100%;
  4. position: fixed;
  5. top: 0;
  6. left: 0;
  7. background-color: rgba($color-black, .8);
  8. z-index: 9999;
  9. &__content {
  10. @include absCenter;
  11. width: 75%;
  12. background-color: $color-white;
  13. box-shadow: 0 2rem 4rem rgba($color-black, .2);
  14. border-radius: 3px;
  15. display: table;
  16. overflow: hidden;
  17. }
  18. &__left {
  19. width: 33.333333%;
  20. display: table-cell;
  21. }
  22. &__right {
  23. width: 66.666667%;
  24. display: table-cell;
  25. vertical-align: middle;
  26. padding: 3rem 5rem;
  27. }
  28. &__img {
  29. display: block;
  30. width: 100%;
  31. }
  32. &__text {
  33. font-size: 1.4rem;
  34. margin-bottom: 4rem;
  35. column-count: 2;
  36. column-gap: 4rem; // 1em = 14px
  37. column-rule: 1px solid $color-grey-light-2;
  38. hyphens: auto;
  39. }
  40. }

⬆ back to top

How to create boxes with equal height using display: table-cell?

  1. .popup {
  2. &__content {
  3. display: table;
  4. }
  5. &__left {
  6. width: 33.333333%;
  7. display: table-cell;
  8. }
  9. &__right {
  10. width: 66.666667%;
  11. display: table-cell;
  12. vertical-align: middle;
  13. }
  14. }

⬆ back to top

How to create CSS text columns?

  1. .popup {
  2. &__text {
  3. column-count: 2;
  4. column-gap: 4rem;
  5. column-rule: 1px solid $color-grey-light-2;
  6. }
  7. }

⬆ back to top

How to automatically hyphenate words using hyphens?

  1. .popup {
  2. &__text {
  3. hyphens: auto;
  4. }
  5. }

⬆ back to top

53. Building a Pure CSS Popup - Part 2

  • Click “Discover our tours” button -> Section tours
  • Click “Book now” button -> open popup
  • Click “x” button -> close popup
  1. <section class="section-tours" id="section-tours">
  2. <a href="#popup" class="btn btn--white">Book now</a>
  3. </section>
  4. <div class="popup" id="popup">
  5. <div class="popup__content">
  6. <div class="popup__left"></div>
  7. <div class="popup__right">
  8. <a href="#section-tours" class="popup__close">×</a>
  9. </div>
  10. </div>
  11. </div>
  1. .popup {
  2. &__content {
  3. opacity: 0;
  4. transform: translate(-50%, -50%) scale(.25);
  5. transition: all .5s .2s;
  6. }
  7. &:target {
  8. opacity: 1;
  9. visibility: visible;
  10. }
  11. &:target &__content {
  12. opacity: 1;
  13. transform: translate(-50%, -50%) scale(1);
  14. }
  15. &__close {
  16. &:link,
  17. &:visited {
  18. color: $color-grey-dark;
  19. position: absolute;
  20. top: 2.5rem;
  21. right: 2.5rem;
  22. font-size: 3rem;
  23. text-decoration: none;
  24. display: inline-block;
  25. transition: all .2s;
  26. line-height: 1;
  27. }
  28. &:hover {
  29. color: $color-primary;
  30. }
  31. }
  32. }

⬆ back to top

How to use the :target pseudo-class?

  • Click “Book now” button in tours section
  • :target pseudo-class with id="popup" -> open popup
  • Click “x” button in popup
  • :target pseudo-class with id="section-tours" -> open section-tours -> close popup
  1. <section class="section-tours" id="section-tours">
  2. <a href="#popup" class="btn btn--white">Book now</a>
  3. </section>
  4. <div class="popup" id="popup">
  5. <div class="popup__content">
  6. <div class="popup__left"></div>
  7. <div class="popup__right">
  8. <a href="#section-tours" class="popup__close">×</a>
  9. </div>
  10. </div>
  11. </div>
  1. .popup {
  2. &__content {
  3. opacity: 0;
  4. }
  5. &:target {
  6. opacity: 1;
  7. visibility: visible;
  8. }
  9. }

⬆ back to top

Section 6: Natours Project — Advanced Responsive Design (Part 3)

Order to write media queries

  • base + typography
  • general layout + grid
  • components

sizzy

⬆ back to top

55. Mobile-First vs Desktop-First and Breakpoints





Screen Resolution Stats Worldwide

⬆ back to top

56. Let’s Use the Power of Sass Mixins to Write Media Queries

How to use the @content and @if Sass directives?

Media Query Manager

Device Group Resolution $breakpoint max-width min-width
Phone 0 - 600px phone 37.5em
Tablet portrait 600 - 900px tab-port 56.25em
Tablet landscape 900 - 1200px tab-land 75em
Desktop 1200 - 1800
Big desktop 1800 - ~ big-desktop 112.5em

Note: 1em = 16px

  1. @mixin respond($breakpoint) {
  2. @if $breakpoint == phone {
  3. @media (max-width: 37.5em) { @content };
  4. }
  5. @if $breakpoint == tab-port {
  6. @media (max-width: 56.25em) { @content };
  7. }
  8. @if $breakpoint == tab-land {
  9. @media (max-width: 75em) { @content };
  10. }
  11. @if $breakpoint == big-desktop {
  12. @media (min-width: 112.5em) { @content };
  13. }
  14. }
Device Group Resolution (px) $breakpoint width font-size (%) font-size
Desktop 1200 - 1800 62.5 1rem = 10px
Tablet landscape 900 - 1200 tab-land <= 1200px 56.25 1rem = 9px
Tablet portrait 600 - 900 tab-port <= 900px 50 1rem = 8px
Phone 0 - 600 phone <= 600px 30 1rem = 4.8px
Big desktop 1800 - ~ big-desktop >= 1800px 75 1rem = 12px
  1. html {
  2. font-size: 62.5%;
  3. @include respond(tab-land) {
  4. font-size: 56.25%;
  5. }
  6. @include respond(tab-port) {
  7. font-size: 50%;
  8. }
  9. @include respond(phone) {
  10. font-size: 30%;
  11. }
  12. @include respond(big-desktop) {
  13. font-size: 75%;
  14. }
  15. }

⬆ back to top

Taking advantage of Chrome DevTools for responsive design.

⬆ back to top

57. Writing Media Queries - Base, Typography and Layout

Base

  1. body {
  2. padding: 3rem;
  3. @include respond(tab-port) {
  4. padding: 0;
  5. }
  6. }
  7. .u-margin-bottom-medium {
  8. margin-bottom: 4rem !important;
  9. @include respond(tab-port) { // width < 900px ?
  10. margin-bottom: 3rem !important;
  11. }
  12. }
  13. .u-margin-bottom-big {
  14. margin-bottom: 8rem !important;
  15. @include respond(tab-port) { // width < 900px ?
  16. margin-bottom: 5rem !important;
  17. }
  18. }

⬆ back to top

Typography

  1. .heading-primary {
  2. &--main {
  3. font-size: 6rem;
  4. letter-spacing: 3.5rem;
  5. @include respond(phone) { // width < 600px ?
  6. font-size: 5rem;
  7. letter-spacing: 1rem;
  8. }
  9. }
  10. &--sub {
  11. letter-spacing: 1.75rem;
  12. @include respond(phone) { // width < 600px ?
  13. letter-spacing: .5rem;
  14. }
  15. }
  16. }
  17. .heading-secondary {
  18. font-size: 3.5rem;
  19. @include respond(tab-port) { // width < 900px ?
  20. font-size: 3rem;
  21. }
  22. @include respond(phone) { // width < 600px ?
  23. font-size: 2.5rem;
  24. }

⬆ back to top

Layout

  1. .navigation {
  2. &__button {
  3. top: 6rem;
  4. right: 6rem;
  5. @include respond(tab-port) { // width < 900px ?
  6. top: 4rem;
  7. right: 4rem;
  8. }
  9. @include respond(phone) { // width < 600px ?
  10. top: 3rem;
  11. right: 3rem;
  12. }
  13. }
  14. &__background {
  15. top: 6.5rem;
  16. right: 6.5rem;
  17. @include respond(tab-port) { // width < 900px ?
  18. top: 4.5rem;
  19. right: 4.5rem;
  20. }
  21. @include respond(phone) { // width < 600px ?
  22. top: 3.5rem;
  23. right: 3.5rem;
  24. }
  25. }
  26. }
  27. .header {
  28. -webkit-clip-path: polygon(0 0, 100% 0, 100% 75vh, 0 100%);
  29. clip-path: polygon(0 0, 100% 0, 100% 75vh, 0 100%);
  30. @include respond(phone) { // width < 600px ?
  31. -webkit-clip-path: polygon(0 0, 100% 0, 100% 85vh, 0 100%);
  32. clip-path: polygon(0 0, 100% 0, 100% 85vh, 0 100%);
  33. }
  34. }
  35. .row {
  36. max-width: $grid-width;
  37. @include respond(tab-port) { // width < 900px ?
  38. max-width: 50rem;
  39. padding: 0 3rem;
  40. }
  41. &:not(:last-child) {
  42. margin-bottom: $gutter-vertical;
  43. @include respond(tab-port) { // width < 900px ?
  44. margin-bottom: $gutter-vertical-small;
  45. }
  46. }
  47. [class^="col-"] {
  48. float: left;
  49. &:not(:last-child) {
  50. margin-right: $gutter-horizontal;
  51. @include respond(tab-port) { // width < 900px ?
  52. margin-right: 0;
  53. margin-bottom: $gutter-vertical-small;
  54. }
  55. }
  56. @include respond(tab-port) { // width < 900px ?
  57. width: 100% !important;
  58. }
  59. }
  60. }
  61. .footer {
  62. padding: 10rem 0;
  63. @include respond(tab-port) { // width < 900px ?
  64. padding: 8rem 0;
  65. }
  66. &__logo-box {
  67. margin-bottom: 8rem;
  68. @include respond(tab-port) { // width < 900px ?
  69. margin-bottom: 6rem;
  70. }
  71. }
  72. &__navigation {
  73. border-top: 1px solid $color-grey-dark;
  74. padding-top: 2rem;
  75. display: inline-block;
  76. @include respond(tab-port) { // width < 900px ?
  77. width: 100%;
  78. text-align: center;
  79. }
  80. }
  81. &__copyright {
  82. width: 80%;
  83. float: right;
  84. @include respond(tab-port) { // width < 900px ?
  85. width: 100%;
  86. float: none;
  87. }
  88. }
  89. }

⬆ back to top

58. Writing Media Queries - About and Features Sections

Home page

  1. .section-about {
  2. padding: 25rem 0;
  3. @include respond(tab-port) { // width < 900px ?
  4. padding: 20rem 0;
  5. }
  6. }
  7. .section-features {
  8. padding: 20rem 0;
  9. @include respond(tab-port) { // width < 900px ?
  10. padding: 10rem 0;
  11. }
  12. }
  13. .section-tours {
  14. padding: 25rem 0 15rem 0;
  15. @include respond(tab-port) { // width < 900px ?
  16. padding: 20rem 0 10rem 0;
  17. }
  18. }
  19. .section-stories {
  20. padding: 15rem 0;
  21. @include respond(tab-port) { // width < 900px ?
  22. padding: 10rem 0;
  23. }
  24. }
  25. .section-book {
  26. padding: 15rem 0;
  27. @include respond(tab-port) { // width < 900px ?
  28. padding: 10rem 0;
  29. }
  30. }

⬆ back to top

About Section

  1. .composition {
  2. &__photo {
  3. width: 55%;
  4. box-shadow: 0 1.5rem 4rem rgba($color-black, .4);
  5. position: absolute;
  6. @include respond(tab-port) { // width < 900px ?
  7. float: left;
  8. position: relative;
  9. width: 33.333333%;
  10. box-shadow: 0 1.5rem 3rem rgba($color-black, .2);
  11. }
  12. &--p1 {
  13. left: 0;
  14. top: -2rem;
  15. @include respond(tab-port) { // width < 900px ?
  16. top: 0;
  17. transform: scale(1.2);
  18. }
  19. }
  20. &--p2 {
  21. right: 0;
  22. top: 2rem;
  23. @include respond(tab-port) { // width < 900px ?
  24. top: -1rem;
  25. transform: scale(1.3);
  26. z-index: 100;
  27. }
  28. }
  29. &--p3 {
  30. left: 20%;
  31. top: 10rem;
  32. @include respond(tab-port) { // width < 900px ?
  33. top: 1rem;
  34. left: 0;
  35. transform: scale(1.1);
  36. }
  37. }
  38. }
  39. }

⬆ back to top

Features Section

  1. .feature-box {
  2. padding: 2.5rem;
  3. @include respond(tab-port) { // width < 900px ?
  4. padding: 2rem;
  5. }
  6. &__icon {
  7. margin-bottom: .5rem;
  8. @include respond(tab-port) { // width < 900px ?
  9. margin-bottom: 0;
  10. }
  11. }
  12. }

⬆ back to top

59. Writing Media Queries - Tours, Stories and Booking Sections

Tours section

  1. .card {
  2. @include respond(tab-port) { // width < 900px ?
  3. // FUNCTIONALITY
  4. height: auto;
  5. border-radius: 3px;
  6. background-color: $color-white;
  7. box-shadow: 0 1.5rem 4rem rgba($color-black, .15);
  8. &__side {
  9. height: auto;
  10. position: relative;
  11. box-shadow: none;
  12. &--back {
  13. transform: rotateY(0);
  14. clip-path: polygon(0 15%, 100% 0, 100% 100%, 0% 100%);
  15. }
  16. }
  17. &:hover &__side--front {
  18. transform: rotateY(0);
  19. }
  20. &__details {
  21. padding: 1rem 3rem;
  22. }
  23. // STYLING
  24. &__cta {
  25. position: relative;
  26. top: 0;
  27. left: 0;
  28. transform: translate(0);
  29. width: 100%;
  30. padding: 7rem 4rem 4rem 4rem;
  31. }
  32. &__price-box {
  33. margin-bottom: 3rem;
  34. }
  35. &__price-value {
  36. font-size: 4rem;
  37. }
  38. }
  39. }

⬆ back to top

Stories section

  1. .story {
  2. width: 75%;
  3. padding: 6rem;
  4. padding-left: 9rem;
  5. transform: skewX(-12deg);
  6. @include respond(tab-port) { // width < 900px ?
  7. width: 100%;
  8. padding: 4rem;
  9. padding-left: 7rem;
  10. }
  11. @include respond(phone) { // width < 600px ?
  12. transform: skewX(0);
  13. }
  14. &__shape {
  15. transform: translateX(-3rem) skewX(12deg);
  16. @include respond(phone) { // width < 600px ?
  17. transform: translateX(-3rem) skewX(0);
  18. }
  19. }
  20. &__text {
  21. transform: skewX(12deg);
  22. @include respond(phone) { // width < 600px ?
  23. transform: skewX(0);
  24. }
  25. }
  26. }

⬆ back to top

Booking section

  1. .book {
  2. background-image:
  3. linear-gradient(
  4. 105deg,
  5. rgba($color-white, 0.9) 0%,
  6. rgba($color-white, 0.9) 50%,
  7. transparent 50%
  8. ),
  9. url(../img/nat-10.jpg);
  10. background-size: 100%;
  11. @include respond(tab-land) { // width < 1200px ?
  12. background-image:
  13. linear-gradient(
  14. 105deg,
  15. rgba($color-white, 0.9) 0%,
  16. rgba($color-white, 0.9) 65%,
  17. transparent 65%
  18. ),
  19. url(../img/nat-10.jpg);
  20. background-size: cover;
  21. }
  22. @include respond(tab-port) { // width < 900px ?
  23. background-image:
  24. linear-gradient(
  25. to right,
  26. rgba($color-white, 0.9) 0%,
  27. rgba($color-white, 0.9) 100%
  28. ),
  29. url(../img/nat-10.jpg);
  30. }
  31. &__form {
  32. width: 50%;
  33. padding: 6rem;
  34. @include respond(tab-land) { // width < 1200px ?
  35. width: 65%;
  36. }
  37. @include respond(tab-port) { // width < 900px ?
  38. width: 100%;
  39. }
  40. }
  41. }
  42. .form {
  43. &__input {
  44. width: 90%;
  45. @include respond(tab-port) { // width < 900px ?
  46. width: 100%;
  47. }
  48. }
  49. &__radio-group {
  50. width: 49%;
  51. @include respond(tab-port) { // width < 900px ?
  52. width: 100%;
  53. margin-bottom: 2rem;
  54. }
  55. }
  56. }

⬆ back to top

60. An Overview of Responsive Images

Responsive design + Web performance

  • Art Direction for when you want to switch pictures at various points, using completely different ones
  • Resolution and density switching can be used together for both performance improvements and responsiveness.
  • Responsive images


⬆ back to top

61. Responsive Images in HTML - Density Switching and Art Direction

Density Switching

Use the srcset attribute on the <img> and <source> elements, together with density descriptors

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

Test density switching with chrome dev tool

  1. console.dir($0)
  2. $0.currentSrc

⬆ back to top

Art Direction

  • Use the <picture> element for art direction
  • Write media queries in HTML
  • Add src attribute in case old browser don’t understand srcset
  1. <picture class="footer__logo">
  2. <source srcset="img/logo-green-small-1x.png 1x, img/logo-green-small-2x.png 2x" media="(max-width: 37.5em)">
  3. <img srcset="img/logo-green-1x.png 1x, img/logo-green-2x.png 2x" alt="Full logo" class="footer__logo" src="img/logo-green-2x.png">
  4. </picture>

⬆ back to top

62. Responsive Images in HTML - Resolution Switching

Allow the browser to decide the best image to download, using the srcset attribute, width descriptors, and the sizes attribute of the <img> element.

  1. <div class="composition">
  2. <img
  3. srcset="img/nat-1.jpg 300w, img/nat-1-large.jpg 1000w"
  4. sizes="(max-width: 65.25em) 20vw, (max-width: 37.5em) 30vw 300px"
  5. alt="Photo 1"
  6. class="composition__photo composition__photo--p1"
  7. src="img/nat-1-large.jpg"
  8. >
  9. </div>
  1. .composition {
  2. &__photo {
  3. width: 55%;
  4. @include respond(tab-port) { // width < 900px ?
  5. width: 33.333333%;
  6. }
  7. &--p1 {
  8. @include respond(tab-port) { // width < 900px ?
  9. transform: scale(1.2);
  10. }
  11. }
  12. }
  13. }

DPR = 1

Device Group Resolution vw range size = breakpoint * vw
Phone 0 - 600px <= 600px 600px * 0.3 = 180px
Tablet portrait 600 - 900px <= 900px 900px * 0.2 = 180px
Tablet landscape 900 - 1200px <= 1200px 300px
Desktop 1200 - 1800px <= 1800px 300px
Big desktop 1800 - ~ >= 1800px 300px
Image width
nat-1.jpg 300px
nat-1-large.jpg 1000px
Device Group selected vw composition &__photo &—p1 actual img width selected by browser
Phone 600px 352px 33.333333% scale(1.2) 140.79 nat-1.jpg
Tablet portrait 900px 352px 33.333333% scale(1.2) 140.79 nat-1.jpg
Tablet landscape 1200px 486px 55% 267px nat-1-large.jpg
Desktop 1800px 648px 55% 356.39px nat-1-large.jpg
Big desktop 1800px 648px 55% 356.39px nat-1-large.jpg

DPR = 2

Device Group Resolution vw range size = breakpoint * vw
Phone 0 - 600px <= 600px 600px * 0.3 = 180px
Tablet portrait 600 - 900px <= 900px 900px * 0.2 = 180px
Tablet landscape 900 - 1200px <= 1200px 300px
Desktop 1200 - 1800px <= 1800px 300px
Big desktop 1800 - ~ >= 1800px 300px
Image width
nat-1.jpg 300px
nat-1-large.jpg 1000px
Device Group selected vw composition &__photo &—p1 actual img width due to DPR selected by browser
Phone 600px 352px 33.333333% scale(1.2) 140.79 281.58px nat-1.jpg
Tablet portrait 900px 352px 33.333333% scale(1.2) 140.79 281.58px nat-1.jpg
Tablet landscape 1200px 486px 55% 267px 534px nat-1-large.jpg
Desktop 1800px 648px 55% 356.39px 712.78px nat-1-large.jpg
Big desktop 1800px 648px 55% 356.39px 712.78px nat-1-large.jpg

⬆ back to top

63. Responsive Images in CSS

  • dpi
  • 1x resolution -> 96 dpi
  • 2x resolution -> 192 dpi
  • condition 1 -> min-resolution: 192dpi and min-width: 37.5em (600px)
  • condition 1 -> min-width: 125em (2000px)

How to implement responsive images in CSS?
How to use resolution media queries to target high-resolution screens with 2x?
How to combine multiple conditions in media queries?

  1. .header {
  2. background-image: linear-gradient(to right bottom, rgba($color-primary-light, 0.8), rgba($color-primary-dark, 0.8)), url(../img/hero-small.jpg);
  3. @media (min-resolution: 192dpi) and (min-width: 37.5em),
  4. (min-width: 125em) {
  5. background-image: linear-gradient(to right bottom, rgba($color-secondary-light, 0.8), rgba($color-secondary-dark, 0.8)), url(../img/hero.jpg);
  6. }
  7. }

⬆ back to top

64. Testing for Browser Support with @supports

⬆ back to top

How to use backdrop-filter? Only work in safari

The backdrop-filter CSS property lets you apply graphical effects such as blurring or color shifting to the area behind an element. Because it applies to everything behind the element, to see the effect you must make the element or its background at least partially transparent.

  • use @supports feature queries to check for supported -webkit-backdrop-filter and backdrop-filter properties
  • Implement graceful degradation on selected
  1. .popup {
  2. background-color: rgba($color-black, .8);
  3. @supports(-webkit-backdrop-filter: blur(10px)) or (backdrop-filter: blur(10px)) {
  4. // only work in safari
  5. -webkit-backdrop-filter: blur(10px);
  6. backdrop-filter: blur(10px);
  7. background-color: rgba($color-black, .3);
  8. }
  9. }

⬆ back to top

  1. .card {
  2. &__side {
  3. -webkit-backface-visibility: hidden;
  4. backface-visibility: hidden;
  5. }
  6. }

⬆ back to top

Media Queries - Safari don’t support standard min/max-resolution

Media Queries: resolution feature

  1. @media (min-resolution: 192dpi) and (min-width: 37.5em),
  2. (-webkit-min-device-pixel-ratio: 2) and (min-width: 37.5em),
  3. (min-width: 125em) {
  4. background-image: linear-gradient(to right bottom, rgba($color-secondary-light, 0.8), rgba($color-secondary-dark, 0.8)), url(../img/hero.jpg);
  5. }

⬆ back to top

65. Setting up a Simple Build Process with NPM Scripts

Build CSS workflow

  1. "scripts": {
  2. "compile:sass": "node-sass sass/main.scss css/style.comp.css",
  3. "concat:css": "concat -o css/style.concat.css css/icon-font.css css/style.comp.css",
  4. "prefix:css": "postcss --use autoprefixer -b 'last 10 versions' css/style.concat.css -o css/style.prefix.css",
  5. "compress:css": "node-sass css/style.prefix.css css/style.css --output-style compressed",
  6. "build:css": "npm-run-all compile:sass concat:css prefix:css compress:css"
  7. }
  1. <html lang="en">
  2. <head>
  3. <link rel="stylesheet" href="css/style.css">
  4. </head>
  5. </html>

⬆ back to top

Development workflow

  1. "scripts": {
  2. "watch:sass": "node-sass sass/main.scss css/style.css -w",
  3. "devserver": "live-server",
  4. "start": "npm-run-all --parallel devserver watch:sass",
  5. }

⬆ back to top

66. Wrapping up the Natours Project: Final Considerations

Change the style of selected text

  1. ::selection {
  2. background-color: $color-primary;
  3. color: $color-white;
  4. }

⬆ back to top

Change media query to cater to touch and non-touch device

  1. .card {
  2. @media only screen and (max-width: 56.25em), // width < 900px ?
  3. only screen and (hover: none) { // touch device
  4. }
  5. }

⬆ back to top

Section 7: Trillo Project — Master Flexbox!

68. Why Flexbox: An Overview of the Philosophy Behind Flexbox

Flexbox

  • Flexbox is a new module in CSS3 that makes it easy to align elements to one another, in different directions and orders;
  • The main idea behind flexbox is to give the container the ability to expand and to shrink elements to best use all the available space;
  • Flexbox replaces float layouts, using less, and more readable and logical code;
  • Flexbox completely changes the way that we build one-dimensional layouts;
  • A true revolution in CSS!


⬆ back to top

69. A Basic Intro to Flexbox: The Flex Container

  1. <div class="container">
  2. <div class="item">1</div>
  3. <div class="item i2">2</div>
  4. <div class="item">3</div>
  5. <div class="item">4</div>
  6. <div class="item">5</div>
  7. </div>
  1. .container {
  2. background-color:#ccc;
  3. padding: 10px;
  4. height: 1000px;
  5. /* use flexbox */
  6. display: flex;
  7. /* set main axis direction */
  8. flex-direction: row;
  9. /* control how items are positioned in main axis */
  10. justify-content: center;
  11. /* control how items are positioned in cross axis */
  12. align-items: center;
  13. }

⬆ back to top

70. A Basic Intro to Flexbox: Flex Items

  1. <div class="container">
  2. <div class="item">1</div>
  3. <div class="item i2">2</div>
  4. <div class="item i3">3</div>
  5. <div class="item i4">4</div>
  6. <div class="item">5</div>
  7. </div>
  1. .item{
  2. background-color:#f1425d;
  3. padding:30px;
  4. margin:30px;
  5. color:#fff;
  6. font-size:40px;
  7. /* all items grow as much as they can */
  8. /* flex-grow: 1; */
  9. /* shorthand for flex-grow flex-shrink flex-basis*/
  10. /* flex: 1; */
  11. }
  12. .i2 {
  13. height: 200px;
  14. /* grow 3x more than other items */
  15. /* flex-grow: 3; */
  16. /* grow to 20% of the flex container */
  17. /* flex-basis: 20%; */
  18. /* grow to 300px */
  19. /* flex-basis: 300px; */
  20. /* not allow to shrink */
  21. /* flex-shrink: 0; */
  22. flex: 0 1 300px;
  23. }
  24. .i3 {
  25. order: 1;
  26. flex: 1;
  27. }
  28. .i4 {
  29. /* over-write align-items in container */
  30. /* align-self: flex-end; */
  31. /* all flex box items order are 0 by default */
  32. order: -1;
  33. }

⬆ back to top

71. A Basic Intro to Flexbox: Adding More Flex Items

  1. <div class="container">
  2. <div class="item">1</div>
  3. <div class="item i2">2</div>
  4. <div class="item i3">3</div>
  5. <div class="item i4">4</div>
  6. <div class="item">5</div>
  7. <div class="item">6</div>
  8. <div class="item">7</div>
  9. <div class="item">8</div>
  10. <div class="item">9</div>
  11. <div class="item">10</div>
  12. </div>
  1. .container{
  2. /* wrap all items to new line if container width is not enough*/
  3. flex-wrap: wrap;
  4. /* align rows in cross axis */
  5. align-content: center;
  6. }

⬆ back to top

72. Project Overview

trillo

⬆ back to top

73. Defining Project Settings and Custom Properties

  1. :root {
  2. --color-white: #fff;
  3. --color-primary: #eb2f64;
  4. --color-primary-light: #FF3366;
  5. --color-primary-dark: #BA265D;
  6. --color-grey-light-1: #faf9f9;
  7. --color-grey-light-2: #f4f2f2;
  8. --color-grey-light-3: #f0eeee;
  9. --color-grey-light-4: #ccc;
  10. --color-grey-dark-1: #333;
  11. --color-grey-dark-2: #777;
  12. --color-grey-dark-3: #999;
  13. --shadow-dark: 0 2rem 6rem rbga(0, 0, 0, .3);
  14. }
  15. * {
  16. margin: 0;
  17. padding: 0;
  18. }
  19. *,
  20. *::before,
  21. *::after {
  22. box-sizing: inherit;
  23. }
  24. html {
  25. box-sizing: border-box;
  26. font-size: 62.5%; // 1rem = 10px, 10px/16px = 62.5%
  27. }
  28. body {
  29. font-family: 'Open Sans', sans-serif;
  30. font-weight: 400;
  31. line-height: 1.6;
  32. background-image: linear-gradient(to right bottom, var(--color-primary-light), var(--color-primary-dark));
  33. background-size: cover;
  34. background-repeat: no-repeat;
  35. min-height: 100vh;
  36. }

⬆ back to top

How and why to use CSS custom properties?

  1. // similar to html selector for css
  2. :root {
  3. --color-primary-light: #FF3366;
  4. --color-primary-dark: #BA265D;
  5. }
  6. body {
  7. background-image: linear-gradient(to right bottom, var(--color-primary-light), var(--color-primary-dark));
  8. }

⬆ back to top

74. Building the Overall Layout

How to think about the overall layout of an app?

  1. <body>
  2. <div class="container">
  3. <header class="header">
  4. Header part
  5. </header>
  6. <div class="content">
  7. <div class="sidebar">
  8. Navigation
  9. </div>
  10. <main class="hotel-view">
  11. Hotel view
  12. </main>
  13. </div>
  14. </div>
  15. </body>

⬆ back to top

Use flexbox in a real-world project for the first time

  1. .container {
  2. max-width: 120rem;
  3. margin: 8rem auto;
  4. background-color: var(--color-grey-light-2);
  5. box-shadow: var(--shadow-dark);
  6. min-height: 50rem;
  7. }
  8. .header {
  9. height: 7rem;
  10. background-color: var(--color-white);
  11. border-bottom: 1px solid var(--color-grey-light-2);
  12. }
  13. .content {
  14. display: flex;
  15. }
  16. .sidebar {
  17. background-color: var(--color-grey-dark-1);
  18. flex: 0 0 18%;
  19. }
  20. .hotel-view {
  21. background-color: var(--color-white);
  22. flex: 1;
  23. }

⬆ back to top

75. Building the Header - Part 1

Components

  • Logo
  • Search bar
  • User navigations
  1. <header class="header">
  2. <img src="img/logo.png" alt="trillo logo" class="logo">
  3. <form action="" class="search">
  4. <input type="text" class="search__input" placeholder="Search hotels">
  5. <button class="search__button">
  6. <svg class="search__icon">
  7. <use xlink:href="img/sprite.svg#icon-magnifying-glass"></use>
  8. </svg>
  9. </button>
  10. </form>
  11. <nav class="user-nav">
  12. <div class="user-nav__icon-box">
  13. <svg class="user-nav__icon">
  14. <use xlink:href="img/sprite.svg#icon-bookmark"></use>
  15. </svg>
  16. <span class="user-nav__notification">7</span>
  17. </div>
  18. <div class="user-nav__icon-box">
  19. <svg class="user-nav__icon">
  20. <use xlink:href="img/sprite.svg#icon-chat"></use>
  21. </svg>
  22. <span class="user-nav__notification">13</span>
  23. </div>
  24. <div class="user-nav__user">
  25. <img src="img/user.jpg" alt="trillo logo" class="user-nav__user-photo">
  26. <span class="user-nav__user-name">Jonas</span>
  27. </div>
  28. </nav>
  29. </header>
  1. // LOGO
  2. .logo {
  3. height: 3.25rem;
  4. }
  5. // SEARCH
  6. .search {
  7. &__input {
  8. }
  9. &__button {
  10. }
  11. &__icon {
  12. height: 2rem;
  13. width: 2rem;
  14. }
  15. }
  16. // USER NAVIGATION
  17. .user-nav {
  18. &__icon-box {
  19. }
  20. &__icon {
  21. height: 2.25rem;
  22. width: 2.25rem;
  23. }
  24. &__notification {
  25. }
  26. &__user {
  27. }
  28. &__user-photo {
  29. height: 3.75rem;
  30. border-radius: 50%;
  31. }
  32. &__user-name {
  33. }
  34. }

⬆ back to top

Why to use SVG icons vs. font icons?

  • Icon fonts are mapped to individual Unicode characters, enabling you to store multiple icons within a single file. Fonts are vectors, so icons scale to any size.
  • Scalable Vector Graphics (SVG) is an XML-based vector graphics format that can scale to any size without losing clarity.

⬆ back to top

How to find, generate and use SVG sprites in HTML?

  • icomoon
  • use a sprite.svg file to contain all svg to reduce backend calls to 1
  1. <header class="header">
  2. <form action="" class="search">
  3. <input type="text" class="search__input" placeholder="Search hotels">
  4. <button class="search__button">
  5. <svg class="search__icon">
  6. <use xlink:href="img/sprite.svg#icon-magnifying-glass"></use>
  7. </svg>
  8. </button>
  9. </form>
  10. <nav class="user-nav">
  11. <div class="user-nav__icon-box">
  12. <svg class="user-nav__icon">
  13. <use xlink:href="img/sprite.svg#icon-bookmark"></use>
  14. </svg>
  15. <span class="user-nav__notification">7</span>
  16. </div>
  17. </nav>
  18. </header>

⬆ back to top

76. Building the Header - Part 2

Search bar Component

  1. header {
  2. font-size: 1.4rem;
  3. height: 7rem;
  4. background-color: var(--color-white);
  5. border-bottom: var(--color-grey-light-2);
  6. display: flex;
  7. justify-content: space-between;
  8. align-items: center;
  9. }
  10. // LOGO
  11. .logo {
  12. height: 3.25rem;
  13. margin-left: 3rem;
  14. }
  15. // SEARCH
  16. .search {
  17. flex: 0 0 40%;
  18. display: flex;
  19. align-items: center;
  20. justify-content: center;
  21. &__input {
  22. font-family: inherit;
  23. font-size: inherit;
  24. color: inherit;
  25. background-color: var(--color-grey-light-2);
  26. border: none;
  27. padding: .7rem 2rem;
  28. border-radius: 100px;
  29. width: 90%;
  30. transition: all .2s;
  31. margin-right: -3.5rem;
  32. &:focus {
  33. outline: none;
  34. width: 100%;
  35. background-color: var(--color-grey-light-3);
  36. }
  37. &::-webkit-input-placeholder {
  38. font-weight: 100;
  39. color: var(--color-grey-light-4);
  40. }
  41. }
  42. &__input:focus + &__button {
  43. background-color: var(--color-grey-light-3);
  44. }
  45. &__button {
  46. border: none;
  47. background-color: var(--color-grey-light-2);
  48. &:focus {
  49. outline: none;
  50. }
  51. &:active {
  52. transform: translateY(2px);
  53. }
  54. }
  55. &__icon {
  56. height: 2rem;
  57. width: 2rem;
  58. fill: var(--color-grey-dark-3)
  59. }
  60. }

⬆ back to top

How to use more advanced flexbox alignment techniques, including justify-content, align-items, align-self and flex?

  1. header {
  2. display: flex;
  3. justify-content: space-between;
  4. align-items: center;
  5. }
  6. .search {
  7. flex: 0 0 40%;
  8. display: flex;
  9. align-items: center;
  10. justify-content: center;
  11. }

⬆ back to top

How to change the color of an SVG icon in CSS?

  1. .search {
  2. &__icon {
  3. height: 2rem;
  4. width: 2rem;
  5. fill: var(--color-grey-dark-3)
  6. }
  7. }

⬆ back to top

77. Building the Header - Part 3

User navigations Component

  1. .user-nav {
  2. align-self: stretch;
  3. display: flex;
  4. & > * {
  5. padding: 0 2rem;
  6. cursor: pointer;
  7. height: 100%;
  8. display: flex;
  9. align-items: center;
  10. }
  11. & > *:hover {
  12. background-color: var(--color-grey-light-2);
  13. }
  14. &__icon-box {
  15. position: relative;
  16. }
  17. &__icon {
  18. height: 2.25rem;
  19. width: 2.25rem;
  20. fill: var(--color-grey-dark-2);
  21. }
  22. &__notification {
  23. font-size: .8rem;
  24. height: 1.75rem;
  25. width: 1.75rem;
  26. border-radius: 50%;
  27. background-color: var(--color-primary);
  28. color: var(--color-white);
  29. position: absolute;
  30. top: 1.5rem;
  31. right: 1.1rem;
  32. display: flex;
  33. justify-content: center;
  34. align-items: center;
  35. }
  36. &__user-photo {
  37. height: 3.75rem;
  38. border-radius: 50%;
  39. margin-right: 1rem;
  40. }
  41. }

⬆ back to top

78. Building the Navigation - Part 1

  1. .sidebar {
  2. background-color: var(--color-grey-dark-1);
  3. flex: 0 0 18%;
  4. display: flex;
  5. flex-direction: column;
  6. justify-content: space-between;
  7. }
  8. // SIDE NAVIGATION
  9. .side-nav {
  10. &__item {
  11. }
  12. &__link {
  13. }
  14. &__icon {
  15. width: 1.75rem;
  16. height: 1.75rem;
  17. }
  18. }
  19. // LEGAL TEXT
  20. .legal {
  21. font-size: 1.2rem;
  22. color: var(--color-grey-light-4);
  23. text-align: center;
  24. padding: 2.5rem;
  25. }

⬆ back to top

How to use some more advanced flexbox alignment techniques, including flex-direction, justify-content and align-items?

  1. .sidebar {
  2. display: flex;
  3. flex-direction: column;
  4. justify-content: space-between;
  5. }

⬆ back to top

79. Building the Navigation - Part 2

  1. .side-nav {
  2. font-size: 1.4rem;
  3. list-style: none;
  4. margin-top: 3.5rem;
  5. &__item {
  6. position: relative;
  7. &:not(:last-child) {
  8. margin-bottom: .5rem;
  9. }
  10. }
  11. &__item::before {
  12. content: "";
  13. position: absolute;
  14. top: 0;
  15. left: 0;
  16. height: 100%;
  17. width: 3px;
  18. background-color: var(--color-primary);
  19. transform: scaleY(0);
  20. transition: transform .2s,
  21. width .4s cubic-bezier(1,0,0,1) .2s,
  22. background-color .1s;
  23. }
  24. &__item:hover::before,
  25. &__item--active::before {
  26. transform: scaleY(1);
  27. width: 100%;
  28. }
  29. &__item:active::before {
  30. background-color: var(--color-primary-light);
  31. }
  32. &__link:link,
  33. &__link:visited {
  34. color: var(--color-grey-light-1);
  35. text-decoration: none;
  36. text-transform: uppercase;
  37. display: block;
  38. padding: 1.5rem 3rem;
  39. position: relative;
  40. z-index: 10;
  41. display: flex;
  42. align-items: center;
  43. }
  44. &__icon {
  45. width: 1.75rem;
  46. height: 1.75rem;
  47. margin-right: 2rem;
  48. fill: currentColor;
  49. }
  50. }

⬆ back to top

How to use scaleY and multiple transition properties with different settings, to create a creative hover effect?

  1. .side-nav {
  2. &__item::before {
  3. content: "";
  4. position: absolute;
  5. top: 0;
  6. left: 0;
  7. height: 100%;
  8. width: 3px;
  9. background-color: var(--color-primary);
  10. transform: scaleY(0);
  11. transition: transform .2s,
  12. width .4s cubic-bezier(1,0,0,1) .2s,
  13. background-color .1s;
  14. }
  15. &__item:hover::before,
  16. &__item--active::before {
  17. transform: scaleY(1);
  18. width: 100%;
  19. }
  20. &__item:active::before {
  21. background-color: var(--color-primary-light);
  22. }
  23. }

⬆ back to top

How and why to use the currentColor CSS variable?

currentColor property take the color value of itself or its parent

  1. <a href="" class="side-nav__link">
  2. <svg class="side-nav__icon">
  3. <use xlink:href="img/sprite.svg#icon-key"></use>
  4. </svg>
  5. <span>Car rental</span>
  6. </a>
  1. .side-nav {
  2. &__link:link,
  3. &__link:visited {
  4. color: var(--color-grey-light-1);
  5. }
  6. &__icon {
  7. fill: currentColor;
  8. }
  9. }

⬆ back to top

80. Building the Hotel Overview - Part 1

Hotel Overview Layout

  1. <div class="gallery">
  2. <figure class="gallery__item">
  3. <img src="img/hotel-1.jpg" alt="Photo of hotel 1" class="gallery__photo">
  4. </figure>
  5. <figure class="gallery__item">
  6. <img src="img/hotel-2.jpg" alt="Photo of hotel 2" class="gallery__photo">
  7. </figure>
  8. <figure class="gallery__item">
  9. <img src="img/hotel-3.jpg" alt="Photo of hotel 3" class="gallery__photo">
  10. </figure>
  11. </div>
  12. <div class="overview">
  13. <h1 class="overview__heading">Hotel Las Palmas</h1>
  14. <div class="overview__stars">
  15. <svg class="overview__icon-star">
  16. <use xlink:href="img/sprite.svg#icon-star"></use>
  17. </svg>
  18. <svg class="overview__icon-star">
  19. <use xlink:href="img/sprite.svg#icon-star"></use>
  20. </svg>
  21. <svg class="overview__icon-star">
  22. <use xlink:href="img/sprite.svg#icon-star"></use>
  23. </svg>
  24. <svg class="overview__icon-star">
  25. <use xlink:href="img/sprite.svg#icon-star"></use>
  26. </svg>
  27. <svg class="overview__icon-star">
  28. <use xlink:href="img/sprite.svg#icon-star"></use>
  29. </svg>
  30. </div>
  31. <div class="overview__location">
  32. <svg class="overview__icon-location">
  33. <use xlink:href="img/sprite.svg#icon-location-pin"></use>
  34. </svg>
  35. <button class="btn-inline">Albufeira, Portugal</button>
  36. </div>
  37. <div class="overview__rating">
  38. <div class="overview__rating-average">8.6</div>
  39. <div class="overview__rating-count">429 votes</div>
  40. </div>
  41. </div>
  1. .gallery {
  2. display: flex;
  3. &__photo {
  4. width: 100%;
  5. display: block;
  6. }
  7. }
  8. .overview {
  9. display: flex;
  10. &__stars {
  11. // flex: 1;
  12. // current block expand to fill entire space
  13. // add full margin to the right of the current content
  14. margin-right: auto;
  15. }
  16. &__icon-star,
  17. &__icon-location {
  18. width: 1.75em;
  19. height: 1.75em;
  20. fill: var(--color-primary);
  21. }
  22. }

⬆ back to top

How to use margin: auto with flexbox, and why it’s so powerful?


Hotel Las Palmas






```scss .overview { display: flex; &__stars { // flex: 1; // current block expand to fill entire space // add full margin to the right of the current content margin-right: auto; } }

⬆ back to top

### 81. Building the Hotel Overview - Part 2

scss //HOTEL OVERVIEW .overview { display: flex; align-items: center; border-bottom: 1px solid var(--color-grey-light-2); &__heading { font-size: 2.25rem; font-weight: 300; text-transform: uppercase; letter-spacing: 1px; padding: 1.5rem 3rem; } &__stars { // flex: 1; // current block expand to fill entire space // add full margin to the right of the current content margin-right: auto; display: flex; } &__icon-star, &__icon-location { width: 1.75em; height: 1.75em; fill: var(--color-primary); } &__location { font-size: 1.2rem; display: flex; align-items: center; } &__icon-location { margin-right: .5rem; } &__rating { background-color: var(--color-primary); color: var(--color-white); margin-left: 3rem; padding: 0 2.25rem; align-self: stretch; display: flex; flex-direction: column; align-items: center; justify-content: center; } &__rating-average { font-size: 2.25rem; font-weight: 300; margin-bottom: -3px; } &__rating-count { font-size: .8rem; text-transform: uppercase; } } // BUTTON INLINE .btn-inline { border: none; color: var(--color-primary); font-size: inherit; border-bottom: 1px solid currentColor; padding-bottom: 2px; display: inline-block; background-color: transparent; cursor: pointer; transition: all .2s; &:hover { color: var(--color-grey-dark-1); } &:focus { outline: none; animation: pulsate 1s infinite; } } @keyframes pulsate { 0% { transform: scale(1); box-shadow: none; } 50% { transform: scale(1.05); box-shadow: 0 1rem 4rem rgba(0,0,0,.25); } 100% { transform: scale(1); box-shadow: none; } }

⬆ back to top

#### Continue to use flexbox properties for easy positioning and alignment.

html <div class="gallery"> <figure class="gallery__item"></figure> <figure class="gallery__item"></figure> <figure class="gallery__item"></figure> </div> <div class="overview"> <h1 class="overview__heading">Hotel Las Palmas</h1> <div class="overview__stars"> <svg class="overview__icon-star"></svg> <svg class="overview__icon-star"></svg> <svg class="overview__icon-star"></svg> <svg class="overview__icon-star"></svg> <svg class="overview__icon-star"></svg> </div> <div class="overview__location"> <svg class="overview__icon-location"></svg> <button class="btn-inline">Albufeira, Portugal</button> </div> <div class="overview__rating"> <div class="overview__rating-average">8.6</div> <div class="overview__rating-count">429 votes</div> </div> </div>

scss .gallery { display: flex; } .overview { display: flex; align-items: center; &__stars { margin-right: auto; display: flex; } &__location { display: flex; align-items: center; } &__rating { display: flex; flex-direction: column; align-items: center; justify-content: center; } }

⬆ back to top

#### How to create an infinite animation?

scss .btn-inline { &:focus { animation: pulsate 1s infinite; } } @keyframes pulsate { 0% { transform: scale(1); box-shadow: none; } 50% { transform: scale(1.05); box-shadow: 0 1rem 4rem rgba(0,0,0,.25); } 100% { transform: scale(1); box-shadow: none; } }

⬆ back to top

### 82. Building the Description Section - Part 1

html <div class="detail"> <div class="description"> <p class="paragraph"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi nisi dignissimos debitis ratione sapiente saepe. Accusantium cumque, quas, ut corporis incidunt deserunt quae architecto voluptate. </p> <p class="paragraph"> Accusantium cumque, quas, ut corporis incidunt deserunt quae architecto voluptate delectus, inventore iure aliquid aliquam. </p> <ul class="list"> <li class="list__item">Close to the bench</li> <li class="list__item">Breakfast included</li> <li class="list__item">Free airport shuttle</li> <li class="list__item">Free wifi in all rooms</li> <li class="list__item">Air conditioning and heating</li> <li class="list__item">Pets allowed</li> <li class="list__item">We speak all languages</li> <li class="list__item">Perfect for families</li> </ul> <div class="recommend"> <p class="recommend__count"> Lucy and 3 other friends recommend this hotel. </p> <div class="recommend__friends"> <img src="img/user-3.jpg" alt="Friend 1" class="recommend__photo"> <img src="img/user-4.jpg" alt="Friend 2" class="recommend__photo"> <img src="img/user-5.jpg" alt="Friend 3" class="recommend__photo"> <img src="img/user-6.jpg" alt="Friend 4" class="recommend__photo"> </div> </div> </div> <div class="user-reviews"> User reviews </div> </div>

scss .detail { display: flex; padding: 4.5rem; background-color: var(--color-grey-light-1); border-bottom: var(--line); } .description { font-size: 1.4rem; background-color: var(--color-white); box-shadow: var(--shadow-light); padding: 3rem; flex: 0 0 60%; margin-right: 4.5rem; } .user-reviews { background-color: yellowgreen; flex: 1; }

⬆ back to top

### 83. Building the Description Section - Part 2

scss // PARAGRAPH .paragraph:not(:last-of-type) { margin-bottom: 2rem; } // LIST .list { list-style: none; margin: 3rem 0; padding: 3rem 0; border-top: var(--line); border-bottom: var(--line); display: flex; flex-wrap: wrap; &__item { flex: 0 0 50%; margin-bottom: .7rem; } &__item::before { content: ""; display: inline-block; height: 1rem; width: 1rem; margin-right: .7rem; // older browser // background-image: url(../img/chevron-thin-right.svg); // background-size: cover; // newer browser background-color: var(--color-primary); -webkit-mask-image: url(../img/chevron-thin-right.svg); -webkit-mask-size: cover; mask-image: url(../img/chevron-thin-right.svg); mask-size: cover; } } // RECOMMEND .recommend { font-size: 1.3rem; color: var(--color-grey-dark-3); display: flex; align-items: center; &__count { margin-right: auto; } &__friends { display: flex; } &__photo { box-sizing: content-box; height: 4rem; width: 4rem; border-radius: 50%; border: 3px solid var(--color-white); &:not(:last-child) { margin-right: -1.15rem; } } }

#### Continue to use flexbox, including flex-wrap to build a multi-column list

html <ul class="list"> <li class="list__item">Close to the bench</li> <li class="list__item">Breakfast included</li> <li class="list__item">Free airport shuttle</li> <li class="list__item">Free wifi in all rooms</li> <li class="list__item">Air conditioning and heating</li> <li class="list__item">Pets allowed</li> <li class="list__item">We speak all languages</li> <li class="list__item">Perfect for families</li> </ul> <div class="recommend"> <p class="recommend__count"> Lucy and 3 other friends recommend this hotel. </p> <div class="recommend__friends"> <img src="img/user-3.jpg" alt="Friend 1" class="recommend__photo"> <img src="img/user-4.jpg" alt="Friend 2" class="recommend__photo"> <img src="img/user-5.jpg" alt="Friend 3" class="recommend__photo"> <img src="img/user-6.jpg" alt="Friend 4" class="recommend__photo"> </div> </div>

scss .list { display: flex; flex-wrap: wrap; &__item { flex: 0 0 50%; } } .recommend { display: flex; align-items: center; }

⬆ back to top

#### How and why to use CSS masks with mask-image and mask-size?

scss .list { &__item::before { background-color: var(--color-primary); -webkit-mask-image: url(../img/chevron-thin-right.svg); -webkit-mask-size: cover; mask-image: url(../img/chevron-thin-right.svg); mask-size: cover; } }

⬆ back to top

### 84. Building the User Reviews Section

Continue using and practicing flexbox

html <div class="user-reviews"> <figure class="review"> <blockquote class="review__text"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fuga doloremque architecto dicta animi, totam, itaque officia ex. </blockquote> <figcaption class="review__user"> <img src="img/user-1.jpg" alt="User 1" class="review__photo"> <div class="review__user-box"> <p class="review__user-name">Nick Smith</p> <p class="review__user-date">Feb 23rd, 2017</p> </div> <div class="review__rating">7.8</div> </figcaption> </figure> <figure class="review"> <blockquote class="review__text"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fuga doloremque architecto dicta animi. </blockquote> <figcaption class="review__user"> <img src="img/user-2.jpg" alt="User 1" class="review__photo"> <div class="review__user-box"> <p class="review__user-name">Mary Thomas</p> <p class="review__user-date">Sept 13th, 2017</p> </div> <div class="review__rating">9.3</div> </figcaption> </figure> <button class="btn-inline">Show all<span>→</span></button> </div>

scss .detail { font-size: 1.4rem; } .user-reviews { flex: 1; display: flex; flex-direction: column; align-items: center; } .review { background-color: var(--color-white); box-shadow: var(--shadow-light); padding: 3rem; margin-bottom: 3.5rem; position: relative; overflow: hidden; &__text { margin-bottom: 2rem; z-index: 20; position: relative; } &__user { display: flex; align-items: center; } &__photo { height: 4.5rem; width: 4.5rem; border-radius: 50%; margin-right: 1.5rem; } &__user-box { margin-right: auto; } &__user-name { font-size: 1.1rem; font-weight: 600; text-transform: uppercase; margin-bottom: .4rem; } &__user-date { font-size: 1rem; color: var(--color-grey-dark-3); } &__rating { color: var(--color-primary); font-size: 2.2rem; font-weight: 300; } &::before { content: "\201C"; position: absolute; top: -2.75rem; left: -1rem; line-height: 1; font-size: 20rem; color: var(--color-grey-light-2); font-family: sans-serif; z-index: 1; } } .btn-inline { transition: all .2s; & span { margin-left: 3px; transition: margin-left .2s; } &:hover { color: var(--color-grey-dark-1); span { margin-left: 8px; } }

⬆ back to top

### 85. Building the CTA Section

Yet another creative and modern hover effect

html <div class="cta"> <h2 class="cta__book-now"> Good news! We have 4 free rooms for your selected dates! </h2> <button class="btn"> <span class="btn__visible">Book now</span> <span class="btn__invisible">Only 4 rooms left</span> </button> </div>

scss .cta { padding: 3.5rem 0; text-align: center; &__book-now { font-size: 2rem; font-weight: 300; text-transform: uppercase; margin-bottom: 2.5rem; } } .btn { font-size: 1.5rem; font-weight: 300; text-transform: uppercase; border-radius: 100px; border: none; background-image: linear-gradient(to right, var(--color-primary-light), var(--color-primary-dark)); color: var(--color-white); position: relative; overflow: hidden; cursor: pointer; & > * { display: inline-block; height: 100%; width: 100%; transition: all .2s; } &__visible { padding: 2rem 7.5rem; } &__invisible { position: absolute; padding: 2rem 0; left: 0; top: -100%; } &:hover { background-image: linear-gradient(to left, var(--color-primary-light), var(--color-primary-dark)); } &:hover &__visible { transform: translateY(100%); } &:hover &__invisible { top: 0; } &:focus { outline: none; animation: pulsate 1s infinite; } }

⬆ back to top

### 86. Writing Media Queries - Part 1
### 87. Writing Media Queries - Part 2

- CSS variables are not working for media queries
- We use SCSS variables for media queries

scss $bp-largest: 75em; // 1200px $bp-large: 68.75em; // 1100px $bp-medium: 56.25em; // 900px $bp-small: 37.5em; // 600px $bp-smallest: 31.25em; // 500px html { font-size: 62.5%; // 1rem = 10px, 10px/16px = 62.5% @media only screen and (max-width: $bp-large) { font-size: 50%; } } .container { max-width: 120rem; margin: 8rem auto; @media only screen and (max-width: $bp-largest) { margin: 0; max-width: 100%; width: 100%; } } .header { height: 7rem; display: flex; justify-content: space-between; align-items: center; @media only screen and (max-width: $bp-smallest) { flex-wrap: wrap; align-content: space-around; height: 11rem; } } .content { display: flex; @media only screen and (max-width: $bp-medium) { flex-direction: column; } } .detail { display: flex; padding: 4.5rem; @media only screen and (max-width: $bp-medium) { padding: 3rem; } @media only screen and (max-width: $bp-small) { flex-direction: column; } } .description { padding: 3rem; margin-right: 4.5rem; @media only screen and (max-width: $bp-medium) { padding: 2rem; margin-right: 3rem; } @media only screen and (max-width: $bp-small) { margin-right: 0; margin-bottom: 3rem; } } .search { flex: 0 0 40%; display: flex; align-items: center; justify-content: center; @media only screen and (max-width: $bp-smallest) { order: 1; flex: 0 0 100%; background-color: var(--color-grey-light-2); } } .side-nav { margin-top: 3.5rem; @media only screen and (max-width: $bp-medium) { display: flex; margin: 0; } &__item { &:not(:last-child) { margin-bottom: .5rem; @media only screen and (max-width: $bp-medium) { margin: 0; } } @media only screen and (max-width: $bp-medium) { flex: 1; } } &__link:link, &__link:visited { padding: 1.5rem 3rem; @media only screen and (max-width: $bp-medium) { justify-content: center; padding: 2rem; } @media only screen and (max-width: $bp-small) { flex-direction: column; padding: 1.5rem .5rem; } } &__icon { width: 1.75rem; height: 1.75rem; margin-right: 2rem; @media only screen and (max-width: $bp-small) { margin-right: 0; margin-bottom: .7rem; width: 1.5rem; height: 1.5rem; } } } .legal { @media only screen and (max-width: $bp-medium) { display: none; } } .overview { &__heading { font-size: 2.25rem; padding: 1.5rem 3rem; @media only screen and (max-width: $bp-small) { font-size: 1.8rem; padding: 1.25rem 2rem; } } &__rating { padding: 0 2.25rem; @media only screen and (max-width: $bp-small) { padding: 0 1.5rem; } } &__rating-average { font-size: 2.25rem; @media only screen and (max-width: $bp-small) { font-size: 1.8rem; } } &__rating-count { font-size: .8rem; @media only screen and (max-width: $bp-small) { font-size: .5rem; } } } .review { padding: 3rem; margin-bottom: 3.5rem; @media only screen and (max-width: $bp-medium) { padding: 2rem; margin-bottom: 3rem; } } .cta { padding: 3.5rem 0; @media only screen and (max-width: $bp-medium) { padding: 2.5rem 0; } }

⬆ back to top

### 88. Wrapping up the Trillo Project: Final Considerations

caniuse

scss .list { &__item::before { // Older browsers background-image: url(../img/chevron-thin-right.svg); background-size: cover; //Newer browsers - masks @supports (-webkit-mask-image: url()) or (mask-image: url()) { background-color: var(--color-primary); -webkit-mask-image: url(../img/chevron-thin-right.svg); -webkit-mask-size: cover; mask-image: url(../img/chevron-thin-right.svg); mask-size: cover; background-image: none; } } }

Challenges

- Display some kind of user menu when hovering over the username in .user-nav;
- Display a message menu when hovering overthe chat icon in .user-nav (maybe like facebook);
- Display a box with search suggestions as soon as the user starts typing in the search field;
- Create a caption for the .gallery__item with a nice hover effect;
- Make the page 100% responsive even for viewport sizes below 500px, maybe even responsive images.

⬆ back to top

## Section 8: A Quick Introduction to CSS Grid Layouts

### 90. Why CSS Grid: A Whole New Mindset

CSS Grid

- CSS Grid Layout is a brand new module that brings a two-dimensional grid system to CSS for the first time;
- CSS Grid replaces float layouts, using less, and more readable and logical CSS and HTML;
- CSS Grid works perfectly together with Flexbox, which is best to handle one-dimensional components and layouts;
- CSS Grid completely changes the way that we envision and build two-dimensional layouts.






⬆ back to top

### 92. Creating Our First Grid



html <div class="container"> <div class="item item--1">1: Orange</div> <div class="item item--2">2: Green</div> <div class="item item--3">3: Violet</div> <div class="item item--4">4: Pink</div> <div class="item item--5">5: Blue</div> <div class="item item--6">6: Brown</div> </div>

scss .container { background-color: #eee; width: 1000px; margin: 30px auto; display: grid; grid-template-rows: 150px 150px; grid-template-columns: 150px 150px 150px; // grid-row-gap: 30px; // grid-column-gap: 30px; grid-gap: 30px; // keeps all gaps the same } .item { padding: 20px; font-size: 30px; font-family: sans-serif; color: white; &--1 { background-color: orangered; } &--2 { background-color: yellowgreen; } &--3 { background-color: blueviolet; } &--4 { background-color: palevioletred; } &--5 { background-color: royalblue; } &--6 { background-color: goldenrod; } }

⬆ back to top

### 93. Getting Familiar with the fr Unit

scss .container { background-color: #eee; width: 1000px; margin: 30px auto; // height: 1000px; display: grid; grid-template-rows: repeat(2, 150px); // grid-template-rows: repeat(2, 1fr); // grid-template-columns: repeat(2, 150px) 1fr; grid-template-columns: repeat(3, 1fr); // grid-template-columns: 1fr 2fr 1fr; // grid-template-columns: 50% 1fr 2fr; // grid-row-gap: 30px; // grid-column-gap: 50px; grid-gap: 30px; // keeps all gaps the same }

⬆ back to top

### 94. Positioning Grid Items



scss .item { padding: 20px; font-size: 30px; font-family: sans-serif; color: white; &--1 { background-color: orangered; grid-row: 2 / 3; // grid-row-start: 2; // grid-row-end: 3; grid-column: 2 / 3; // grid-column-start: 2; // grid-column-end: 3; } &--5 { background-color: royalblue; grid-area: 1 / 3 / 2 / 4; // grid-row: 1 / 2; // grid-column: 3 / 4; } &--6 { background-color: goldenrod; grid-row: 1 / 2; grid-column: 2 / 3; } }

⬆ back to top

### 95. Spanning Grid Items

Items can be placed in the same cell.

scss .item { padding: 20px; font-size: 30px; font-family: sans-serif; color: white; &--1 { background-color: orangered; grid-row: 2 / 3; // grid-row-start: 2; // grid-row-end: 3; grid-column: 2 / 3; // grid-column-start: 2; // grid-column-end: 3; z-index: 10; } &--2 { background-color: yellowgreen; // grid-column: 2 / span 2; grid-column: 1 / -1; } &--3 { background-color: blueviolet; grid-row: 2 / 3; grid-column: 1 / 3; } &--4 { background-color: palevioletred; } &--5 { background-color: royalblue; grid-area: 1 / 3 / 3 / 4; // grid-row: 1 / 3; // grid-column: 3 / 4; } &--6 { background-color: goldenrod; grid-row: 1 / 2; grid-column: 2 / 3; } }

⬆ back to top

### 96. Grid Challenge



⬆ back to top

### 97. Grid Challenge: A Basic Solution

html <div class="container"> <div class="header">Header</div> <div class="small-box-1">Small box 1</div> <div class="small-box-2">Small box 2</div> <div class="small-box-3">Small box 3</div> <div class="main-content">Main content</div> <div class="sidebar">Sidebar</div> <div class="footer">Footer</div> </div>

scss .container { width: 1000px; margin: 30px auto; display: grid; grid-template-rows: 100px 200px 400px 100px; grid-template-columns: repeat(3, 1fr) 200px; grid-gap: 30px; & > * { background-color: orangered; padding: 20px; color: white; font-size: 30px; font-family: sans-serif; } } .header { grid-column: 1 / -1; } .sidebar { grid-row: 2 / span 2; grid-column: 4 / 5; } .main-content { grid-column: 1 / span 3; } .footer { grid-column: 1 / -1; }

⬆ back to top

### 98. Naming Grid Lines

scss .container { width: 1000px; margin: 30px auto; display: grid; grid-template-rows: [header-start] 100px [header-end box-start] 200px [box-end main-start] 400px [main-end footer-start] 100px [footer-end]; grid-template-columns: repeat(3, [col-start] 1fr [col-end]) 200px [grid-end]; grid-gap: 30px; & > * { background-color: orangered; padding: 20px; color: white; font-size: 30px; font-family: sans-serif; } } .header { grid-column: col-start 1 / grid-end; } .sidebar { grid-row: box-start / main-end; grid-column: col-end 3 / grid-end; } .main-content { grid-column: col-start 1 / col-end 3; } .footer { grid-column: col-start 1 / grid-end; }

⬆ back to top

### 99. Naming Grid Areas

use . to represent empty cell

scss .container { width: 1000px; margin: 30px auto; display: grid; grid-template-rows: 100px 200px 400px 100px; grid-template-columns: repeat(3, 1fr) 200px; grid-gap: 30px; grid-template-areas: ". head head ." "box-1 box-2 box-3 side" "main main main side" "foot foot foot foot"; & > * { background-color: orangered; padding: 20px; color: white; font-size: 30px; font-family: sans-serif; } } .header { grid-area: head; } .small-box-1 { grid-area: box-1; } .small-box-2 { grid-area: box-2; } .small-box-3 { grid-area: box-3; } .sidebar { grid-area: side; } .main-content { grid-area: main; } .footer { grid-area: foot; }

⬆ back to top

### 100. Implicit Grids vs. Explicit Grids

html <div class="container"> <div class="item item-1">Modern</div> <div class="item item-2">CSS</div> <div class="item item-3">with</div> <div class="item item-4">Flexbox</div> <div class="item item-5">and</div> <div class="item item-6">Grid</div> <div class="item item-7">is</div> <div class="item item-8">great</div> </div>

scss .container { width: 1000px; margin: 30px auto; background-color: #ddd; display: grid; grid-template-rows: repeat(2, 150px); grid-template-columns: repeat(2, 1fr); grid-gap: 30px; grid-auto-rows: 80px; grid-auto-flow: column; grid-auto-columns: .5fr; .item { padding: 20px; color: white; font-family: sans-serif; font-size: 30px; background-color: orangered; } }

⬆ back to top

### 101. Aligning Grid Items

html <div class="container"> <div class="item item--1">Modern</div> <div class="item item--2">CSS</div> <div class="item item--3">with</div> <div class="item item--4">Flexbox</div> <div class="item item--5">and</div> <div class="item item--6">Grid</div> <div class="item item--7">is</div> <div class="item item--8">great</div> </div>

scss .container { width: 1000px; margin: 30px auto; background-color: #ddd; display: grid; grid-template-rows: repeat(2, 150px); grid-template-columns: repeat(2, 1fr); grid-gap: 30px; grid-auto-rows: 80px; grid-auto-flow: row; grid-auto-columns: .5fr; align-items: center; justify-items: center; .item { padding: 10px; color: white; font-family: sans-serif; font-size: 30px; background-color: orangered; &--4 { background-color: crimson; grid-row: 2 / span 3; align-self: start; justify-self: start; } &--7 { background-color: palevioletred; grid-column: 1 / -1; } } }

⬆ back to top

### 102. Aligning Tracks

scss .container { width: 1000px; margin: 30px auto; background-color: #ddd; display: grid; grid-gap: 30px; grid-auto-rows: 80px; grid-auto-flow: row dense; // patch up the hole with dense grid-auto-columns: .5fr; // align grid items to grid area // align-items: center; // justify-items: center; // align grid tracks to grid container grid-template-rows: repeat(2, 100px); grid-template-columns: repeat(2, 200px); height: 1000px; justify-content: center; //horizontal direction align-content: center; //vertical direction .item { padding: 10px; color: white; font-family: sans-serif; font-size: 30px; background-color: orangered; &--4 { background-color: crimson; grid-row: 2 / span 3; // align-self: start; // justify-self: start; } &--6 { background-color: lightcoral; grid-row: 2 / span 2; } &--7 { background-color: palevioletred; grid-column: 1 / -1; } } }

⬆ back to top

### 103. Using min-content, max-content and the minmax() function

html <div class="container"> <div class="item item--1">Modern</div> <div class="item item--2">CSS</div> <div class="item item--3">with</div> <div class="item item--4">Flexbox</div> <div class="item item--5">and</div> <div class="item item--6">Grid</div> <div class="item item--7">is</div> <div class="item item--8">great</div> </div>

scss .container { width: 1000px; margin: 30px auto; background-color: #ddd; display: grid; // use min-content and max-content // grid-template-rows: repeat(2, 150px); // grid-template-rows: repeat(2, min-content); // grid-template-columns: max-content 1fr 1fr min-content; // using minmax function width: 90%; grid-template-rows: repeat(2, minmax(150px, min-content)); // grid-template-columns: minmax(200px, 300px) repeat(3, 1fr); // grid-template-columns: minmax(200px, 50%) repeat(3, 1fr); grid-template-columns: minmax(200px, 1fr) repeat(3, 1fr); .item { padding: 10px; color: white; font-family: sans-serif; font-size: 30px; background-color: orangered; &--1 { background-color: orangered; } &--2 { background-color: yellowgreen; } &--3 { background-color: blueviolet; } &--4 { background-color: palevioletred; } &--5 { background-color: royalblue; } &--6 { background-color: goldenrod; } &--7 { background-color: crimson; } &--8 { background-color: darkslategray; } } }

⬆ back to top

### 104. Responsive Layouts with auto-fit and auto-fill

scss .container { width: 1000px; margin: 30px auto; background-color: #ddd; display: grid; // use min-content and max-content // grid-template-rows: repeat(2, 150px); // grid-template-rows: repeat(2, min-content); // grid-template-columns: max-content 1fr 1fr min-content; // using minmax function // width: 90%; // grid-template-rows: repeat(2, minmax(150px, min-content)); // grid-template-columns: minmax(200px, 300px) repeat(3, 1fr); // grid-template-columns: minmax(200px, 50%) repeat(3, 1fr); // grid-template-columns: minmax(200px, 1fr) repeat(3, 1fr); // use auto-fill and auto-fit grid-template-rows: repeat(2, minmax(150px, min-content)); // grid-template-columns: repeat(auto-fill, 100px); // grid-template-columns: repeat(auto-fit, 100px); width: 90%; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); grid-auto-rows: 150px; .item { padding: 10px; color: white; font-family: sans-serif; font-size: 30px; background-color: orangered; &--1 { background-color: orangered; } &--2 { background-color: yellowgreen; } &--3 { background-color: blueviolet; } &--4 { background-color: palevioletred; } &--5 { background-color: royalblue; } &--6 { background-color: goldenrod; } &--7 { background-color: crimson; } &--8 { background-color: darkslategray; } } }

⬆ back to top

## Section 9: Nexter Project — Master CSS Grid Layouts!

### 105. Project Overview and Setup

nexter

html <body class="container"> TEST TEXT </body>

scss *, *::before, *::after { margin: 0; padding: 0; box-sizing: inherit; } html { box-sizing: border-box; font-size: 62.5%; // 10px/16px = 62.5% -> 1rem = 10px } body { font-family: $font-primary; color: $color-grey-dark-2; font-weight: 300; line-height: 1.6; }

⬆ back to top

### 106. Building the Overall Layout - Part 1

```html

  1. <header class="header">header</header>
  2. <div class="realtors">Top 3 Realtors</div>
  3. <section class="features">features</section>
  4. <div class="story__pictures">story pictures</div>
  5. <div class="story__content">story content</div>
  6. <section class="homes">homes</section>
  7. <section class="gallery">gallery</section>
  8. <footer class="footer">footer</footer>
  9. </body>
  1. ```scss
  2. .container {
  3. display: grid;
  4. grid-template-rows: 80vh min-content 40vw repeat(3, min-content);
  5. }

107. Building the Overall Layout - Part 2

  1. .container {
  2. display: grid;
  3. grid-template-rows: 80vh min-content 40vw repeat(3, min-content);
  4. // 1140 / 0 = 140px = 14rem
  5. // center content on the page up to 1140px
  6. grid-template-columns: [sidebar-start] 8rem [sidebar-end full-start] minmax(6rem, 1fr) [center-start] repeat(8, [col-start] minmax(min-content, 14rem) [col-end]) [center-end] minmax(6rem, 1fr) [full-end];
  7. }
  8. .sidebar {
  9. background-color: $color-primary;
  10. grid-column: sidebar-start / sidebar-end;
  11. grid-row: 1 / -1;
  12. }
  13. .header {
  14. background-color: $color-grey-dark-1;
  15. grid-column: full-start / col-end 6;
  16. }
  17. .realtors {
  18. background-color: $color-secondary;
  19. grid-column: col-start 7 / full-end;
  20. }
  21. .features {
  22. background-color: $color-grey-light-2;
  23. grid-column: center-start / center-end;
  24. }
  25. .story {
  26. &__pictures {
  27. background-color: $color-primary;
  28. grid-column: full-start /col-end 4;
  29. }
  30. &__content {
  31. background-color: $color-grey-light-1;
  32. grid-column: col-start 5 /full-end;
  33. }
  34. }
  35. .homes {
  36. background-color: $color-secondary;
  37. grid-column: center-start / center-end;
  38. }
  39. .gallery {
  40. background-color: $color-grey-dark-1;
  41. grid-column: full-start / full-end;
  42. }
  43. .footer {
  44. background-color: $color-secondary;
  45. grid-column: full-start / full-end;
  46. }

How to build a complex and modern layout using advanced CSS Grid techniques?

  • Determine the layput
  • sidebar: 1 column
  • content
    • left: 1 column
    • center: 8 columns (max: 1140px)
    • right: 1 column
  1. .container {
  2. display: grid;
  3. grid-template-rows: 80vh min-content 40vw repeat(3, min-content);
  4. // 1140 / 0 = 140px = 14rem
  5. // center content on the page up to 1140px
  6. grid-template-columns: [sidebar-start] 8rem [sidebar-end full-start] minmax(6rem, 1fr) [center-start] repeat(8, [col-start] minmax(min-content, 14rem) [col-end]) [center-end] minmax(6rem, 1fr) [full-end];
  7. }

⬆ back to top

How to choose different row and column track sizes for different types of content?

  1. .sidebar {
  2. grid-column: sidebar-start / sidebar-end;
  3. grid-row: 1 / -1;
  4. }
  5. .header { grid-column: full-start / col-end 6; }
  6. .realtors { grid-column: col-start 7 / full-end; }
  7. .features { grid-column: center-start / center-end; }
  8. .story {
  9. &__pictures { grid-column: full-start /col-end 4; }
  10. &__content { grid-column: col-start 5 /full-end; }
  11. }
  12. .homes { grid-column: center-start / center-end; }
  13. .gallery { grid-column: full-start / full-end; }
  14. .footer { grid-column: full-start / full-end; }

⬆ back to top

108. Building the Features Section - Part 1

  1. <section class="features">
  2. <div class="feature">
  3. <svg class="feature__icon">
  4. <use xlink:href="img/sprite.svg#icon-global"></use>
  5. </svg>
  6. <h4 class="heading-4 heading-4--dark">World's best luxury homes</h4>
  7. <p class="feature__text">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Tenetur distinctio necessitatibus pariatur voluptatibus.</p>
  8. </div>
  9. <div class="feature">
  10. <svg class="feature__icon">
  11. <use xlink:href="img/sprite.svg#icon-trophy"></use>
  12. </svg>
  13. <h4 class="heading-4 heading-4--dark">Only the best properties</h4>
  14. <p class="feature__text">Voluptatum mollitia quae. Vero ipsum sapiente molestias accusamus rerum sed a eligendi aut quia.</p>
  15. </div>
  16. <div class="feature">
  17. <svg class="feature__icon">
  18. <use xlink:href="img/sprite.svg#icon-map-pin"></use>
  19. </svg>
  20. <h4 class="heading-4 heading-4--dark">All homes in in top locations</h4>
  21. <p class="feature__text">Tenetur distinctio necessitatibus pariatur voluptatibus quidem consequatur harum.</p>
  22. </div>
  23. <div class="feature">
  24. <svg class="feature__icon">
  25. <use xlink:href="img/sprite.svg#icon-key"></use>
  26. </svg>
  27. <h4 class="heading-4 heading-4--dark">New home in one week</h4>
  28. <p class="feature__text">Vero ipsum sapiente molestias accusamus rerum. Lorem, ipsum dolor sit amet consectetur adipisicing elit.</p>
  29. </div>
  30. <div class="feature">
  31. <svg class="feature__icon">
  32. <use xlink:href="img/sprite.svg#icon-presentation"></use>
  33. </svg>
  34. <h4 class="heading-4 heading-4--dark">Top 1% realtors</h4>
  35. <p class="feature__text">Quidem consequatur harum, voluptatum mollitia quae. Tenetur distinctio necessitatibus pariatur voluptatibus.</p>
  36. </div>
  37. <div class="feature">
  38. <svg class="feature__icon">
  39. <use xlink:href="img/sprite.svg#icon-lock"></use>
  40. </svg>
  41. <h4 class="heading-4 heading-4--dark">Secure payments on nexter</h4>
  42. <p class="feature__text">Pariatur voluptatibus quidem consequatur harum, voluptatum mollitia quae.</p>
  43. </div>
  44. </section>
  1. .features {
  2. grid-column: center-start / center-end;
  3. margin: 15rem 0;
  4. display: grid;
  5. grid-template-columns: repeat(3, 1fr);
  6. grid-gap: 6rem;
  7. }

⬆ back to top

How and why to create grids inside of grids?

  1. .features {
  2. grid-column: center-start / center-end;
  3. margin: 15rem 0;
  4. display: grid;
  5. grid-template-columns: repeat(3, 1fr);
  6. grid-gap: 6rem;
  7. }

⬆ back to top

109. Building the Features Section - Part 2

  1. .features {
  2. grid-column: center-start / center-end;
  3. margin: 15rem 0;
  4. display: grid;
  5. grid-template-columns: repeat(auto-fit, minmax(25rem, 1fr));
  6. grid-gap: 6rem;
  7. align-items: start;
  8. }
  9. .feature {
  10. display: grid;
  11. grid-template-columns: min-content 1fr;
  12. grid-row-gap: 1.5rem;
  13. grid-column-gap: 2.5rem;
  14. &__icon {
  15. fill: $color-primary;
  16. width: 4.5rem;
  17. height: 4.5rem;
  18. grid-row: 1 / span 2;
  19. transform: translateY(-1rem);
  20. }
  21. &__text {
  22. font-size: 1.7rem;
  23. }
  24. }
  25. %heading {
  26. font-family: $font-display;
  27. font-weight: 400;
  28. }
  29. .heading-4 {
  30. @extend %heading;
  31. font-size: 1.9rem;
  32. &--light { color: $color-grey-light-1; }
  33. &--dark { color: $color-grey-dark-1; }
  34. }

How to build a small component using CSS Grid?

  1. <div class="feature">
  2. <svg class="feature__icon">
  3. <use xlink:href="img/sprite.svg#icon-lock"></use>
  4. </svg>
  5. <h4 class="heading-4 heading-4--dark">Secure payments on nexter</h4>
  6. <p class="feature__text">Pariatur voluptatibus quidem consequatur harum, voluptatum mollitia quae.</p>
  7. </div>
  1. .feature {
  2. display: grid;
  3. grid-template-columns: min-content 1fr;
  4. grid-row-gap: 1.5rem;
  5. grid-column-gap: 2.5rem;
  6. &__icon {
  7. grid-row: 1 / span 2;
  8. }
  9. }

⬆ back to top

How to create a responsive component without media queries?

  1. .features {
  2. grid-template-columns: repeat(auto-fit, minmax(25rem, 1fr));
  3. }

⬆ back to top

110. Building the Story Section - Part 1

  1. <div class="story__content">
  2. <h3 class="heading-3 mb-sm">Happy Customers</h3>
  3. <h2 class="heading-2 heading-2--dark mb-md">“The best decision of our lives”</h2>
  4. <p class="story__text">
  5. Lorem, ipsum dolor sit amet consectetur adipisicing elit. Tenetur distinctio necessitatibus pariatur voluptatibus. Quidem consequatur harum volupta!
  6. </p>
  7. <button class="btn">Find your own home</button>
  8. </div>
  1. .story {
  2. &__content {
  3. background-color: $color-grey-light-1;
  4. grid-column: col-start 5 / full-end;
  5. padding: 6rem 8vw;
  6. // display: flex;
  7. // flex-direction: column;
  8. // justify-content: center;
  9. // align-items: flex-start;
  10. display: grid;
  11. align-content: center;
  12. justify-items: start;
  13. }
  14. &__text {
  15. font-size: 1.5rem;
  16. font-style: italic;
  17. margin-bottom: 4rem;
  18. }
  19. }
  20. .heading-2 {
  21. @extend %heading;
  22. font-size: 4rem;
  23. font-style: italic;
  24. line-height: 1;
  25. &--light { color: $color-grey-light-1; }
  26. &--dark { color: $color-grey-dark-1; }
  27. }
  28. .heading-3 {
  29. @extend %heading;
  30. font-size: 1.6rem;
  31. color: $color-primary;
  32. text-transform: uppercase;
  33. }
  34. .btn {
  35. background-color: $color-primary;
  36. color: #fff;
  37. border: none;
  38. border-radius: 0;
  39. font-family: $font-display;
  40. font-size: 1.5rem;
  41. text-transform: uppercase;
  42. padding: 1.8rem 3rem;
  43. cursor: pointer;
  44. transition: all .2s;
  45. &:hover {
  46. background-color: $color-primary-dark;
  47. }
  48. }
  49. .mb-sm { margin-bottom: 2rem; }
  50. .mb-md { margin-bottom: 3rem; }
  51. .mb-lg { margin-bottom: 4rem; }
  52. .mb-hg { margin-bottom: 8rem; }

⬆ back to top

111. Building the Story Section - Part 2

  1. <div class="story__pictures">
  2. <img src="img/story-1.jpeg" alt="Couple with new house" class="story__img--1">
  3. <img src="img/story-2.jpeg" alt="New house" class="story__img--2">
  4. </div>
  1. .story {
  2. &__pictures {
  3. background-color: $color-primary;
  4. grid-column: full-start / col-end 4;
  5. background-image: linear-gradient(rgba($color-primary, .5), rgba($color-primary, .5)), url(../img/back.jpg);
  6. background-size: cover;
  7. display: grid;
  8. grid-template-rows: repeat(6, 1fr);
  9. grid-template-columns: repeat(6, 1fr);
  10. align-items: center;
  11. }
  12. &__img--1 {
  13. width: 100%;
  14. grid-row: 2 / 6;
  15. grid-column: 2 / 6;
  16. box-shadow: 0 2rem 5rem rgba(#000, .1);
  17. }
  18. &__img--2 {
  19. width: 115%;
  20. grid-row: 4 / 6;
  21. grid-column: 4 / 7;
  22. z-index: 20;
  23. box-shadow: 0 2rem 5rem rgba(#000, .2);
  24. }
  25. }

⬆ back to top

How to deal with overlapping grid items?

  1. .story {
  2. &__pictures {
  3. display: grid;
  4. grid-template-rows: repeat(6, 1fr);
  5. grid-template-columns: repeat(6, 1fr);
  6. align-items: center;
  7. }
  8. &__img--2 {
  9. width: 115%;
  10. grid-row: 4 / 6;
  11. grid-column: 4 / 7;
  12. z-index: 20;
  13. }
  14. }

⬆ back to top

Why images are special and behave differently than other grid items?

  • image has aspect ratio to maintain

⬆ back to top

How to decide if flexbox is a better tool in certain situations?

Quick! What’s the Difference Between Flexbox and Grid?

⬆ back to top

112. Building the Homes Section - Part 1

  1. <section class="homes">
  2. <div class="home">
  3. <img src="img/house-1.jpeg" alt="House 1" class="home__img">
  4. <svg class="home__like">
  5. <use xlink:href="img/sprite.svg#icon-heart-full"></use>
  6. </svg>
  7. <h5 class="home__name">Beautiful Familiy House</h5>
  8. <div class="home__location">
  9. <svg>
  10. <use xlink:href="img/sprite.svg#icon-map-pin"></use>
  11. </svg>
  12. <p>USA</p>
  13. </div>
  14. <div class="home__rooms">
  15. <svg>
  16. <use xlink:href="img/sprite.svg#icon-profile-male"></use>
  17. </svg>
  18. <p>5 rooms</p>
  19. </div>
  20. <div class="home__area">
  21. <svg>
  22. <use xlink:href="img/sprite.svg#icon-expand"></use>
  23. </svg>
  24. <p>325 m<sup>2</sup></p>
  25. </div>
  26. <div class="home__price">
  27. <svg>
  28. <use xlink:href="img/sprite.svg#icon-key"></use>
  29. </svg>
  30. <p>$1,200,000</p>
  31. </div>
  32. <button class="btn home__btn">Contact realtor</button>
  33. </div>
  34. </section>
  1. .homes {
  2. grid-column: center-start / center-end;
  3. margin: 15rem 0;
  4. display: grid;
  5. grid-template-columns: repeat(auto-fit, minmax(25rem, 1fr));
  6. grid-gap: 7rem;
  7. }
  8. .home {
  9. background-color: $color-grey-light-1;
  10. &__img {
  11. width: 100%;
  12. }
  13. &__like {
  14. }
  15. &__name {
  16. }
  17. &__location,
  18. &__rooms,
  19. &__area,
  20. &__price {
  21. svg {
  22. fill: $color-primary;
  23. height: 2rem;
  24. width: 2rem;
  25. }
  26. p {
  27. }
  28. }
  29. &__btn {
  30. }
  31. }

⬆ back to top

113. Building the Homes Section - Part 2

How to build a rather complex component using a mix of CSS Grid properties, overlapping and flexbox?

  1. .home {
  2. background-color: $color-grey-light-1;
  3. display: grid;
  4. grid-template-columns: repeat(2, 1fr);
  5. grid-row-gap: 3.5rem;
  6. &__img {
  7. width: 100%;
  8. grid-row: 1 / 2;
  9. grid-column: 1 / -1;
  10. z-index: 1;
  11. }
  12. &__like {
  13. grid-row: 1 / 2;
  14. grid-column: 2 / 3;
  15. fill: $color-primary;
  16. height: 2.5rem;
  17. width: 2.5rem;
  18. z-index: 2;
  19. justify-self: end;
  20. margin: 1rem;
  21. }
  22. &__name {
  23. grid-row: 1 / 2;
  24. grid-column: 1 / -1;
  25. justify-self: center;
  26. align-self: end;
  27. z-index: 3;
  28. width: 80%;
  29. font-family: $font-display;
  30. font-size: 1.6rem;
  31. text-align: center;
  32. padding: 1.25rem;
  33. background-color: $color-secondary;
  34. color: #fff;
  35. font-weight: 400;
  36. transform: translateY(50%);
  37. }
  38. &__location,
  39. &__rooms {
  40. margin-top: 2.5rem;
  41. }
  42. &__location,
  43. &__rooms,
  44. &__area,
  45. &__price {
  46. font-size: 1.5rem;
  47. margin-left: 2rem;
  48. display: flex;
  49. align-items: center;
  50. svg {
  51. fill: $color-primary;
  52. height: 2rem;
  53. width: 2rem;
  54. margin-right: 1rem;
  55. }
  56. }
  57. &__btn {
  58. grid-column: 1 / -1;
  59. }
  60. }

⬆ back to top

  1. <section class="gallery">
  2. <figure class="gallery__item gallery__item--1"><img src="img/gal-1.jpeg" alt="Gallery image 1" class="gallery__img"></figure>
  3. <figure class="gallery__item gallery__item--2"><img src="img/gal-2.jpeg" alt="Gallery image 2" class="gallery__img"></figure>
  4. <figure class="gallery__item gallery__item--3"><img src="img/gal-3.jpeg" alt="Gallery image 3" class="gallery__img"></figure>
  5. <figure class="gallery__item gallery__item--4"><img src="img/gal-4.jpeg" alt="Gallery image 4" class="gallery__img"></figure>
  6. <figure class="gallery__item gallery__item--5"><img src="img/gal-5.jpeg" alt="Gallery image 5" class="gallery__img"></figure>
  7. <figure class="gallery__item gallery__item--6"><img src="img/gal-6.jpeg" alt="Gallery image 6" class="gallery__img"></figure>
  8. <figure class="gallery__item gallery__item--7"><img src="img/gal-7.jpeg" alt="Gallery image 7" class="gallery__img"></figure>
  9. <figure class="gallery__item gallery__item--8"><img src="img/gal-8.jpeg" alt="Gallery image 8" class="gallery__img"></figure>
  10. <figure class="gallery__item gallery__item--9"><img src="img/gal-9.jpeg" alt="Gallery image 9" class="gallery__img"></figure>
  11. <figure class="gallery__item gallery__item--10"><img src="img/gal-10.jpeg" alt="Gallery image 10" class="gallery__img"></figure>
  12. <figure class="gallery__item gallery__item--11"><img src="img/gal-11.jpeg" alt="Gallery image 11" class="gallery__img"></figure>
  13. <figure class="gallery__item gallery__item--12"><img src="img/gal-12.jpeg" alt="Gallery image 12" class="gallery__img"></figure>
  14. <figure class="gallery__item gallery__item--13"><img src="img/gal-13.jpeg" alt="Gallery image 13" class="gallery__img"></figure>
  15. <figure class="gallery__item gallery__item--14"><img src="img/gal-14.jpeg" alt="Gallery image 14" class="gallery__img"></figure>
  16. </section>
  1. .gallery {
  2. background-color: $color-grey-light-1;
  3. grid-column: full-start / full-end;
  4. display: grid;
  5. grid-template-columns: repeat(8, 1fr);
  6. grid-template-rows: repeat(7, 5vw);
  7. grid-gap: 1.5rem;
  8. padding: 1.5rem;
  9. &__item {
  10. &--1 {
  11. grid-row: 1 / span 2;
  12. grid-column: 1 / span 2;
  13. }
  14. }
  15. &__img {
  16. width: 100%;
  17. height: 100%;
  18. object-fit: cover;
  19. display: block;
  20. }
  21. }

⬆ back to top

Using object-fit together with images for grid items

  1. &__img {
  2. width: 100%;
  3. height: 100%;
  4. object-fit: cover;
  5. display: block;
  6. }

⬆ back to top

  1. .gallery {
  2. &__item {
  3. &--1 {
  4. grid-row: 1 / span 2;
  5. grid-column: 1 / span 2;
  6. }
  7. &--2 {
  8. grid-row: 1 / span 3;
  9. grid-column: 3 / span 3;
  10. }
  11. &--3 {
  12. grid-row: 1 / span 2;
  13. grid-column: 6 / 7;
  14. }
  15. &--4 {
  16. grid-row: 1 / span 2;
  17. grid-column: 7 / -1;
  18. }
  19. &--5 {
  20. grid-row: 3 / span 3;
  21. grid-column: 1 / span 2;
  22. }
  23. &--6 {
  24. grid-row: 4 / span 2;
  25. grid-column: 3 / span 2;
  26. }
  27. &--7 {
  28. grid-row: 4 / 5;
  29. grid-column: 5 / 6;
  30. }
  31. &--8 {
  32. grid-row: 3 / span 2;
  33. grid-column: 6 / span 2;
  34. }
  35. &--9 {
  36. grid-row: 3 / span 3;
  37. grid-column: 8 / -1;
  38. }
  39. &--10 {
  40. grid-row: 6 / span 2;
  41. grid-column: 1 / 2;
  42. }
  43. &--11 {
  44. grid-row: 6 / span 2;
  45. grid-column: 2 / span 2;
  46. }
  47. &--12 {
  48. grid-row: 6 / span 2;
  49. grid-column: 4 / 5;
  50. }
  51. &--13 {
  52. grid-row: 5 / span 3;
  53. grid-column: 5 / span 3;
  54. }
  55. &--14 {
  56. grid-row: 6 / span 2;
  57. grid-column: 8 / -1;
  58. }
  59. }
  60. }

⬆ back to top

  1. <footer class="footer">
  2. <ul class="nav">
  3. <li class="nav__item"><a href="#" class="nav__link">Find your dream home</a></li>
  4. <li class="nav__item"><a href="#" class="nav__link">Request proposal</a></li>
  5. <li class="nav__item"><a href="#" class="nav__link">Download home planner</a></li>
  6. <li class="nav__item"><a href="#" class="nav__link">Contact us</a></li>
  7. <li class="nav__item"><a href="#" class="nav__link">Submit your property</a></li>
  8. <li class="nav__item"><a href="#" class="nav__link">Come work with us!</a></li>
  9. </ul>
  10. <p class="copyright">
  11. © Copyright 2017 by Jonas Schmedtmann. Feel free to use this project for your own purposes. This does NOT apply if you plan to produce your own course or tutorials based on this project.
  12. </p>
  13. </footer>
  1. .footer {
  2. background-color: $color-secondary;
  3. grid-column: full-start / full-end;
  4. padding: 8rem;
  5. }
  6. .nav {
  7. list-style: none;
  8. display: grid;
  9. grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  10. grid-gap: 2rem;
  11. align-items: center;
  12. &__link:link,
  13. &__link:visited {
  14. font-size: 1.4rem;
  15. color: #fff;
  16. text-decoration: none;
  17. font-family: $font-display;
  18. text-transform: uppercase;
  19. text-align: center;
  20. padding: 1.5rem;
  21. display: block;
  22. transition: all .2s;
  23. }
  24. &__link:hover,
  25. &__link:active {
  26. background-color: rgba(#fff, .05);
  27. transform: translateY(-3px);
  28. }
  29. }
  30. .copyright {
  31. font-size: 1.4rem;
  32. color: $color-grey-light-2;
  33. margin-top: 6rem;
  34. margin-right: auto;
  35. margin-left: auto;
  36. text-align: center;
  37. width: 70%;
  38. }

⬆ back to top

117. Building the Sidebar

  1. <div class="sidebar">
  2. <button class="nav-btn"></button>
  3. </div>
  1. .sidebar {
  2. background-color: $color-primary;
  3. grid-column: sidebar-start / sidebar-end;
  4. grid-row: 1 / -1;
  5. display: flex;
  6. justify-content: center;
  7. }
  8. .nav-btn {
  9. border: none;
  10. border-radius: 0;
  11. background-color: #fff;
  12. height: 2px;
  13. width: 4.5rem;
  14. margin-top: 4rem;
  15. &::before,
  16. &::after {
  17. background-color: #fff;
  18. height: 2px;
  19. width: 4.5rem;
  20. content: "";
  21. display: block;
  22. }
  23. &::before { transform: translateY(-1.5rem); }
  24. &::after { transform: translateY(1.3rem); }
  25. }

⬆ back to top

118. Building the Header - Part 1

  1. <header class="header">
  2. <img src="img/logo.png" alt="Nexter logo" class="header__logo">
  3. <h3 class="heading-3">Your own home:</h3>
  4. <h1 class="heading-1">The ultimate personal freedom</h1>
  5. <button class="btn header__btn">View our properties</button>
  6. <div class="header__seenon-text">Seen on</div>
  7. <div class="header__seenon-logos">
  8. <img src="img/logo-bbc.png" alt="Seen on logo 1">
  9. <img src="img/logo-forbes.png" alt="Seen on logo 2">
  10. <img src="img/logo-techcrunch.png" alt="Seen on logo 3">
  11. <img src="img/logo-bi.png" alt="Seen on logo 4">
  12. </div>
  13. </header>
  1. .heading-1 {
  2. @extend %heading;
  3. font-size: 4.5rem;
  4. color: $color-grey-light-1;
  5. line-height: 1;
  6. }
  7. .header {
  8. background-color: $color-grey-dark-1;
  9. grid-column: full-start / col-end 6;
  10. background-image: linear-gradient(rgba($color-secondary, .93), rgba($color-secondary, .93)), url(../img/hero.jpeg);
  11. background-size: cover;
  12. background-position: center;
  13. padding: 8rem;
  14. padding-top: 4rem;
  15. display: grid;
  16. grid-template-rows: 1fr min-content minmax(6rem, min-content) 1fr;
  17. grid-template-columns: minmax(min-content, max-content);
  18. grid-row-gap: 1.5rem;
  19. justify-content: center;
  20. &__logo {
  21. height: 3rem;
  22. justify-self: center;
  23. }
  24. &__btn {
  25. align-self: start;
  26. justify-self: start;
  27. }
  28. &__seenon-text {
  29. }
  30. &__seenon-logos {
  31. img {
  32. height: 2.5rem;
  33. }
  34. }
  35. }

⬆ back to top

119. Building the Header - Part 2

  1. .header {
  2. &__seenon-text {
  3. display: grid;
  4. grid-template-columns: 1fr max-content 1fr;
  5. grid-column-gap: 1.5rem;
  6. align-items: center;
  7. font-size: 1.6rem;
  8. color: $color-grey-light-2;
  9. &::before,
  10. &::after {
  11. content: "";
  12. height: 1px;
  13. display: block;
  14. background-color: currentColor;
  15. }
  16. }
  17. &__seenon-logos {
  18. display: grid;
  19. grid-template-columns: repeat(4, 1fr);
  20. grid-column-gap: 3rem;
  21. justify-items: center;
  22. align-items: center;
  23. img {
  24. height: 2.5rem;
  25. max-width: 100%;
  26. filter: brightness(70%);
  27. }
  28. }
  29. }

⬆ back to top

How to manage vertical spacing in a responsive layout using CSS Grid techniques?

  1. .header {
  2. display: grid;
  3. grid-template-rows: 1fr min-content minmax(6rem, min-content) 1fr;
  4. grid-row-gap: 1.5rem;
  5. }

⬆ back to top

How to use ::before and ::after as grid items?

  1. .header {
  2. &__seenon-text {
  3. display: grid;
  4. grid-template-columns: 1fr max-content 1fr;
  5. grid-column-gap: 1.5rem;
  6. align-items: center;
  7. font-size: 1.6rem;
  8. color: $color-grey-light-2;
  9. &::before,
  10. &::after {
  11. content: "";
  12. height: 1px;
  13. display: block;
  14. background-color: currentColor;
  15. }
  16. }
  17. }

⬆ back to top

120. Building the Realtors Section

  1. <div class="realtors">
  2. <h3 class="heading-3">Top 3 Realtors</h3>
  3. <div class="realtors__list">
  4. <img src="img/realtor-1.jpeg" alt="Realtor 1" class="realtors__img">
  5. <div class="realtors__details">
  6. <h4 class="heading-4 heading-4--light">Erik Feinman</h4>
  7. <p class="realtors__sold">245 houses sold</p>
  8. </div>
  9. <img src="img/realtor-2.jpeg" alt="Realtor 2" class="realtors__img">
  10. <div class="realtors__details">
  11. <h4 class="heading-4 heading-4--light">Kim Brown</h4>
  12. <p class="realtors__sold">212 houses sold</p>
  13. </div>
  14. <img src="img/realtor-3.jpeg" alt="Realtor 3" class="realtors__img">
  15. <div class="realtors__details">
  16. <h4 class="heading-4 heading-4--light">Toby Ramsey</h4>
  17. <p class="realtors__sold">198 houses sold</p>
  18. </div>
  19. </div>
  20. </div>
  1. .realtors {
  2. background-color: $color-secondary;
  3. grid-column: col-start 7 / full-end;
  4. padding: 3rem;
  5. display: grid;
  6. align-content: center;
  7. justify-content: center;
  8. justify-items: center;
  9. grid-row-gap: 2rem;
  10. &__list {
  11. display: grid;
  12. grid-template-columns: min-content max-content;
  13. grid-column-gap: 2rem;
  14. grid-row-gap: 5vh;
  15. align-items: center;
  16. }
  17. &__img {
  18. width: 7rem;
  19. border-radius: 50%;
  20. display: block;
  21. }
  22. &__sold {
  23. text-transform: uppercase;
  24. color: $color-grey-light-2;
  25. margin-top: -3px;
  26. }
  27. }

⬆ back to top

121. Writing Media Queries - Part 1

122. Writing Media Queries - Part 2

  1. // RESPONSIVE BREAKPOINTS
  2. $bp-largest: 75em; // 1200px
  3. $bp-large: 62.5em; // 1000px
  4. $bp-medium: 50em; // 800px;
  5. $bp-small: 37.5em; // 600px;
  6. html {
  7. font-size: 62.5%; // 10px/16px = 62.5% -> 1rem = 10px
  8. @media only screen and (max-width: $bp-largest) {
  9. font-size: 50%;
  10. }
  11. }
  12. .container {
  13. display: grid;
  14. grid-template-rows: 80vh min-content 40vw repeat(3, min-content);
  15. // 1140 / 0 = 140px = 14rem
  16. // center content on the page up to 1140px
  17. grid-template-columns: [sidebar-start] 8rem [sidebar-end full-start] minmax(6rem, 1fr) [center-start] repeat(8, [col-start] minmax(min-content, 14rem) [col-end]) [center-end] minmax(6rem, 1fr) [full-end];
  18. @media only screen and (max-width: $bp-large) {
  19. grid-template-rows: 6rem 80vh min-content 40vw repeat(3, min-content);
  20. grid-template-columns: [full-start] minmax(6rem, 1fr) [center-start] repeat(8, [col-start] minmax(min-content, 14rem) [col-end]) [center-end] minmax(6rem, 1fr) [full-end];
  21. }
  22. @media only screen and (max-width: $bp-medium) {
  23. grid-template-rows: 6rem calc(100vh - 6rem);
  24. }
  25. }
  26. .sidebar {
  27. grid-column: sidebar-start / sidebar-end;
  28. grid-row: 1 / -1;
  29. display: flex;
  30. justify-content: center;
  31. @media only screen and (max-width: $bp-large) {
  32. grid-column: 1 / -1;
  33. grid-row: 1 / 2;
  34. justify-content: flex-end;
  35. align-items: center;
  36. }
  37. }
  38. .nav-btn {
  39. margin-top: 4rem;
  40. &::before { transform: translateY(-1.5rem); }
  41. &::after { transform: translateY(1.3rem); }
  42. @media only screen and (max-width: $bp-large) {
  43. margin-top: 0;
  44. margin-right: 3rem;
  45. &::before { transform: translateY(-1.2rem); }
  46. &::after { transform: translateY(1rem); }
  47. }
  48. }
  49. .header {
  50. grid-column: full-start / col-end 6;
  51. padding: 8rem;
  52. @media only screen and (max-width: $bp-medium) {
  53. grid-column: 1 / -1;
  54. }
  55. @media only screen and (max-width: $bp-small) {
  56. padding: 5rem;
  57. }
  58. }
  59. .realtors {
  60. grid-column: col-start 7 / full-end;
  61. @media only screen and (max-width: $bp-medium) {
  62. grid-column: 1 / -1;
  63. }
  64. &__list {
  65. grid-template-columns: min-content max-content;
  66. @media only screen and (max-width: $bp-medium) {
  67. grid-template-columns: repeat(3, min-content max-content);
  68. }
  69. @media only screen and (max-width: $bp-small) {
  70. grid-template-columns: min-content max-content;
  71. }
  72. }
  73. }
  74. .story {
  75. &__pictures {
  76. grid-column: full-start / col-end 4;
  77. display: grid;
  78. grid-template-rows: repeat(6, 1fr);
  79. grid-template-columns: repeat(6, 1fr);
  80. align-items: center;
  81. @media only screen and (max-width: $bp-medium) {
  82. grid-column: 1 / -1;
  83. padding: 6rem;
  84. }
  85. }
  86. &__img--1 {
  87. grid-row: 2 / 6;
  88. grid-column: 2 / 6;
  89. @media only screen and (max-width: $bp-medium) {
  90. grid-column: 1 / 5;
  91. grid-row: 1 / -1;
  92. }
  93. }
  94. &__img--2 {
  95. width: 115%;
  96. grid-row: 4 / 6;
  97. grid-column: 4 / 7;
  98. @media only screen and (max-width: $bp-medium) {
  99. grid-row: 1 / -1;
  100. width: 100%;
  101. }
  102. }
  103. &__content {
  104. grid-column: col-start 5 / full-end;
  105. @media only screen and (max-width: $bp-medium) {
  106. grid-column: 1 / -1;
  107. grid-row: 5 / 6;
  108. }
  109. }
  110. }

⬆ back to top

123. Browser Support for CSS Grid

  • caniuse
  • Fallback for users with old browser
  1. .features {
  2. @supports(display: grid) {
  3. display: grid;
  4. grid-template-columns: repeat(auto-fit, minmax(25rem, 1fr));
  5. grid-gap: 6rem;
  6. align-items: start;
  7. }
  8. }
  9. .feature {
  10. float: left;
  11. width: 33.3333%;
  12. margin-bottom: 6rem;
  13. @supports(display: grid) {
  14. width: auto;
  15. margin-bottom: 0;
  16. }
  17. }

⬆ back to top

124. Wrapping up the Nexter Project: Final Considerations

⬆ back to top

Section 10: That’s It, Everyone!

⬆ back to top