Advanced CSS and Sass: Flexbox, Grid, Animations and More!
<body>
<header class="header">
</header>
</body>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: "Lato", sans-serif;
font-weight: 400;
font-size: 16px;
line-height: 1.7;
color: #777;
padding: 30px;
}
.header {
clip-path: polygon(0 0, 100% 0, 100% 75vh, 0 100%);
}
<body>
<header class="header">
<div class="logo-box">
<img src="img/logo-white.png" alt="Logo" class="logo">
</div>
<div class="text-box">
<h1 class="heading-primary">
<span class="heading-primary-main">Outdoors</span>
<span class="heading-primary-sub">is where life happens</span>
</h1>
</div>
</header>
</body>
.header {
position: relative;
}
.logo-box {
position: absolute;
top: 40px;
left: 40px;
}
.logo {
height: 35px;
}
/* The easiest way to center anything with the transform, top and left properties. */
.text-box {
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
}
.heading-primary {
color: #fff;
text-transform: uppercase;
}
.heading-primary-main {
display: block;
font-size: 60px;
font-weight: 400;
letter-spacing: 35px;
}
.heading-primary-sub {
display: block;
font-size: 20px;
font-weight: 700;
letter-spacing: 17.4px;
}
.heading-primary {
backface-visibility: hidden;
}
.heading-primary-main {
animation-name: moveInLeft;
animation-duration: 1s;
animation-timing-function: ease-out;
}
.heading-primary-sub {
animation: moveInRight 1s ease-out;
}
@keyframes moveInLeft {
0% {
opacity: 0;
transform: translateX(-100px);
}
80% {
transform: translateX(10px);
}
100% {
opacity: 1;
transform: translate(0);
}
}
@keyframes moveInRight {
0% {
opacity: 0;
transform: translateX(100px);
}
80% {
transform: translateX(-10px);
}
100% {
opacity: 1;
transform: translate(0);
}
}
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
<a href="" class="btn btn-white">Discover our tours</a>
.btn:link,
.btn:visited {
text-transform: uppercase;
text-decoration: none;
padding: 15px 40px;
display: inline-block;
border-radius: 100px;
transition: all .2s;
}
.btn:hover {
transform: translateY(-3px);
box-shadow: 0 10px 20px rgba(0, 0, 0, .2);
}
.btn:active {
transform: translateY(-1px);
box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
}
.btn-white {
background-color: #fff;
color: #777;
}
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
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.
@keyframes moveInBottom {
0% {
opacity: 0;
transform: translateY(30px);
}
100% {
opacity: 1;
transform: translate(0);
}
}
.btn:link,
.btn:visited {
position: relative;
}
.btn::after {
content: "";
display: inline-block;
height: 100%;
width: 100%;
border-radius: 100px;
position: absolute;
top: 0;
left: 0;
z-index: -1;
transition: all .4s;
}
.btn-white::after {
background-color: #fff;
}
.btn:hover::after {
transform: scaleX(1.4) scaleY(1.6);
opacity: 0;
}
.btn-animated {
animation: moveInBottom .5s ease-out .75s;
animation-fill-mode: backwards;
}
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 |
Maintainable and scalable code
<nav id="nav">
<div class="pull-right">
<a class="button button-danger" href="link.html">Don't click here!</a>
</div>
</nav>
body {
padding: 50px;
}
.button {
font-size: 20px;
color: white;
background-color: blue e
}
a {
background-color: purple;
}
/* (Inline, IDs, Classes, Elements) */
/* (0, 1, 2, 2) */
#nav div.pull-right a.button {
background-color: orangered;
}
/* (0, 1, 3, 2) */
#nav div.pull-right a.button:hover {
background-color: green;
}
/* (0, 1, 2, 1) */
#nav a.button:hover {
background-color: yellow;
}
Inheritance in CSS
html {
font-size: 62.5%;
}
body {
font-family: "Lato", sans-serif;
font-weight: 400;
/* font-size: 16px; */
line-height: 1.7;
color: #777;
padding: 3rem;
}
box-sizing: inherit;
box-sizing: border-box;
from parent element body
*,
*::after,
*::before {
margin: 0;
padding: 0;
box-sizing: inherit;
}
body {
box-sizing: border-box;
}
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.
The box model - Heights and Widths (default)
The box model - Heights and Widths (box-sizing: border-box)
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 |
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 |
The Think - Build - Architect Mindset
Responsive design | Maintainable and scalable code | Web performance |
---|---|---|
Clean | ||
Modular | ||
Reusable | ||
Ready for growth |
Think -> Build -> Architect
Component-driven design
The 7-1 pattern
The 7 Folders
<header class="header">
<div class="header__logo-box">
<img src="img/logo-white.png" alt="Logo" class="header__logo">
</div>
<div class="header__text-box">
<h1 class="heading-primary">
<span class="heading-primary--main">Outdoors</span>
<span class="heading-primary--sub">is where life happens</span>
</h1>
<a href="" class="btn btn--white btn--animated">Discover our tours</a>
</div>
</header>
.header {
height: 95vh;
background-image: linear-gradient(to right bottom, rgba(126, 213, 111, 0.8), rgba(40, 180, 133, 0.8)), url(../img/hero.jpg);
background-size: cover;
background-position: top;
position: relative;
clip-path: polygon(0 0, 100% 0, 100% 75vh, 0 100%);
}
.header__logo-box {
position: absolute;
top: 4rem;
left: 4rem;
}
.header__logo {
height: 3.5rem;
}
.header__text-box {
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
}
.heading-primary {
color: #fff;
text-transform: uppercase;
backface-visibility: hidden;
margin-bottom: 6rem;
}
.heading-primary--main {
display: block;
font-size: 6rem;
font-weight: 400;
letter-spacing: 3.5rem;
animation-name: moveInLeft;
animation-duration: 1s;
animation-timing-function: ease-out;
/* animation-delay: 3s; */
}
.heading-primary--sub {
display: block;
font-size: 2rem;
font-weight: 700;
letter-spacing: 1.75rem;
animation: moveInRight 1s ease-out;
}
.btn:link,
.btn:visited {
text-transform: uppercase;
text-decoration: none;
padding: 1.5rem 4rem;
display: inline-block;
border-radius: 10rem;
transition: all .2s;
position: relative;
font-size: 1.6rem;
}
.btn:hover {
transform: translateY(-.3rem);
box-shadow: 0 1rem 2rem rgba(0, 0, 0, .2);
}
.btn:active {
transform: translateY(-.1rem);
box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .2);
}
.btn--white {
background-color: #fff;
color: #777;
}
.btn--white::after {
background-color: #fff;
}
.btn--animated {
animation: moveInBottom .5s ease-out .75s;
animation-fill-mode: backwards;
}
Sass is a CSS preprocessor, an extension of CSS that adds power and elegance to the basic language.
Main SASS features
<nav>
<ul class="navigation">
<li><a href="#">About us</a></li>
<li><a href="#">Pricing</a></li>
<li><a href="#">Contact</a></li>
</ul>
<div class="buttons">
<a class="btn-main" href="#">Sign up</a>
<a class="btn-hot" href="#">Get a quote</a>
</div>
</nav>
* {
margin: 0;
padding: 0;
}
// SaSS variables
$color-primary: #f9ed69; //yellow color
$color-secondary: #f08a5d; //orange color
$color-tertiary: #b83b5e; //pink color
$color-text-dark: #333; //dark grey
$color-text-light: #eee; //light grey
$width-button: 150px;
nav {
margin: 30px;
background-color: $color-primary;
// Fix for displaying no background when using floats
&:after {
content: "";
clear: both;
display: table;
}
}
.navigation {
list-style: none;
float: left;
// Nested selector
li {
display: inline-block;
margin-left: 30px;
// No limit on how many nested selectors you have
// &: === .nagivation li
&:first-child {
margin: 0;
}
a:link,
a:active {
text-decoration: none;
text-transform: uppercase;
color: $color-text-dark;
}
}
}
.buttons {
float: right;
}
.btn-main:link,
.btn-hot:link {
padding: 10px;
display: inline-block;
text-align: center;
border-radius: 100px;
text-decoration: none;
text-transform: uppercase;
width: $width-button;
color: $color-text-light;
}
.btn-main {
&:link {
background-color: $color-secondary;
}
&:hover {
background-color: darken($color-secondary, 15%);
}
}
.btn-hot {
&:link {
background-color: $color-tertiary;
}
&:hover {
background-color: lighten($color-tertiary, 15%);
}
}
$color-text-dark: #333; //dark grey
$color-text-light: #eee; //light grey
@mixin clearfix {
&::after{
content:"";
clear:both;
display:table;
}
}
@mixin style-link-text($color) {
text-decoration: none;
text-transform: uppercase;
color: $color;
}
@function divide($a, $b) {
@return $a / $b;
}
nav {
margin: divide(60, 2) * 1px; // 30px
background-color: $color-primary;
@include clearfix
}
.navigation {
list-style: none;
float: left;
li {
a:link,
a:active {
@include style-link-text($color-text-dark)
}
}
}
// both .btn-main:link, .btn-hot:link will share styles
%btn-placeholder {
padding: 10px;
display: inline-block;
text-align: center;
border-radius: 100px;
width: $width-button;
@include style-link-text($color-text-light)
}
.btn-main {
&:link {
@extend %btn-placeholder;
background-color: $color-secondary;
}
}
.btn-hot {
&:link {
@extend %btn-placeholder;
background-color: $color-tertiary;
}
}
npm run compile:sass
npm i live-server -g
live-server
$color-primary: #55c57a;
$color-primary-light: #7ed56f;
$color-primary-dark: #28b485;
$color-grey-dark: #777;
$color-white: #fff;
$color-black: #000;
.header {
height: 95vh;
background-image: linear-gradient(to right bottom, rgba($color-primary-light, 0.8), rgba($color-primary-dark, 0.8)), url(../img/hero.jpg);
background-size: cover;
background-position: top;
position: relative;
clip-path: polygon(0 0, 100% 0, 100% 75vh, 0 100%);
&__logo-box {
position: absolute;
top: 4rem;
left: 4rem;
}
&__logo {
height: 3.5rem;
}
&__text-box {
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
}
}
Basic Responsive Design Principles
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.
Images behave differently than text content, and so we need to ensure that they also adapt nicely to the current viewport.
To change styles on certain viewport widths (breakpoints), allowing us to create different version of our website for different widths.
<section class="grid-test">
<div class="row">
<div class="col-1-of-2">Col 1 of 2</div>
<div class="col-1-of-2">Col 1 of 2</div>
</div>
<div class="row">
<div class="col-1-of-3">Col 1 of 3</div>
<div class="col-1-of-3">Col 1 of 3</div>
<div class="col-1-of-3">Col 1 of 3</div>
</div>
<div class="row">
<div class="col-1-of-3">Col 1 of 3</div>
<div class="col-2-of-3">Col 2 of 3</div>
</div>
<div class="row">
<div class="col-1-of-4">Col 1 of 4</div>
<div class="col-1-of-4">Col 1 of 4</div>
<div class="col-1-of-4">Col 1 of 4</div>
<div class="col-1-of-4">Col 1 of 4</div>
</div>
<div class="row">
<div class="col-1-of-4">Col 1 of 4</div>
<div class="col-1-of-4">Col 1 of 4</div>
<div class="col-2-of-4">Col 2 of 4</div>
</div>
<div class="row">
<div class="col-1-of-4">Col 1 of 4</div>
<div class="col-3-of-4">Col 3 of 4</div>
</div>
</section>
.row {
max-width: $grid-width;
background-color: #eee;
// center block element
margin: 0 auto;
// select everything except last child
&:not(:last-child) {
margin-bottom: $gutter-vertical;
}
@include clearfix;
// select all class selector start with "col-"
[class^="col-"] {
background-color: orangered;
float: left;
&:not(:last-child) {
margin-right: $gutter-horizontal;
}
}
.col-1-of-2 {
width: calc((100% - #{$gutter-horizontal}) / 2);
}
.col-1-of-3 {
width: calc((100% - 2 * #{$gutter-horizontal}) / 3);
}
.col-2-of-3 {
width: calc(2 * ((100% - 2 * #{$gutter-horizontal}) / 3) + #{$gutter-horizontal});
}
.col-1-of-4 {
width: calc((100% - 3 * #{$gutter-horizontal}) / 4);
}
.col-2-of-4 {
width: calc(2 * ((100% - 3 * #{$gutter-horizontal}) / 4) + #{$gutter-horizontal});
}
.col-3-of-4 {
width: calc(3 * ((100% - 3 * #{$gutter-horizontal}) / 4) + 2 * #{$gutter-horizontal});
}
}
<section class="section-about">
<div class="u-center-text u-margin-bottom-big">
<h2 class="heading-secondary">
Exciting tours for adventurous people
</h2>
</div>
<div class="row">
<div class="col-1-of-2"></div>
<div class="col-1-of-2"></div>
</div>
</section>
.section-about {
background-color: $color-grey-light-1;
padding: 25rem 0;
margin-top: -20vh;
}
Secondary Heading component
<div class="u-center-text u-margin-bottom-big">
<h2 class="heading-secondary">
Exciting tours for adventurous people
</h2>
</div>
.heading-secondary {
font-size: 3.5rem;
text-transform: uppercase;
font-weight: 700;
display: inline-block;
background-image: linear-gradient(to right, $color-primary-light, $color-primary-dark);
background-clip: text;
-webkit-background-clip: text;
color: transparent;
letter-spacing: .2rem;
transition: all .2s;
&:hover {
transform: skewY(2deg) skewX(15deg) scale(1.1);
text-shadow: .5rem 1rem 2rem rgba($color-black, .2);
}
}
.u-center-text {
// center inline-block child
text-align: center;
}
.u-margin-bottom-small { margin-bottom: 2rem; }
.u-margin-bottom-medium { margin-bottom: 4rem; }
.u-margin-bottom-big { margin-bottom: 8rem; }
.heading-secondary {
display: inline-block;
background-image: linear-gradient(to right, $color-primary-light, $color-primary-dark);
-webkit-background-clip: text;
color: transparent;
}
.heading-secondary {
transition: all .2s;
&:hover {
transform: skewY(2deg) skewX(15deg) scale(1.1);
text-shadow: .5rem 1rem 2rem rgba($color-black, .2);
}
}
<h3 class="heading-tertiary u-margin-bottom-small">You are going to fall in love with nature</h3>
<p class="paragraph">
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?
</p>
<h3 class="heading-tertiary u-margin-bottom-small">Live adventures like you never have before</h3>
<p class="paragraph">
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?
</p>
<a href="#" class="btn-text">
Learn more →
</a>
.heading-tertiary {
font-size: $default-font-size;
font-weight: 700;
text-transform: uppercase;
}
.paragraph {
font-size: $default-font-size;
&:not(:last-child) {
margin-bottom: 3rem;
}
}
.btn-text {
&:link,
&:visited {
font-size: $default-font-size;
color: $color-primary;
display: inline-block;
text-decoration: none;
border-bottom: 1px solid $color-primary;
padding: 3px;
transition: all .2s;
}
&:hover {
background-color: $color-primary;
color: $color-white;
box-shadow: 0 1rem 2rem rgba($color-black, .15);
transform: translateY(-2px);
}
&:active {
box-shadow: 0 .5rem 1rem rgba($color-black, .15);
transform: translateY(0);
}
}
Image Composition component
<div class="composition">
<img src="img/nat-1-large.jpg" alt="Photo 1" class="composition__photo composition__photo--p1">
<img src="img/nat-2-large.jpg" alt="Photo 2" class="composition__photo composition__photo--p2">
<img src="img/nat-3-large.jpg" alt="Photo 3" class="composition__photo composition__photo--p3">
</div>
.composition {
position: relative;
&__photo {
width: 55%;
box-shadow: 0 1.5rem 4rem rgba($color-black, 0.4);
border-radius: 2px;
position: absolute;
z-index: 10;
transition: all .2s;
outline-offset: 2rem;
&--p1 {
left: 0;
top: -2rem;
}
&--p2 {
right: 0;
top: 2rem;
}
&--p3 {
left: 20%;
top: 10rem;
}
&:hover {
outline: 1.5rem solid $color-primary;
transform: scale(1.05) translateY(-.5rem);
box-shadow: 0 2.5rem 4rem rgba($color-black, .5);
z-index: 20;
}
}
// composition:hover composition__photo:not(:hover)
&:hover &__photo:not(:hover) {
transform: scale(0.95);
}
}
.composition {
position: relative;
&__photo {
outline-offset: 2rem;
&:hover {
outline: 1.5rem solid $color-primary;
}
}
}
.composition {
position: relative;
&__photo {
&:hover {
outline: 1.5rem solid $color-primary;
transform: scale(1.05) translateY(-.5rem);
box-shadow: 0 2.5rem 4rem rgba($color-black, .5);
z-index: 20;
}
}
// composition:hover composition__photo:not(:hover)
&:hover &__photo:not(:hover) {
transform: scale(0.95);
}
}
<section class="section-features">
<div class="row">
<div class="col-1-of-4">
<div class="feature-box">
<i class="feature-box__icon icon-basic-world"></i>
<h3 class="heading-tertiary u-margin-bottom-small">Explore the world</h3>
<p class="feature-box__text">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae rerum commodi atque, natus inventore.
</p>
</div>
</div>
<div class="col-1-of-4">
<div class="feature-box">
<i class="feature-box__icon icon-basic-compass"></i>
<h3 class="heading-tertiary u-margin-bottom-small">Meet nature</h3>
<p class="feature-box__text">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae rerum commodi atque, natus inventore.
</p>
</div>
</div>
<div class="col-1-of-4">
<div class="feature-box">
<i class="feature-box__icon icon-basic-map"></i>
<h3 class="heading-tertiary u-margin-bottom-small">Find your way</h3>
<p class="feature-box__text">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae rerum commodi atque, natus inventore.
</p>
</div>
</div>
<div class="col-1-of-4">
<div class="feature-box">
<i class="feature-box__icon icon-basic-heart"></i>
<h3 class="heading-tertiary u-margin-bottom-small">Live a healther life</h3>
<p class="feature-box__text">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae rerum commodi atque, natus inventore.
</p>
</div>
</div>
</div>
</section>
.section-features {
padding: 20rem 0;
background-image: linear-gradient(to right bottom, rgba($color-primary-light, 0.8), rgba($color-primary-dark, 0.8)), url(../img/nat-4.jpg);
background-size: cover;
transform: skewY(-7deg);
margin-top: -10rem;
// select all direct child: row selector in this case
& > * {
transform: skewY(7deg);
}
}
.feature-box {
background-color: rgba($color-white, .8);
font-size: 1.5rem;
padding: 2.5rem;
text-align: center;
border-radius: 3px;
box-shadow: 0 1.5rem 4rem rgba($color-black, .15);
transition: transform .3s;
&__icon {
font-size: 6rem;
margin-bottom: .5rem;
display: inline-block;
background-image: linear-gradient(to right, $color-primary-light, $color-primary-dark);
-webkit-background-clip: text;
color: transparent;
}
&:hover {
transform: translateY(-1.5rem) scale(1.03);
}
&__text {
}
}
.section-features {
transform: skewY(-7deg);
margin-top: -10rem;
}
<section class="section-features">
<div class="row">
</div>
</section>
.section-features {
// select all direct child of section-features
// Example: row selector
& > * {
transform: skewY(7deg);
}
}
<section class="section-tours">
<div class="u-center-text u-margin-bottom-big">
<h2 class="heading-secondary">
Most popular tours
</h2>
</div>
<div class="row">
<div class="col-1-of-3">
<div class="card">
<div class="card__side card__side--front">
<div class="card__picture card__picture--1"> </div>
<h4 class="card__heading">
<span class="card__heading-span card__heading-span--1">
The Sea Explorer
</span>
</h4>
<div class="card__details">
<ul>
<li>3 day tours</li>
<li>Up to 30 people</li>
<li>2 tour guides</li>
<li>Sleep in cozy hotel</li>
<li>Difficulty: easy</li>
</ul>
</div>
</div>
<div class="card__side card__side--back card__side--back--1">
<div class="card__cta">
<div class="card__price-box">
<p class="card__price-only">Only</p>
<p class="card__price-value">$297</p>
</div>
<a href="" class="btn btn--white">Book now</a>
</div>
</div>
</div>
</div>
</div>
<div class="u-center-text u-margin-top-huge">
<a href="#" class="btn btn--green">Discover all tours</a>
</div>
</section>
.section-tours {
background-color: $color-grey-light-1;
padding: 25rem 0 15rem 0;
margin-top: -10rem;
}
.card {
// FUNCTIONALITY
perspective: 150rem;
-moz-perspective: 150rem;
position: relative;
height: 52rem;
&__side {
height: 52rem;
transition: all .8s ease;
position: absolute;
top: 0;
left: 0;
width: 100%;
backface-visibility: hidden;
border-radius: 3px;
overflow: hidden;
box-shadow: 0 1.5rem 4rem rgba($color-black, .15);
&--front {
background-color: $color-white;
}
&--back {
transform: rotateY(180deg);
&--1 {
background-image: linear-gradient(to right bottom, $color-secondary-light, $color-secondary-dark);
}
}
}
&:hover &__side--front {
transform: rotateY(180deg);
}
&:hover &__side--back {
transform: rotateY(0);
}
// FRONT SIDE STYLING
&__picture {
background-size: cover;
height: 23rem;
background-blend-mode: screen;
-webkit-clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%);
clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%);
border-top-left-radius: 3px;
border-top-right-radius: 3px;
&--1 {
background-image: linear-gradient(to right bottom, $color-secondary-light, $color-secondary-dark), url(../img/nat-5.jpg);
}
}
&__heading {
font-size: 2.5rem;
font-weight: 300;
text-transform: uppercase;
text-align: right;
color: $color-white;
position: absolute;
top: 12rem;
right: 2rem;
width: 75%;
}
&__heading-span {
padding: 1rem 1.5rem;
-webkit-box-decoration-break: clone;
box-decoration-break: clone;
&--1 {
background-image: linear-gradient(to right bottom, $color-secondary-light, $color-secondary-dark);
}
}
&__details {
padding: 3rem;
ul {
list-style: none;
width: 80%;
margin: 0 auto;
li {
text-align: center;
font-size: 1.5rem;
padding: 1rem;
&:not(:last-child) {
border-bottom: 1px solid $color-grey-light-2;
}
}
}
}
// BACK SIDE STYLING
&__cta {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 90%;
text-align: center;
}
&__price-box {
text-align: center;
color: $color-white;
margin-bottom: 8rem;
}
&__price-only {
font-size: 1.4rem;
text-transform: uppercase;
}
&__price-value {
font-size: 6rem;
font-weight: 100;
}
}
<div class="card">
<div class="card__side card__side--front">
FRONT
</div>
<div class="card__side card__side--back card__side--back--1">
BACK
</div>
</div>
.card {
perspective: 150rem;
-moz-perspective: 150rem;
position: relative;
height: 52rem;
&__side {
height: 52rem;
transition: all .8s ease;
position: absolute;
top: 0;
left: 0;
width: 100%;
backface-visibility: hidden;
border-radius: 3px;
overflow: hidden;
box-shadow: 0 1.5rem 4rem rgba($color-black, .15);
&--front {
background-color: $color-white;
}
&--back {
transform: rotateY(180deg);
}
}
&:hover &__side--front {
transform: rotateY(180deg);
}
&:hover &__side--back {
transform: rotateY(0);
}
}
<section class="section-tours">
<div class="u-center-text u-margin-bottom-big">
<h2 class="heading-secondary">
Most popular tours
</h2>
</div>
<div class="row">
<div class="col-1-of-3">
<div class="card">
<div class="card__side card__side--front">
<div class="card__picture card__picture--1"> </div>
<h4 class="card__heading">
<span class="card__heading-span card__heading-span--1">
The Sea Explorer
</span>
</h4>
<div class="card__details">
<ul>
<li>3 day tours</li>
<li>Up to 30 people</li>
<li>2 tour guides</li>
<li>Sleep in cozy hotel</li>
<li>Difficulty: easy</li>
</ul>
</div>
</div>
<div class="card__side card__side--back card__side--back--1">
BACK
</div>
</div>
</div>
</div>
<div class="u-center-text u-margin-top-huge">
<a href="#" class="btn btn--green">Discover all tours</a>
</div>
</section>
.card {
&__picture {
background-size: cover;
height: 23rem;
background-blend-mode: screen;
-webkit-clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%);
clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%);
border-top-left-radius: 3px;
border-top-right-radius: 3px;
&--1 {
background-image: linear-gradient(to right bottom, $color-secondary-light, $color-secondary-dark), url(../img/nat-5.jpg);
}
}
&__heading {
font-size: 2.5rem;
font-weight: 300;
text-transform: uppercase;
text-align: right;
color: $color-white;
position: absolute;
top: 12rem;
right: 2rem;
width: 75%;
}
&__heading-span {
padding: 1rem 1.5rem;
-webkit-box-decoration-break: clone;
box-decoration-break: clone;
&--1 {
background-image: linear-gradient(to right bottom, $color-secondary-light, $color-secondary-dark);
}
}
&__details {
padding: 3rem;
ul {
list-style: none;
width: 80%;
margin: 0 auto;
li {
text-align: center;
font-size: 1.5rem;
padding: 1rem;
&:not(:last-child) {
border-bottom: 1px solid $color-grey-light-2;
}
}
}
}
}
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.
.card {
perspective: 150rem;
-moz-perspective: 150rem;
}
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:
<div class="card">
<div class="card__side card__side--front">
</div>
<div class="card__side card__side--back card__side--back--1">
</div>
</div>
.card {
&__side {
backface-visibility: hidden;
&--front {
background-color: $color-white;
}
&--back {
transform: rotateY(180deg);
}
}
&:hover &__side--front {
transform: rotateY(180deg);
}
&:hover &__side--back {
transform: rotateY(0);
}
}
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.
.card {
&__picture {
background-size: cover;
height: 23rem;
background-blend-mode: screen;
&--1 {
background-image: linear-gradient(to right bottom, $color-secondary-light, $color-secondary-dark), url(../img/nat-5.jpg);
}
}
}
The box-decoration-break CSS property specifies how an element’s fragments should be rendered when broken across multiple lines, columns, or pages.
.card {
&__heading-span {
padding: 1rem 1.5rem;
-webkit-box-decoration-break: clone;
box-decoration-break: clone;
&--1 {
background-image: linear-gradient(to right bottom, $color-secondary-light, $color-secondary-dark);
}
}
}
<section class="section-tours">
<div class="u-center-text u-margin-bottom-big">
<h2 class="heading-secondary">
Most popular tours
</h2>
</div>
<div class="row">
<div class="col-1-of-3">
<div class="card">
<div class="card__side card__side--front">
FRONT
</div>
<div class="card__side card__side--back card__side--back--1">
<div class="card__cta">
<div class="card__price-box">
<p class="card__price-only">Only</p>
<p class="card__price-value">$297</p>
</div>
<a href="" class="btn btn--white">Book now</a>
</div>
</div>
</div>
</div>
</div>
</section>
.card {
&__cta {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 90%;
text-align: center;
}
&__price-box {
text-align: center;
color: $color-white;
margin-bottom: 8rem;
}
&__price-only {
font-size: 1.4rem;
text-transform: uppercase;
}
&__price-value {
font-size: 6rem;
font-weight: 100;
}
}
<div class="u-center-text u-margin-top-huge">
<a href="#" class="btn btn--green">Discover all tours</a>
</div>
.btn {
&--green {
background-color: $color-primary;
color: $color-white;
&::after {
background-color: $color-primary;
}
}
}
<section class="section-stories">
<div class="u-center-text u-margin-bottom-big">
<h2 class="heading-secondary">
We make people genuinely happy
</h2>
</div>
<div class="row">
<div class="story">
<figure class="story__shape">
<img src="img/nat-8.jpg" alt="Person on a tour" class="story__img">
</figure>
<div class="story__text">
<h3 class="heading-tertiary u-margin-bottom-small">I had the best week ever with my family</h3>
<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>
</div>
</div>
</div>
</section>
.section-stories {
padding: 15rem 0;
background-color: $color-grey-light-1;
}
.story {
width: 75%;
margin: 0 auto;
box-shadow: 0 3rem 6rem rgba($color-black, .1);
background-color: $color-white;
border-radius: 3px;
padding: 6rem;
padding-left: 9rem;
font-size: $default-font-size;
transform: skewX(-12deg);
&__shape {
width: 15rem;
height: 15rem;
float: left;
-webkit-shape-outside: circle(50% at 50% 50%);
shape-outside: circle(50% at 50% 50%);
-webkit-clip-path: circle(50% at 50% 50%);
clip-path: circle(50% at 50% 50%);
transform: translateX(-3rem) skewX(12deg);
}
&__img {
height: 100%;
}
&__text {
transform: skewX(12deg);
}
}
The shape-outside CSS property defines a shape—which may be non-rectangular—around which adjacent inline content should wrap.
.story {
width: 75%;
margin: 0 auto;
box-shadow: 0 3rem 6rem rgba($color-black, .1);
background-color: $color-white;
border-radius: 3px;
padding: 6rem;
padding-left: 9rem;
font-size: $default-font-size;
transform: skewX(-12deg);
&__shape {
width: 15rem;
height: 15rem;
float: left;
-webkit-shape-outside: circle(50% at 50% 50%);
shape-outside: circle(50% at 50% 50%);
-webkit-clip-path: circle(50% at 50% 50%);
clip-path: circle(50% at 50% 50%);
transform: translateX(-3rem) skewX(12deg);
}
&__img {
height: 100%;
}
}
The HTML <figcaption>
or Figure Caption element represents a caption or legend describing the rest of the contents of its parent <figure>
element.
<div class="story">
<figure class="story__shape">
<img src="img/nat-8.jpg" alt="Person on a tour" class="story__img">
<figcaption class="story__caption">
Mary Smith
</figcaption>
</figure>
</div>
.story {
&__shape {
position: relative;
overflow: hidden;
}
&__img {
height: 100%;
transform: translateX(-4rem) scale(1.4);
backface-visibility: hidden;
transition: all 0.5s;
}
&__caption {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, 20%);
color: $color-white;
text-transform: uppercase;
font-size: 1.7rem;
text-align: center;
opacity: 0;
transition: all 0.5s;
backface-visibility: hidden;
}
&:hover &__caption {
opacity: 1;
transform: translate(-50%, -50%);
}
&:hover &__img {
transform: translateX(-4rem) scale(1);
filter: blur(3px) brightness(80%);
}
}
Coverr: Free Stock Footage | Royalty Free Videos for Download
<div class="bg-video">
<video class="bg-video__content" autoplay muted>
<source src="img/video.mp4" type="video/mp4" ></source>
<source src="img/video.webm" type="video/webm" ></source>
Your browser is not supported!
</video>
</div>
.section-stories {
position: relative;
}
.story {
background-color: rgba($color-white, .6);
}
.bg-video {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index: -1;
opacity: .15;
overflow: hidden;
&__content {
height: 100%;
width: 100%;
object-fit: cover;
}
}
<div class="bg-video">
<video class="bg-video__content" autoplay muted>
<source src="img/video.mp4" type="video/mp4" ></source>
<source src="img/video.webm" type="video/webm" ></source>
Your browser is not supported!
</video>
</div>
.section-stories {
position: relative;
}
.bg-video {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index: -1;
opacity: .15;
overflow: hidden;
&__content {
height: 100%;
width: 100%;
object-fit: cover;
}
}
The object-fit CSS property sets how the content of a replaced element, such as an or
.section-stories {
position: relative;
}
.bg-video {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index: -1;
opacity: .15;
overflow: hidden;
&__content {
height: 100%;
width: 100%;
object-fit: cover;
}
}
<section class="section-book">
<div class="row">
<div class="book">
<div class="book__form">
<form action="" class="form">
<div class="u-margin-bottom-medium">
<h2 class="heading-secondary">
Start booking now
</h2>
</div>
<div class="form__group">
<input type="text" class="form__input" placeholder="Full Name" id="name" required>
<label for="name" class="form__label">Full name</label>
</div>
<div class="form__group">
<input type="email" class="form__input" placeholder="Email address" id="email" required>
<label for="email" class="form__label">Email address</label>
</div>
</form>
</div>
</div>
</div>
</section>
.section-book {
padding: 15rem 0;
background-image: linear-gradient(to right bottom, $color-primary-light, $color-primary-dark);
}
.book {
background-image:
linear-gradient(
105deg,
rgba($color-white, 0.9) 0%,
rgba($color-white, 0.9) 50%,
transparent 50%),
url(../img/nat-10.jpg);
background-size: cover;
border-radius: 3px;
box-shadow: 0 1.5rem 4rem rgba($color-black, 0.2);
height: 50rem;
&__form {
width: 50%;
padding: 6rem;
}
}
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>
.
.book {
background-image:
linear-gradient(
105deg,
rgba($color-white, 0.9) 0%,
rgba($color-white, 0.9) 50%,
transparent 50%),
url(../img/nat-10.jpg);
background-size: cover;
border-radius: 3px;
box-shadow: 0 1.5rem 4rem rgba($color-black, 0.2);
height: 50rem;
}
.form {
&__group:not(:last-child) {
margin-bottom: 2rem;
}
&__input {
font-size: 1.5rem;
font-family: inherit;
color: inherit;
padding: 1.5rem 2rem;
border-radius: 2px;
background-color: rgba($color-white, .5);
border: none;
border-bottom: 3px solid transparent;
width: 90%;
display: block;
transition: all .3s;
&:focus {
outline: none;
box-shadow: 0 1rem 2rem rgba($color-black, .2);
border-bottom: 3px solid $color-primary;
}
&:focus:invalid {
border-bottom: 3px solid $color-secondary-dark;
}
&::-webkit-input-placeholder {
color: $color-grey-dark-2;
}
}
&__label {
font-size: 1.2rem;
font-weight: 700;
margin-left: 2rem;
margin-top: .7rem;
display: block;
transition: all .3s;
}
&__input:placeholder-shown + &__label {
opacity: 0;
visibility: hidden;
transform: translateY(-4rem);
}
}
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.
<form action="" class="form">
<div class="form__group">
<input type="text" class="form__input" placeholder="Full Name" id="name" required>
<label for="name" class="form__label">Full name</label>
</div>
</div>
.form {
// form__input and form__label are adjacent siblings
&__input:placeholder-shown + &__label {
opacity: 0;
visibility: hidden;
transform: translateY(-4rem);
}
}
.form {
&__input {
// customise placeholder text
&::-webkit-input-placeholder {
color: $color-grey-dark-2;
}
}
}
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.
.form {
&__group:not(:last-child) {
margin-bottom: 2rem;
}
&__input {
&:focus {
outline: none;
box-shadow: 0 1rem 2rem rgba($color-black, .2);
border-bottom: 3px solid $color-primary;
}
&:focus:invalid {
border-bottom: 3px solid $color-secondary-dark;
}
&::-webkit-input-placeholder {
color: $color-grey-dark-2;
}
}
// css property is applied when placeholder is shown
// css property is remove when placeholder is gone, user key in value
&__input:placeholder-shown + &__label {
opacity: 0;
visibility: hidden;
transform: translateY(-4rem);
}
}
<div class="form__group u-margin-bottom-medium">
<div class="form__radio-group">
<input type="radio" class="form__radio-input" id="small" name="size">
<label for="small" class="form__radio-label">
<span class="form__radio-button"></span>
Small tour group
</label>
</div>
<div class="form__radio-group">
<input type="radio" class="form__radio-input" id="large" name="size">
<label for="large" class="form__radio-label">
<span class="form__radio-button"></span>
Large tour group
</label>
</div>
</div>
.form {
&__radio-group {
width: 49%;
display: inline-block;
}
&__radio-input {
display: none;
}
&__radio-label {
font-size: $default-font-size;
cursor: pointer;
position: relative;
padding-left: 4.5rem;
}
&__radio-button {
height: 3rem;
width: 3rem;
border: 5px solid $color-primary;
border-radius: 50%;
display: inline-block;
position: absolute;
left: 0;
top: -.4rem;
&::after {
content: "";
display: block;
height: 1.3rem;
width: 1.3rem;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: $color-primary;
opacity: 0;
transition: opacity .2s;
}
}
// form__radio-input:checked
// form__radio-label is sibling of form__radio-input:checked
// form__radio-button::after is child of form__radio-label
&__radio-input:checked ~ &__radio-label &__radio-button::after {
opacity: 1;
}
}
<div class="form__group">
<button class="btn btn--green">Next step →</button>
</div>
.btn {
// add & for the <button> element
&,
&:link,
&:visited {
...
// change for the <button> element
border: none;
cursor: pointer;
}
// add :focus for the <button> element
&:active,
&:focus {
outline: none;
...
}
}
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.
.form {
// form__radio-input:checked
// form__radio-label is sibling of form__radio-input:checked
// form__radio-button::after is child of form__radio-label
&__radio-input:checked ~ &__radio-label &__radio-button::after {
opacity: 1;
}
}
<footer class="footer">
<div class="footer__logo-box">
<img src="img/logo-green-2x.png" alt="Full logo" class="footer__logo">
</div>
<div class="row">
<div class="col-1-of-2">
<div class="footer__navigation">
<ul class="footer__list">
<li class="footer__item"><a href="#" class="footer__link">Company</a></li>
<li class="footer__item"><a href="#" class="footer__link">Contact us</a></li>
<li class="footer__item"><a href="#" class="footer__link">Careers</a></li>
<li class="footer__item"><a href="#" class="footer__link">Privacy policy</a></li>
<li class="footer__item"><a href="#" class="footer__link">Terms</a></li>
</ul>
</div>
</div>
<div class="col-1-of-2">
<p class="footer__copyright">
Built by <a href="#" class="footer__link">Jonas Schmedtmann</a> for his online course <a href="#" class="footer__link">Advanced CSS and Sass</a>.
Copyright © by Jonas Schmedtmann. You are 100% allowed to use this webpage for both personal
and commercial use, but NOT to claim it as your own design. A credit to the original author, Jonas
Schmedtmann, is of course highly appreciated!
</p>
</div>
</div>
</footer>
.footer {
background-color: $color-grey-dark-3;
padding: 10rem 0;
font-size: 1.4rem;
color: $color-grey-light-1;
&__logo-box {
text-align: center;
margin-bottom: 8rem;
}
&__logo {
width: 15rem;
height: auto
}
&__navigation {
border-top: 1px solid $color-grey-dark;
padding-top: 2rem;
display: inline-block;
}
&__list {
list-style: none;
}
&__item {
display: inline-block;
&:not(:last-child) {
margin-right: 1.5rem;
}
}
&__link {
&:link,
&:visited {
color: $color-grey-light-1;
background-color: $color-grey-dark-3;
text-decoration: none;
text-transform: uppercase;
display: inline-block;
transition: all .2s;
}
&:hover,
&:active {
color: $color-primary;
box-shadow: 0 1rem 2rem rgba($color-black, .4);
transform: rotate(5deg) scale(1.3);
}
}
&__copyright {
border-top: 1px solid $color-grey-dark;
padding-top: 2rem;
width: 80%;
float: right;
}
}
Think in components
component | css selector | z-index |
---|---|---|
Navigation button | navigation__button | 2000 |
Navigation list | navigation__nav | 1500 |
Navigation background | navigation__background | 1000 |
<div class="navigation">
<input type="checkbox" class="navigation__checkbox" id="navi-toggle">
<label for="navi-toggle" class="navigation__button">MENU</label>
<div class="navigation__background"> </div>
<nav class="navigation__nav">
<ul class="navigation__list">
<li class="navigation__item"><a href="#" class="navigation__link"><span>01</span>About Natous</a></li>
<li class="navigation__item"><a href="#" class="navigation__link"><span>02</span>Your benefits</a></li>
<li class="navigation__item"><a href="#" class="navigation__link"><span>03</span>Popular tours</a></li>
<li class="navigation__item"><a href="#" class="navigation__link"><span>04</span>Stories</a></li>
<li class="navigation__item"><a href="#" class="navigation__link"><span>05</span>Book now</a></li>
</ul>
</nav>
</div>
.navigation {
&__checkbox {
display: none;
}
&__button {
background-color: $color-white;
height: 7rem;
width: 7rem;
position: fixed;
top: 6rem;
right: 6rem;
border-radius: 50%;
z-index: 2000;
}
&__background {
height: 6rem;
width: 6rem;
border-radius: 50%;
position: fixed;
top: 6.5rem;
right: 6.5rem;
background-image: radial-gradient($color-primary-light, $color-primary-dark);
z-index: 1000;
transform: scale(80);
}
&__nav {
height: 100vh;
width: 100%;
position: fixed;
top: 0;
left: 0;
z-index: 1500;
}
&__list {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
list-style: none;
text-align: center;
}
&__item {
margin: 1rem;
}
&__link {
&:link,
&:visited {
display: inline-block;
font-size: 3rem;
font-weight: 300;
padding: 1rem 2rem;
color: $color-white;
text-decoration: none;
text-transform: uppercase;
background-image: linear-gradient(120deg, transparent 0%, transparent 50%, $color-white 50%);
background-size: 220%;
transition: all .4s;
span {
margin-right: 1.5rem;
display: inline-block;
}
}
&:hover,
&:active {
background-position: 100%;
color: $color-primary;
transform: translateX(1rem);
}
}
}
<div class="navigation">
<input type="checkbox" class="navigation__checkbox" id="navi-toggle">
<label for="navi-toggle" class="navigation__button">MENU</label>
<div class="navigation__background"> </div>
<nav class="navigation__nav">
</nav>
</div>
.navigation {
&__background {
height: 6rem;
width: 6rem;
}
&__nav {
z-index: 1500;
opacity: 0;
width: 0;
}
&__checkbox:checked ~ &__background{
transform: scale(80);
}
&__checkbox:checked ~ &__nav{
opacity: 1;
width: 100%;
}
}
<div class="navigation">
<input type="checkbox" class="navigation__checkbox" id="navi-toggle">
<label for="navi-toggle" class="navigation__button"></label>
<div class="navigation__background"> </div>
<div>
.navigation {
&__checkbox {
display: none;
}
&__button {
background-color: $color-white;
height: 7rem;
width: 7rem;
position: fixed;
top: 6rem;
right: 6rem;
border-radius: 50%;
z-index: 2000;
box-shadow: 0 1rem 3rem rgba($color-black, .1);
text-align: center;
cursor: pointer;
}
&__background {
background-image: radial-gradient($color-primary-light, $color-primary-dark);
z-index: 1000;
transition: transform .8s cubic-bezier(0.83, 0, 0.17, 1);
}
&__checkbox:checked ~ &__background {
transform: scale(80);
}
}
.navigation {
&__background {
transition: transform .8s cubic-bezier(0.83, 0, 0.17, 1);
}
&__nav {
transition: all .8s cubic-bezier(0.68, -0.6, 0.32, 1.6);
}
&__checkbox:checked ~ &__background{
transform: scale(80);
}
&__checkbox:checked ~ &__nav{
opacity: 1;
width: 100%;
}
}
<label for="navi-toggle" class="navigation__button">
<span class="navigation__icon"> </span>
</label>
.navigation {
// ICON
&__icon {
position: relative;
margin-top: 3.5rem;
&,
&::before,
&::after {
width: 3.5rem;
height: 2px;
background-color: $color-grey-dark-3;
display: inline-block;
}
&::before,
&::after {
content: "";
position: absolute;
left: 0;
transition: all .2s;
}
&::before { top: -.8rem; }
&::after { top: .8rem; }
}
&__button:hover &__icon::before {
top: -1rem;
}
&__button:hover &__icon::after {
top: 1rem;
}
&__checkbox:checked + &__button &__icon {
background-color: transparent;
}
&__checkbox:checked + &__button &__icon::before {
top: 0;
transform: rotate(135deg);
}
&__checkbox:checked + &__button &__icon::after {
top: 0;
transform: rotate(-135deg);
}
}
The transform-origin CSS property sets the origin for an element’s transformations.
<div class="box">Sample</div>
.box {
border-style: solid;
border-width: 1px;
display: block;
width: 100px;
height: 100px;
background-color: #0000FF;
transition: width 2s, height 2s, background-color 2s, transform 2s;
}
.box:hover {
background-color: #FFCCCC;
width: 200px;
height: 200px;
transform: rotate(180deg);
}
Thinking in components
<div class="popup">
<div class="popup__content">
<div class="popup__left">
<img src="img/nat-8.jpg" alt="Tour photo" class="popup__img">
<img src="img/nat-9.jpg" alt="Tour photo" class="popup__img">
</div>
<div class="popup__right">
<h2 class="heading-secondary u-margin-bottom-small">Start booking now</h2>
<h3 class="heading-tertiary u-margin-bottom-small">Important – Please read these terms before booking</h3>
<p class="popup__text">
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.
</p>
<a href="#" class="btn btn--green">Book now</a>
</div>
</div>
</div>
.popup {
height: 100vh;
width: 100%;
position: fixed;
top: 0;
left: 0;
background-color: rgba($color-black, .8);
z-index: 9999;
&__content {
@include absCenter;
width: 75%;
background-color: $color-white;
box-shadow: 0 2rem 4rem rgba($color-black, .2);
border-radius: 3px;
display: table;
overflow: hidden;
}
&__left {
width: 33.333333%;
display: table-cell;
}
&__right {
width: 66.666667%;
display: table-cell;
vertical-align: middle;
padding: 3rem 5rem;
}
&__img {
display: block;
width: 100%;
}
&__text {
font-size: 1.4rem;
margin-bottom: 4rem;
column-count: 2;
column-gap: 4rem; // 1em = 14px
column-rule: 1px solid $color-grey-light-2;
hyphens: auto;
}
}
.popup {
&__content {
display: table;
}
&__left {
width: 33.333333%;
display: table-cell;
}
&__right {
width: 66.666667%;
display: table-cell;
vertical-align: middle;
}
}
.popup {
&__text {
column-count: 2;
column-gap: 4rem;
column-rule: 1px solid $color-grey-light-2;
}
}
.popup {
&__text {
hyphens: auto;
}
}
<section class="section-tours" id="section-tours">
<a href="#popup" class="btn btn--white">Book now</a>
</section>
<div class="popup" id="popup">
<div class="popup__content">
<div class="popup__left"></div>
<div class="popup__right">
<a href="#section-tours" class="popup__close">×</a>
</div>
</div>
</div>
.popup {
&__content {
opacity: 0;
transform: translate(-50%, -50%) scale(.25);
transition: all .5s .2s;
}
&:target {
opacity: 1;
visibility: visible;
}
&:target &__content {
opacity: 1;
transform: translate(-50%, -50%) scale(1);
}
&__close {
&:link,
&:visited {
color: $color-grey-dark;
position: absolute;
top: 2.5rem;
right: 2.5rem;
font-size: 3rem;
text-decoration: none;
display: inline-block;
transition: all .2s;
line-height: 1;
}
&:hover {
color: $color-primary;
}
}
}
:target
pseudo-class with id="popup"
-> open popup:target
pseudo-class with id="section-tours"
-> open section-tours -> close popup
<section class="section-tours" id="section-tours">
<a href="#popup" class="btn btn--white">Book now</a>
</section>
<div class="popup" id="popup">
<div class="popup__content">
<div class="popup__left"></div>
<div class="popup__right">
<a href="#section-tours" class="popup__close">×</a>
</div>
</div>
</div>
.popup {
&__content {
opacity: 0;
}
&:target {
opacity: 1;
visibility: visible;
}
}
Order to write media queries
Screen Resolution Stats Worldwide
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
@mixin respond($breakpoint) {
@if $breakpoint == phone {
@media (max-width: 37.5em) { @content };
}
@if $breakpoint == tab-port {
@media (max-width: 56.25em) { @content };
}
@if $breakpoint == tab-land {
@media (max-width: 75em) { @content };
}
@if $breakpoint == big-desktop {
@media (min-width: 112.5em) { @content };
}
}
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 |
html {
font-size: 62.5%;
@include respond(tab-land) {
font-size: 56.25%;
}
@include respond(tab-port) {
font-size: 50%;
}
@include respond(phone) {
font-size: 30%;
}
@include respond(big-desktop) {
font-size: 75%;
}
}
body {
padding: 3rem;
@include respond(tab-port) {
padding: 0;
}
}
.u-margin-bottom-medium {
margin-bottom: 4rem !important;
@include respond(tab-port) { // width < 900px ?
margin-bottom: 3rem !important;
}
}
.u-margin-bottom-big {
margin-bottom: 8rem !important;
@include respond(tab-port) { // width < 900px ?
margin-bottom: 5rem !important;
}
}
.heading-primary {
&--main {
font-size: 6rem;
letter-spacing: 3.5rem;
@include respond(phone) { // width < 600px ?
font-size: 5rem;
letter-spacing: 1rem;
}
}
&--sub {
letter-spacing: 1.75rem;
@include respond(phone) { // width < 600px ?
letter-spacing: .5rem;
}
}
}
.heading-secondary {
font-size: 3.5rem;
@include respond(tab-port) { // width < 900px ?
font-size: 3rem;
}
@include respond(phone) { // width < 600px ?
font-size: 2.5rem;
}
.navigation {
&__button {
top: 6rem;
right: 6rem;
@include respond(tab-port) { // width < 900px ?
top: 4rem;
right: 4rem;
}
@include respond(phone) { // width < 600px ?
top: 3rem;
right: 3rem;
}
}
&__background {
top: 6.5rem;
right: 6.5rem;
@include respond(tab-port) { // width < 900px ?
top: 4.5rem;
right: 4.5rem;
}
@include respond(phone) { // width < 600px ?
top: 3.5rem;
right: 3.5rem;
}
}
}
.header {
-webkit-clip-path: polygon(0 0, 100% 0, 100% 75vh, 0 100%);
clip-path: polygon(0 0, 100% 0, 100% 75vh, 0 100%);
@include respond(phone) { // width < 600px ?
-webkit-clip-path: polygon(0 0, 100% 0, 100% 85vh, 0 100%);
clip-path: polygon(0 0, 100% 0, 100% 85vh, 0 100%);
}
}
.row {
max-width: $grid-width;
@include respond(tab-port) { // width < 900px ?
max-width: 50rem;
padding: 0 3rem;
}
&:not(:last-child) {
margin-bottom: $gutter-vertical;
@include respond(tab-port) { // width < 900px ?
margin-bottom: $gutter-vertical-small;
}
}
[class^="col-"] {
float: left;
&:not(:last-child) {
margin-right: $gutter-horizontal;
@include respond(tab-port) { // width < 900px ?
margin-right: 0;
margin-bottom: $gutter-vertical-small;
}
}
@include respond(tab-port) { // width < 900px ?
width: 100% !important;
}
}
}
.footer {
padding: 10rem 0;
@include respond(tab-port) { // width < 900px ?
padding: 8rem 0;
}
&__logo-box {
margin-bottom: 8rem;
@include respond(tab-port) { // width < 900px ?
margin-bottom: 6rem;
}
}
&__navigation {
border-top: 1px solid $color-grey-dark;
padding-top: 2rem;
display: inline-block;
@include respond(tab-port) { // width < 900px ?
width: 100%;
text-align: center;
}
}
&__copyright {
width: 80%;
float: right;
@include respond(tab-port) { // width < 900px ?
width: 100%;
float: none;
}
}
}
.section-about {
padding: 25rem 0;
@include respond(tab-port) { // width < 900px ?
padding: 20rem 0;
}
}
.section-features {
padding: 20rem 0;
@include respond(tab-port) { // width < 900px ?
padding: 10rem 0;
}
}
.section-tours {
padding: 25rem 0 15rem 0;
@include respond(tab-port) { // width < 900px ?
padding: 20rem 0 10rem 0;
}
}
.section-stories {
padding: 15rem 0;
@include respond(tab-port) { // width < 900px ?
padding: 10rem 0;
}
}
.section-book {
padding: 15rem 0;
@include respond(tab-port) { // width < 900px ?
padding: 10rem 0;
}
}
.composition {
&__photo {
width: 55%;
box-shadow: 0 1.5rem 4rem rgba($color-black, .4);
position: absolute;
@include respond(tab-port) { // width < 900px ?
float: left;
position: relative;
width: 33.333333%;
box-shadow: 0 1.5rem 3rem rgba($color-black, .2);
}
&--p1 {
left: 0;
top: -2rem;
@include respond(tab-port) { // width < 900px ?
top: 0;
transform: scale(1.2);
}
}
&--p2 {
right: 0;
top: 2rem;
@include respond(tab-port) { // width < 900px ?
top: -1rem;
transform: scale(1.3);
z-index: 100;
}
}
&--p3 {
left: 20%;
top: 10rem;
@include respond(tab-port) { // width < 900px ?
top: 1rem;
left: 0;
transform: scale(1.1);
}
}
}
}
.feature-box {
padding: 2.5rem;
@include respond(tab-port) { // width < 900px ?
padding: 2rem;
}
&__icon {
margin-bottom: .5rem;
@include respond(tab-port) { // width < 900px ?
margin-bottom: 0;
}
}
}
.card {
@include respond(tab-port) { // width < 900px ?
// FUNCTIONALITY
height: auto;
border-radius: 3px;
background-color: $color-white;
box-shadow: 0 1.5rem 4rem rgba($color-black, .15);
&__side {
height: auto;
position: relative;
box-shadow: none;
&--back {
transform: rotateY(0);
clip-path: polygon(0 15%, 100% 0, 100% 100%, 0% 100%);
}
}
&:hover &__side--front {
transform: rotateY(0);
}
&__details {
padding: 1rem 3rem;
}
// STYLING
&__cta {
position: relative;
top: 0;
left: 0;
transform: translate(0);
width: 100%;
padding: 7rem 4rem 4rem 4rem;
}
&__price-box {
margin-bottom: 3rem;
}
&__price-value {
font-size: 4rem;
}
}
}
.story {
width: 75%;
padding: 6rem;
padding-left: 9rem;
transform: skewX(-12deg);
@include respond(tab-port) { // width < 900px ?
width: 100%;
padding: 4rem;
padding-left: 7rem;
}
@include respond(phone) { // width < 600px ?
transform: skewX(0);
}
&__shape {
transform: translateX(-3rem) skewX(12deg);
@include respond(phone) { // width < 600px ?
transform: translateX(-3rem) skewX(0);
}
}
&__text {
transform: skewX(12deg);
@include respond(phone) { // width < 600px ?
transform: skewX(0);
}
}
}
.book {
background-image:
linear-gradient(
105deg,
rgba($color-white, 0.9) 0%,
rgba($color-white, 0.9) 50%,
transparent 50%
),
url(../img/nat-10.jpg);
background-size: 100%;
@include respond(tab-land) { // width < 1200px ?
background-image:
linear-gradient(
105deg,
rgba($color-white, 0.9) 0%,
rgba($color-white, 0.9) 65%,
transparent 65%
),
url(../img/nat-10.jpg);
background-size: cover;
}
@include respond(tab-port) { // width < 900px ?
background-image:
linear-gradient(
to right,
rgba($color-white, 0.9) 0%,
rgba($color-white, 0.9) 100%
),
url(../img/nat-10.jpg);
}
&__form {
width: 50%;
padding: 6rem;
@include respond(tab-land) { // width < 1200px ?
width: 65%;
}
@include respond(tab-port) { // width < 900px ?
width: 100%;
}
}
}
.form {
&__input {
width: 90%;
@include respond(tab-port) { // width < 900px ?
width: 100%;
}
}
&__radio-group {
width: 49%;
@include respond(tab-port) { // width < 900px ?
width: 100%;
margin-bottom: 2rem;
}
}
}
Responsive design + Web performance
Use the srcset attribute on the <img>
and <source>
elements, together with density descriptors
<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
console.dir($0)
$0.currentSrc
<picture>
element for art direction
<picture class="footer__logo">
<source srcset="img/logo-green-small-1x.png 1x, img/logo-green-small-2x.png 2x" media="(max-width: 37.5em)">
<img srcset="img/logo-green-1x.png 1x, img/logo-green-2x.png 2x" alt="Full logo" class="footer__logo" src="img/logo-green-2x.png">
</picture>
Allow the browser to decide the best image to download, using the srcset attribute, width descriptors, and the sizes attribute of the <img>
element.
<div class="composition">
<img
srcset="img/nat-1.jpg 300w, img/nat-1-large.jpg 1000w"
sizes="(max-width: 65.25em) 20vw, (max-width: 37.5em) 30vw 300px"
alt="Photo 1"
class="composition__photo composition__photo--p1"
src="img/nat-1-large.jpg"
>
</div>
.composition {
&__photo {
width: 55%;
@include respond(tab-port) { // width < 900px ?
width: 33.333333%;
}
&--p1 {
@include respond(tab-port) { // width < 900px ?
transform: scale(1.2);
}
}
}
}
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 |
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?
.header {
background-image: linear-gradient(to right bottom, rgba($color-primary-light, 0.8), rgba($color-primary-dark, 0.8)), url(../img/hero-small.jpg);
@media (min-resolution: 192dpi) and (min-width: 37.5em),
(min-width: 125em) {
background-image: linear-gradient(to right bottom, rgba($color-secondary-light, 0.8), rgba($color-secondary-dark, 0.8)), url(../img/hero.jpg);
}
}
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.
.popup {
background-color: rgba($color-black, .8);
@supports(-webkit-backdrop-filter: blur(10px)) or (backdrop-filter: blur(10px)) {
// only work in safari
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
background-color: rgba($color-black, .3);
}
}
.card {
&__side {
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
}
Media Queries: resolution feature
@media (min-resolution: 192dpi) and (min-width: 37.5em),
(-webkit-min-device-pixel-ratio: 2) and (min-width: 37.5em),
(min-width: 125em) {
background-image: linear-gradient(to right bottom, rgba($color-secondary-light, 0.8), rgba($color-secondary-dark, 0.8)), url(../img/hero.jpg);
}
"scripts": {
"compile:sass": "node-sass sass/main.scss css/style.comp.css",
"concat:css": "concat -o css/style.concat.css css/icon-font.css css/style.comp.css",
"prefix:css": "postcss --use autoprefixer -b 'last 10 versions' css/style.concat.css -o css/style.prefix.css",
"compress:css": "node-sass css/style.prefix.css css/style.css --output-style compressed",
"build:css": "npm-run-all compile:sass concat:css prefix:css compress:css"
}
<html lang="en">
<head>
<link rel="stylesheet" href="css/style.css">
</head>
</html>
"scripts": {
"watch:sass": "node-sass sass/main.scss css/style.css -w",
"devserver": "live-server",
"start": "npm-run-all --parallel devserver watch:sass",
}
::selection {
background-color: $color-primary;
color: $color-white;
}
.card {
@media only screen and (max-width: 56.25em), // width < 900px ?
only screen and (hover: none) { // touch device
}
}
Flexbox
<div class="container">
<div class="item">1</div>
<div class="item i2">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
</div>
.container {
background-color:#ccc;
padding: 10px;
height: 1000px;
/* use flexbox */
display: flex;
/* set main axis direction */
flex-direction: row;
/* control how items are positioned in main axis */
justify-content: center;
/* control how items are positioned in cross axis */
align-items: center;
}
<div class="container">
<div class="item">1</div>
<div class="item i2">2</div>
<div class="item i3">3</div>
<div class="item i4">4</div>
<div class="item">5</div>
</div>
.item{
background-color:#f1425d;
padding:30px;
margin:30px;
color:#fff;
font-size:40px;
/* all items grow as much as they can */
/* flex-grow: 1; */
/* shorthand for flex-grow flex-shrink flex-basis*/
/* flex: 1; */
}
.i2 {
height: 200px;
/* grow 3x more than other items */
/* flex-grow: 3; */
/* grow to 20% of the flex container */
/* flex-basis: 20%; */
/* grow to 300px */
/* flex-basis: 300px; */
/* not allow to shrink */
/* flex-shrink: 0; */
flex: 0 1 300px;
}
.i3 {
order: 1;
flex: 1;
}
.i4 {
/* over-write align-items in container */
/* align-self: flex-end; */
/* all flex box items order are 0 by default */
order: -1;
}
<div class="container">
<div class="item">1</div>
<div class="item i2">2</div>
<div class="item i3">3</div>
<div class="item i4">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
</div>
.container{
/* wrap all items to new line if container width is not enough*/
flex-wrap: wrap;
/* align rows in cross axis */
align-content: center;
}
:root {
--color-white: #fff;
--color-primary: #eb2f64;
--color-primary-light: #FF3366;
--color-primary-dark: #BA265D;
--color-grey-light-1: #faf9f9;
--color-grey-light-2: #f4f2f2;
--color-grey-light-3: #f0eeee;
--color-grey-light-4: #ccc;
--color-grey-dark-1: #333;
--color-grey-dark-2: #777;
--color-grey-dark-3: #999;
--shadow-dark: 0 2rem 6rem rbga(0, 0, 0, .3);
}
* {
margin: 0;
padding: 0;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
html {
box-sizing: border-box;
font-size: 62.5%; // 1rem = 10px, 10px/16px = 62.5%
}
body {
font-family: 'Open Sans', sans-serif;
font-weight: 400;
line-height: 1.6;
background-image: linear-gradient(to right bottom, var(--color-primary-light), var(--color-primary-dark));
background-size: cover;
background-repeat: no-repeat;
min-height: 100vh;
}
// similar to html selector for css
:root {
--color-primary-light: #FF3366;
--color-primary-dark: #BA265D;
}
body {
background-image: linear-gradient(to right bottom, var(--color-primary-light), var(--color-primary-dark));
}
<body>
<div class="container">
<header class="header">
Header part
</header>
<div class="content">
<div class="sidebar">
Navigation
</div>
<main class="hotel-view">
Hotel view
</main>
</div>
</div>
</body>
.container {
max-width: 120rem;
margin: 8rem auto;
background-color: var(--color-grey-light-2);
box-shadow: var(--shadow-dark);
min-height: 50rem;
}
.header {
height: 7rem;
background-color: var(--color-white);
border-bottom: 1px solid var(--color-grey-light-2);
}
.content {
display: flex;
}
.sidebar {
background-color: var(--color-grey-dark-1);
flex: 0 0 18%;
}
.hotel-view {
background-color: var(--color-white);
flex: 1;
}
Components
<header class="header">
<img src="img/logo.png" alt="trillo logo" class="logo">
<form action="" class="search">
<input type="text" class="search__input" placeholder="Search hotels">
<button class="search__button">
<svg class="search__icon">
<use xlink:href="img/sprite.svg#icon-magnifying-glass"></use>
</svg>
</button>
</form>
<nav class="user-nav">
<div class="user-nav__icon-box">
<svg class="user-nav__icon">
<use xlink:href="img/sprite.svg#icon-bookmark"></use>
</svg>
<span class="user-nav__notification">7</span>
</div>
<div class="user-nav__icon-box">
<svg class="user-nav__icon">
<use xlink:href="img/sprite.svg#icon-chat"></use>
</svg>
<span class="user-nav__notification">13</span>
</div>
<div class="user-nav__user">
<img src="img/user.jpg" alt="trillo logo" class="user-nav__user-photo">
<span class="user-nav__user-name">Jonas</span>
</div>
</nav>
</header>
// LOGO
.logo {
height: 3.25rem;
}
// SEARCH
.search {
&__input {
}
&__button {
}
&__icon {
height: 2rem;
width: 2rem;
}
}
// USER NAVIGATION
.user-nav {
&__icon-box {
}
&__icon {
height: 2.25rem;
width: 2.25rem;
}
&__notification {
}
&__user {
}
&__user-photo {
height: 3.75rem;
border-radius: 50%;
}
&__user-name {
}
}
<header class="header">
<form action="" class="search">
<input type="text" class="search__input" placeholder="Search hotels">
<button class="search__button">
<svg class="search__icon">
<use xlink:href="img/sprite.svg#icon-magnifying-glass"></use>
</svg>
</button>
</form>
<nav class="user-nav">
<div class="user-nav__icon-box">
<svg class="user-nav__icon">
<use xlink:href="img/sprite.svg#icon-bookmark"></use>
</svg>
<span class="user-nav__notification">7</span>
</div>
</nav>
</header>
Search bar Component
header {
font-size: 1.4rem;
height: 7rem;
background-color: var(--color-white);
border-bottom: var(--color-grey-light-2);
display: flex;
justify-content: space-between;
align-items: center;
}
// LOGO
.logo {
height: 3.25rem;
margin-left: 3rem;
}
// SEARCH
.search {
flex: 0 0 40%;
display: flex;
align-items: center;
justify-content: center;
&__input {
font-family: inherit;
font-size: inherit;
color: inherit;
background-color: var(--color-grey-light-2);
border: none;
padding: .7rem 2rem;
border-radius: 100px;
width: 90%;
transition: all .2s;
margin-right: -3.5rem;
&:focus {
outline: none;
width: 100%;
background-color: var(--color-grey-light-3);
}
&::-webkit-input-placeholder {
font-weight: 100;
color: var(--color-grey-light-4);
}
}
&__input:focus + &__button {
background-color: var(--color-grey-light-3);
}
&__button {
border: none;
background-color: var(--color-grey-light-2);
&:focus {
outline: none;
}
&:active {
transform: translateY(2px);
}
}
&__icon {
height: 2rem;
width: 2rem;
fill: var(--color-grey-dark-3)
}
}
header {
display: flex;
justify-content: space-between;
align-items: center;
}
.search {
flex: 0 0 40%;
display: flex;
align-items: center;
justify-content: center;
}
.search {
&__icon {
height: 2rem;
width: 2rem;
fill: var(--color-grey-dark-3)
}
}
User navigations Component
.user-nav {
align-self: stretch;
display: flex;
& > * {
padding: 0 2rem;
cursor: pointer;
height: 100%;
display: flex;
align-items: center;
}
& > *:hover {
background-color: var(--color-grey-light-2);
}
&__icon-box {
position: relative;
}
&__icon {
height: 2.25rem;
width: 2.25rem;
fill: var(--color-grey-dark-2);
}
&__notification {
font-size: .8rem;
height: 1.75rem;
width: 1.75rem;
border-radius: 50%;
background-color: var(--color-primary);
color: var(--color-white);
position: absolute;
top: 1.5rem;
right: 1.1rem;
display: flex;
justify-content: center;
align-items: center;
}
&__user-photo {
height: 3.75rem;
border-radius: 50%;
margin-right: 1rem;
}
}
.sidebar {
background-color: var(--color-grey-dark-1);
flex: 0 0 18%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
// SIDE NAVIGATION
.side-nav {
&__item {
}
&__link {
}
&__icon {
width: 1.75rem;
height: 1.75rem;
}
}
// LEGAL TEXT
.legal {
font-size: 1.2rem;
color: var(--color-grey-light-4);
text-align: center;
padding: 2.5rem;
}
.sidebar {
display: flex;
flex-direction: column;
justify-content: space-between;
}
.side-nav {
font-size: 1.4rem;
list-style: none;
margin-top: 3.5rem;
&__item {
position: relative;
&:not(:last-child) {
margin-bottom: .5rem;
}
}
&__item::before {
content: "";
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 3px;
background-color: var(--color-primary);
transform: scaleY(0);
transition: transform .2s,
width .4s cubic-bezier(1,0,0,1) .2s,
background-color .1s;
}
&__item:hover::before,
&__item--active::before {
transform: scaleY(1);
width: 100%;
}
&__item:active::before {
background-color: var(--color-primary-light);
}
&__link:link,
&__link:visited {
color: var(--color-grey-light-1);
text-decoration: none;
text-transform: uppercase;
display: block;
padding: 1.5rem 3rem;
position: relative;
z-index: 10;
display: flex;
align-items: center;
}
&__icon {
width: 1.75rem;
height: 1.75rem;
margin-right: 2rem;
fill: currentColor;
}
}
.side-nav {
&__item::before {
content: "";
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 3px;
background-color: var(--color-primary);
transform: scaleY(0);
transition: transform .2s,
width .4s cubic-bezier(1,0,0,1) .2s,
background-color .1s;
}
&__item:hover::before,
&__item--active::before {
transform: scaleY(1);
width: 100%;
}
&__item:active::before {
background-color: var(--color-primary-light);
}
}
currentColor property take the color value of itself or its parent
<a href="" class="side-nav__link">
<svg class="side-nav__icon">
<use xlink:href="img/sprite.svg#icon-key"></use>
</svg>
<span>Car rental</span>
</a>
.side-nav {
&__link:link,
&__link:visited {
color: var(--color-grey-light-1);
}
&__icon {
fill: currentColor;
}
}
Hotel Overview Layout
<div class="gallery">
<figure class="gallery__item">
<img src="img/hotel-1.jpg" alt="Photo of hotel 1" class="gallery__photo">
</figure>
<figure class="gallery__item">
<img src="img/hotel-2.jpg" alt="Photo of hotel 2" class="gallery__photo">
</figure>
<figure class="gallery__item">
<img src="img/hotel-3.jpg" alt="Photo of hotel 3" class="gallery__photo">
</figure>
</div>
<div class="overview">
<h1 class="overview__heading">Hotel Las Palmas</h1>
<div class="overview__stars">
<svg class="overview__icon-star">
<use xlink:href="img/sprite.svg#icon-star"></use>
</svg>
<svg class="overview__icon-star">
<use xlink:href="img/sprite.svg#icon-star"></use>
</svg>
<svg class="overview__icon-star">
<use xlink:href="img/sprite.svg#icon-star"></use>
</svg>
<svg class="overview__icon-star">
<use xlink:href="img/sprite.svg#icon-star"></use>
</svg>
<svg class="overview__icon-star">
<use xlink:href="img/sprite.svg#icon-star"></use>
</svg>
</div>
<div class="overview__location">
<svg class="overview__icon-location">
<use xlink:href="img/sprite.svg#icon-location-pin"></use>
</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>
.gallery {
display: flex;
&__photo {
width: 100%;
display: block;
}
}
.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;
}
&__icon-star,
&__icon-location {
width: 1.75em;
height: 1.75em;
fill: var(--color-primary);
}
}
```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;
}
}
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;
}
}
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;
}
}
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;
}
}
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;
}
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;
}
}
}
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;
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
}
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;
}
}
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
}
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;
}
}
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;
}
}
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;
}
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;
}
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;
}
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;
}
}
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;
}
}
}
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;
}
}
}
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; }
}
}
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; }
}
}
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;
}
<header class="header">header</header>
<div class="realtors">Top 3 Realtors</div>
<section class="features">features</section>
<div class="story__pictures">story pictures</div>
<div class="story__content">story content</div>
<section class="homes">homes</section>
<section class="gallery">gallery</section>
<footer class="footer">footer</footer>
</body>
```scss
.container {
display: grid;
grid-template-rows: 80vh min-content 40vw repeat(3, min-content);
}
.container {
display: grid;
grid-template-rows: 80vh min-content 40vw repeat(3, min-content);
// 1140 / 0 = 140px = 14rem
// center content on the page up to 1140px
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];
}
.sidebar {
background-color: $color-primary;
grid-column: sidebar-start / sidebar-end;
grid-row: 1 / -1;
}
.header {
background-color: $color-grey-dark-1;
grid-column: full-start / col-end 6;
}
.realtors {
background-color: $color-secondary;
grid-column: col-start 7 / full-end;
}
.features {
background-color: $color-grey-light-2;
grid-column: center-start / center-end;
}
.story {
&__pictures {
background-color: $color-primary;
grid-column: full-start /col-end 4;
}
&__content {
background-color: $color-grey-light-1;
grid-column: col-start 5 /full-end;
}
}
.homes {
background-color: $color-secondary;
grid-column: center-start / center-end;
}
.gallery {
background-color: $color-grey-dark-1;
grid-column: full-start / full-end;
}
.footer {
background-color: $color-secondary;
grid-column: full-start / full-end;
}
.container {
display: grid;
grid-template-rows: 80vh min-content 40vw repeat(3, min-content);
// 1140 / 0 = 140px = 14rem
// center content on the page up to 1140px
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];
}
.sidebar {
grid-column: sidebar-start / sidebar-end;
grid-row: 1 / -1;
}
.header { grid-column: full-start / col-end 6; }
.realtors { grid-column: col-start 7 / full-end; }
.features { grid-column: center-start / center-end; }
.story {
&__pictures { grid-column: full-start /col-end 4; }
&__content { grid-column: col-start 5 /full-end; }
}
.homes { grid-column: center-start / center-end; }
.gallery { grid-column: full-start / full-end; }
.footer { grid-column: full-start / full-end; }
<section class="features">
<div class="feature">
<svg class="feature__icon">
<use xlink:href="img/sprite.svg#icon-global"></use>
</svg>
<h4 class="heading-4 heading-4--dark">World's best luxury homes</h4>
<p class="feature__text">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Tenetur distinctio necessitatibus pariatur voluptatibus.</p>
</div>
<div class="feature">
<svg class="feature__icon">
<use xlink:href="img/sprite.svg#icon-trophy"></use>
</svg>
<h4 class="heading-4 heading-4--dark">Only the best properties</h4>
<p class="feature__text">Voluptatum mollitia quae. Vero ipsum sapiente molestias accusamus rerum sed a eligendi aut quia.</p>
</div>
<div class="feature">
<svg class="feature__icon">
<use xlink:href="img/sprite.svg#icon-map-pin"></use>
</svg>
<h4 class="heading-4 heading-4--dark">All homes in in top locations</h4>
<p class="feature__text">Tenetur distinctio necessitatibus pariatur voluptatibus quidem consequatur harum.</p>
</div>
<div class="feature">
<svg class="feature__icon">
<use xlink:href="img/sprite.svg#icon-key"></use>
</svg>
<h4 class="heading-4 heading-4--dark">New home in one week</h4>
<p class="feature__text">Vero ipsum sapiente molestias accusamus rerum. Lorem, ipsum dolor sit amet consectetur adipisicing elit.</p>
</div>
<div class="feature">
<svg class="feature__icon">
<use xlink:href="img/sprite.svg#icon-presentation"></use>
</svg>
<h4 class="heading-4 heading-4--dark">Top 1% realtors</h4>
<p class="feature__text">Quidem consequatur harum, voluptatum mollitia quae. Tenetur distinctio necessitatibus pariatur voluptatibus.</p>
</div>
<div class="feature">
<svg class="feature__icon">
<use xlink:href="img/sprite.svg#icon-lock"></use>
</svg>
<h4 class="heading-4 heading-4--dark">Secure payments on nexter</h4>
<p class="feature__text">Pariatur voluptatibus quidem consequatur harum, voluptatum mollitia quae.</p>
</div>
</section>
.features {
grid-column: center-start / center-end;
margin: 15rem 0;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 6rem;
}
.features {
grid-column: center-start / center-end;
margin: 15rem 0;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 6rem;
}
.features {
grid-column: center-start / center-end;
margin: 15rem 0;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(25rem, 1fr));
grid-gap: 6rem;
align-items: start;
}
.feature {
display: grid;
grid-template-columns: min-content 1fr;
grid-row-gap: 1.5rem;
grid-column-gap: 2.5rem;
&__icon {
fill: $color-primary;
width: 4.5rem;
height: 4.5rem;
grid-row: 1 / span 2;
transform: translateY(-1rem);
}
&__text {
font-size: 1.7rem;
}
}
%heading {
font-family: $font-display;
font-weight: 400;
}
.heading-4 {
@extend %heading;
font-size: 1.9rem;
&--light { color: $color-grey-light-1; }
&--dark { color: $color-grey-dark-1; }
}
<div class="feature">
<svg class="feature__icon">
<use xlink:href="img/sprite.svg#icon-lock"></use>
</svg>
<h4 class="heading-4 heading-4--dark">Secure payments on nexter</h4>
<p class="feature__text">Pariatur voluptatibus quidem consequatur harum, voluptatum mollitia quae.</p>
</div>
.feature {
display: grid;
grid-template-columns: min-content 1fr;
grid-row-gap: 1.5rem;
grid-column-gap: 2.5rem;
&__icon {
grid-row: 1 / span 2;
}
}
.features {
grid-template-columns: repeat(auto-fit, minmax(25rem, 1fr));
}
<div class="story__content">
<h3 class="heading-3 mb-sm">Happy Customers</h3>
<h2 class="heading-2 heading-2--dark mb-md">“The best decision of our lives”</h2>
<p class="story__text">
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Tenetur distinctio necessitatibus pariatur voluptatibus. Quidem consequatur harum volupta!
</p>
<button class="btn">Find your own home</button>
</div>
.story {
&__content {
background-color: $color-grey-light-1;
grid-column: col-start 5 / full-end;
padding: 6rem 8vw;
// display: flex;
// flex-direction: column;
// justify-content: center;
// align-items: flex-start;
display: grid;
align-content: center;
justify-items: start;
}
&__text {
font-size: 1.5rem;
font-style: italic;
margin-bottom: 4rem;
}
}
.heading-2 {
@extend %heading;
font-size: 4rem;
font-style: italic;
line-height: 1;
&--light { color: $color-grey-light-1; }
&--dark { color: $color-grey-dark-1; }
}
.heading-3 {
@extend %heading;
font-size: 1.6rem;
color: $color-primary;
text-transform: uppercase;
}
.btn {
background-color: $color-primary;
color: #fff;
border: none;
border-radius: 0;
font-family: $font-display;
font-size: 1.5rem;
text-transform: uppercase;
padding: 1.8rem 3rem;
cursor: pointer;
transition: all .2s;
&:hover {
background-color: $color-primary-dark;
}
}
.mb-sm { margin-bottom: 2rem; }
.mb-md { margin-bottom: 3rem; }
.mb-lg { margin-bottom: 4rem; }
.mb-hg { margin-bottom: 8rem; }
<div class="story__pictures">
<img src="img/story-1.jpeg" alt="Couple with new house" class="story__img--1">
<img src="img/story-2.jpeg" alt="New house" class="story__img--2">
</div>
.story {
&__pictures {
background-color: $color-primary;
grid-column: full-start / col-end 4;
background-image: linear-gradient(rgba($color-primary, .5), rgba($color-primary, .5)), url(../img/back.jpg);
background-size: cover;
display: grid;
grid-template-rows: repeat(6, 1fr);
grid-template-columns: repeat(6, 1fr);
align-items: center;
}
&__img--1 {
width: 100%;
grid-row: 2 / 6;
grid-column: 2 / 6;
box-shadow: 0 2rem 5rem rgba(#000, .1);
}
&__img--2 {
width: 115%;
grid-row: 4 / 6;
grid-column: 4 / 7;
z-index: 20;
box-shadow: 0 2rem 5rem rgba(#000, .2);
}
}
.story {
&__pictures {
display: grid;
grid-template-rows: repeat(6, 1fr);
grid-template-columns: repeat(6, 1fr);
align-items: center;
}
&__img--2 {
width: 115%;
grid-row: 4 / 6;
grid-column: 4 / 7;
z-index: 20;
}
}
Quick! What’s the Difference Between Flexbox and Grid?
<section class="homes">
<div class="home">
<img src="img/house-1.jpeg" alt="House 1" class="home__img">
<svg class="home__like">
<use xlink:href="img/sprite.svg#icon-heart-full"></use>
</svg>
<h5 class="home__name">Beautiful Familiy House</h5>
<div class="home__location">
<svg>
<use xlink:href="img/sprite.svg#icon-map-pin"></use>
</svg>
<p>USA</p>
</div>
<div class="home__rooms">
<svg>
<use xlink:href="img/sprite.svg#icon-profile-male"></use>
</svg>
<p>5 rooms</p>
</div>
<div class="home__area">
<svg>
<use xlink:href="img/sprite.svg#icon-expand"></use>
</svg>
<p>325 m<sup>2</sup></p>
</div>
<div class="home__price">
<svg>
<use xlink:href="img/sprite.svg#icon-key"></use>
</svg>
<p>$1,200,000</p>
</div>
<button class="btn home__btn">Contact realtor</button>
</div>
</section>
.homes {
grid-column: center-start / center-end;
margin: 15rem 0;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(25rem, 1fr));
grid-gap: 7rem;
}
.home {
background-color: $color-grey-light-1;
&__img {
width: 100%;
}
&__like {
}
&__name {
}
&__location,
&__rooms,
&__area,
&__price {
svg {
fill: $color-primary;
height: 2rem;
width: 2rem;
}
p {
}
}
&__btn {
}
}
.home {
background-color: $color-grey-light-1;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-row-gap: 3.5rem;
&__img {
width: 100%;
grid-row: 1 / 2;
grid-column: 1 / -1;
z-index: 1;
}
&__like {
grid-row: 1 / 2;
grid-column: 2 / 3;
fill: $color-primary;
height: 2.5rem;
width: 2.5rem;
z-index: 2;
justify-self: end;
margin: 1rem;
}
&__name {
grid-row: 1 / 2;
grid-column: 1 / -1;
justify-self: center;
align-self: end;
z-index: 3;
width: 80%;
font-family: $font-display;
font-size: 1.6rem;
text-align: center;
padding: 1.25rem;
background-color: $color-secondary;
color: #fff;
font-weight: 400;
transform: translateY(50%);
}
&__location,
&__rooms {
margin-top: 2.5rem;
}
&__location,
&__rooms,
&__area,
&__price {
font-size: 1.5rem;
margin-left: 2rem;
display: flex;
align-items: center;
svg {
fill: $color-primary;
height: 2rem;
width: 2rem;
margin-right: 1rem;
}
}
&__btn {
grid-column: 1 / -1;
}
}
<section class="gallery">
<figure class="gallery__item gallery__item--1"><img src="img/gal-1.jpeg" alt="Gallery image 1" class="gallery__img"></figure>
<figure class="gallery__item gallery__item--2"><img src="img/gal-2.jpeg" alt="Gallery image 2" class="gallery__img"></figure>
<figure class="gallery__item gallery__item--3"><img src="img/gal-3.jpeg" alt="Gallery image 3" class="gallery__img"></figure>
<figure class="gallery__item gallery__item--4"><img src="img/gal-4.jpeg" alt="Gallery image 4" class="gallery__img"></figure>
<figure class="gallery__item gallery__item--5"><img src="img/gal-5.jpeg" alt="Gallery image 5" class="gallery__img"></figure>
<figure class="gallery__item gallery__item--6"><img src="img/gal-6.jpeg" alt="Gallery image 6" class="gallery__img"></figure>
<figure class="gallery__item gallery__item--7"><img src="img/gal-7.jpeg" alt="Gallery image 7" class="gallery__img"></figure>
<figure class="gallery__item gallery__item--8"><img src="img/gal-8.jpeg" alt="Gallery image 8" class="gallery__img"></figure>
<figure class="gallery__item gallery__item--9"><img src="img/gal-9.jpeg" alt="Gallery image 9" class="gallery__img"></figure>
<figure class="gallery__item gallery__item--10"><img src="img/gal-10.jpeg" alt="Gallery image 10" class="gallery__img"></figure>
<figure class="gallery__item gallery__item--11"><img src="img/gal-11.jpeg" alt="Gallery image 11" class="gallery__img"></figure>
<figure class="gallery__item gallery__item--12"><img src="img/gal-12.jpeg" alt="Gallery image 12" class="gallery__img"></figure>
<figure class="gallery__item gallery__item--13"><img src="img/gal-13.jpeg" alt="Gallery image 13" class="gallery__img"></figure>
<figure class="gallery__item gallery__item--14"><img src="img/gal-14.jpeg" alt="Gallery image 14" class="gallery__img"></figure>
</section>
.gallery {
background-color: $color-grey-light-1;
grid-column: full-start / full-end;
display: grid;
grid-template-columns: repeat(8, 1fr);
grid-template-rows: repeat(7, 5vw);
grid-gap: 1.5rem;
padding: 1.5rem;
&__item {
&--1 {
grid-row: 1 / span 2;
grid-column: 1 / span 2;
}
}
&__img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
}
&__img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.gallery {
&__item {
&--1 {
grid-row: 1 / span 2;
grid-column: 1 / span 2;
}
&--2 {
grid-row: 1 / span 3;
grid-column: 3 / span 3;
}
&--3 {
grid-row: 1 / span 2;
grid-column: 6 / 7;
}
&--4 {
grid-row: 1 / span 2;
grid-column: 7 / -1;
}
&--5 {
grid-row: 3 / span 3;
grid-column: 1 / span 2;
}
&--6 {
grid-row: 4 / span 2;
grid-column: 3 / span 2;
}
&--7 {
grid-row: 4 / 5;
grid-column: 5 / 6;
}
&--8 {
grid-row: 3 / span 2;
grid-column: 6 / span 2;
}
&--9 {
grid-row: 3 / span 3;
grid-column: 8 / -1;
}
&--10 {
grid-row: 6 / span 2;
grid-column: 1 / 2;
}
&--11 {
grid-row: 6 / span 2;
grid-column: 2 / span 2;
}
&--12 {
grid-row: 6 / span 2;
grid-column: 4 / 5;
}
&--13 {
grid-row: 5 / span 3;
grid-column: 5 / span 3;
}
&--14 {
grid-row: 6 / span 2;
grid-column: 8 / -1;
}
}
}
<footer class="footer">
<ul class="nav">
<li class="nav__item"><a href="#" class="nav__link">Find your dream home</a></li>
<li class="nav__item"><a href="#" class="nav__link">Request proposal</a></li>
<li class="nav__item"><a href="#" class="nav__link">Download home planner</a></li>
<li class="nav__item"><a href="#" class="nav__link">Contact us</a></li>
<li class="nav__item"><a href="#" class="nav__link">Submit your property</a></li>
<li class="nav__item"><a href="#" class="nav__link">Come work with us!</a></li>
</ul>
<p class="copyright">
© 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.
</p>
</footer>
.footer {
background-color: $color-secondary;
grid-column: full-start / full-end;
padding: 8rem;
}
.nav {
list-style: none;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
grid-gap: 2rem;
align-items: center;
&__link:link,
&__link:visited {
font-size: 1.4rem;
color: #fff;
text-decoration: none;
font-family: $font-display;
text-transform: uppercase;
text-align: center;
padding: 1.5rem;
display: block;
transition: all .2s;
}
&__link:hover,
&__link:active {
background-color: rgba(#fff, .05);
transform: translateY(-3px);
}
}
.copyright {
font-size: 1.4rem;
color: $color-grey-light-2;
margin-top: 6rem;
margin-right: auto;
margin-left: auto;
text-align: center;
width: 70%;
}
<div class="sidebar">
<button class="nav-btn"></button>
</div>
.sidebar {
background-color: $color-primary;
grid-column: sidebar-start / sidebar-end;
grid-row: 1 / -1;
display: flex;
justify-content: center;
}
.nav-btn {
border: none;
border-radius: 0;
background-color: #fff;
height: 2px;
width: 4.5rem;
margin-top: 4rem;
&::before,
&::after {
background-color: #fff;
height: 2px;
width: 4.5rem;
content: "";
display: block;
}
&::before { transform: translateY(-1.5rem); }
&::after { transform: translateY(1.3rem); }
}
<header class="header">
<img src="img/logo.png" alt="Nexter logo" class="header__logo">
<h3 class="heading-3">Your own home:</h3>
<h1 class="heading-1">The ultimate personal freedom</h1>
<button class="btn header__btn">View our properties</button>
<div class="header__seenon-text">Seen on</div>
<div class="header__seenon-logos">
<img src="img/logo-bbc.png" alt="Seen on logo 1">
<img src="img/logo-forbes.png" alt="Seen on logo 2">
<img src="img/logo-techcrunch.png" alt="Seen on logo 3">
<img src="img/logo-bi.png" alt="Seen on logo 4">
</div>
</header>
.heading-1 {
@extend %heading;
font-size: 4.5rem;
color: $color-grey-light-1;
line-height: 1;
}
.header {
background-color: $color-grey-dark-1;
grid-column: full-start / col-end 6;
background-image: linear-gradient(rgba($color-secondary, .93), rgba($color-secondary, .93)), url(../img/hero.jpeg);
background-size: cover;
background-position: center;
padding: 8rem;
padding-top: 4rem;
display: grid;
grid-template-rows: 1fr min-content minmax(6rem, min-content) 1fr;
grid-template-columns: minmax(min-content, max-content);
grid-row-gap: 1.5rem;
justify-content: center;
&__logo {
height: 3rem;
justify-self: center;
}
&__btn {
align-self: start;
justify-self: start;
}
&__seenon-text {
}
&__seenon-logos {
img {
height: 2.5rem;
}
}
}
.header {
&__seenon-text {
display: grid;
grid-template-columns: 1fr max-content 1fr;
grid-column-gap: 1.5rem;
align-items: center;
font-size: 1.6rem;
color: $color-grey-light-2;
&::before,
&::after {
content: "";
height: 1px;
display: block;
background-color: currentColor;
}
}
&__seenon-logos {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-column-gap: 3rem;
justify-items: center;
align-items: center;
img {
height: 2.5rem;
max-width: 100%;
filter: brightness(70%);
}
}
}
.header {
display: grid;
grid-template-rows: 1fr min-content minmax(6rem, min-content) 1fr;
grid-row-gap: 1.5rem;
}
.header {
&__seenon-text {
display: grid;
grid-template-columns: 1fr max-content 1fr;
grid-column-gap: 1.5rem;
align-items: center;
font-size: 1.6rem;
color: $color-grey-light-2;
&::before,
&::after {
content: "";
height: 1px;
display: block;
background-color: currentColor;
}
}
}
<div class="realtors">
<h3 class="heading-3">Top 3 Realtors</h3>
<div class="realtors__list">
<img src="img/realtor-1.jpeg" alt="Realtor 1" class="realtors__img">
<div class="realtors__details">
<h4 class="heading-4 heading-4--light">Erik Feinman</h4>
<p class="realtors__sold">245 houses sold</p>
</div>
<img src="img/realtor-2.jpeg" alt="Realtor 2" class="realtors__img">
<div class="realtors__details">
<h4 class="heading-4 heading-4--light">Kim Brown</h4>
<p class="realtors__sold">212 houses sold</p>
</div>
<img src="img/realtor-3.jpeg" alt="Realtor 3" class="realtors__img">
<div class="realtors__details">
<h4 class="heading-4 heading-4--light">Toby Ramsey</h4>
<p class="realtors__sold">198 houses sold</p>
</div>
</div>
</div>
.realtors {
background-color: $color-secondary;
grid-column: col-start 7 / full-end;
padding: 3rem;
display: grid;
align-content: center;
justify-content: center;
justify-items: center;
grid-row-gap: 2rem;
&__list {
display: grid;
grid-template-columns: min-content max-content;
grid-column-gap: 2rem;
grid-row-gap: 5vh;
align-items: center;
}
&__img {
width: 7rem;
border-radius: 50%;
display: block;
}
&__sold {
text-transform: uppercase;
color: $color-grey-light-2;
margin-top: -3px;
}
}
// RESPONSIVE BREAKPOINTS
$bp-largest: 75em; // 1200px
$bp-large: 62.5em; // 1000px
$bp-medium: 50em; // 800px;
$bp-small: 37.5em; // 600px;
html {
font-size: 62.5%; // 10px/16px = 62.5% -> 1rem = 10px
@media only screen and (max-width: $bp-largest) {
font-size: 50%;
}
}
.container {
display: grid;
grid-template-rows: 80vh min-content 40vw repeat(3, min-content);
// 1140 / 0 = 140px = 14rem
// center content on the page up to 1140px
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];
@media only screen and (max-width: $bp-large) {
grid-template-rows: 6rem 80vh min-content 40vw repeat(3, min-content);
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];
}
@media only screen and (max-width: $bp-medium) {
grid-template-rows: 6rem calc(100vh - 6rem);
}
}
.sidebar {
grid-column: sidebar-start / sidebar-end;
grid-row: 1 / -1;
display: flex;
justify-content: center;
@media only screen and (max-width: $bp-large) {
grid-column: 1 / -1;
grid-row: 1 / 2;
justify-content: flex-end;
align-items: center;
}
}
.nav-btn {
margin-top: 4rem;
&::before { transform: translateY(-1.5rem); }
&::after { transform: translateY(1.3rem); }
@media only screen and (max-width: $bp-large) {
margin-top: 0;
margin-right: 3rem;
&::before { transform: translateY(-1.2rem); }
&::after { transform: translateY(1rem); }
}
}
.header {
grid-column: full-start / col-end 6;
padding: 8rem;
@media only screen and (max-width: $bp-medium) {
grid-column: 1 / -1;
}
@media only screen and (max-width: $bp-small) {
padding: 5rem;
}
}
.realtors {
grid-column: col-start 7 / full-end;
@media only screen and (max-width: $bp-medium) {
grid-column: 1 / -1;
}
&__list {
grid-template-columns: min-content max-content;
@media only screen and (max-width: $bp-medium) {
grid-template-columns: repeat(3, min-content max-content);
}
@media only screen and (max-width: $bp-small) {
grid-template-columns: min-content max-content;
}
}
}
.story {
&__pictures {
grid-column: full-start / col-end 4;
display: grid;
grid-template-rows: repeat(6, 1fr);
grid-template-columns: repeat(6, 1fr);
align-items: center;
@media only screen and (max-width: $bp-medium) {
grid-column: 1 / -1;
padding: 6rem;
}
}
&__img--1 {
grid-row: 2 / 6;
grid-column: 2 / 6;
@media only screen and (max-width: $bp-medium) {
grid-column: 1 / 5;
grid-row: 1 / -1;
}
}
&__img--2 {
width: 115%;
grid-row: 4 / 6;
grid-column: 4 / 7;
@media only screen and (max-width: $bp-medium) {
grid-row: 1 / -1;
width: 100%;
}
}
&__content {
grid-column: col-start 5 / full-end;
@media only screen and (max-width: $bp-medium) {
grid-column: 1 / -1;
grid-row: 5 / 6;
}
}
}
.features {
@supports(display: grid) {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(25rem, 1fr));
grid-gap: 6rem;
align-items: start;
}
}
.feature {
float: left;
width: 33.3333%;
margin-bottom: 6rem;
@supports(display: grid) {
width: auto;
margin-bottom: 0;
}
}