Luyện tập CSS Grid qua bài tập tạo layout Airbnb, youtube, Pinterest

https://hanoiict.edu.vn/luyen-tap-css-grid-qua-bai-tap-tao-layout-airbnb-youtube-pinterest

Các thuật ngữ trong CSS Grid

Grid Container

Grid Item

Grid Line

Grid Cell

Grid Area

Lưới CSS là gì?

CSS Grid Layout nổi bật khi chia trang thành các vùng lớn hoặc xác định mối quan hệ về size, position, và layer, giữa các phần được xây dựng từ HTML cơ bản.

Giống như table, Grid layout cho phép tác giả sắp xếp các phần tử thành các cột và hàng.

Tuy nhiên, nhiều layout khác làm bằng CSS Grid có thể dễ dàng hơn so với các bảng (bảng không được ưu tiên vì làm chậm tốc độ load).

Ví dụ: Các phần tử con của vùng grid container có thể tự định vị để chúng có thể đặt lên các layer, giống như các phần tử được định vị bằng CSS.

Tóm lại, CSS Grid cung cấp một tập hợp các công cụ sắp xếp layout và các công cụ mà các cài đặt hiện tại của layout theo cột và hàng được tạo ra từ việc sử dụng các thuộc tính witdh và height.

CSS Grid còn làm được nhiều hơn thế. Nó có thể tự động cập nhật các thuộc tính dựa trên các quy tắc bạn xác định (Chẳng hạn như: "khi trình duyệt có chiều rộng này, hãy làm điều này").

Do đó, tôi tin rằng CSS Grid là tương lai của các lập trình viên front-end.

Đối với những người mới tiếp xúc với khái niệm về grid: Một Grid là một tập hợp của các đường thằng, các đường ngang và dọc cho phép định vị vị trí các phần tử.

Các thuật ngữ trong CSS Grid

Grid Container

Grid Container là cha của tất cả các phần tử bên trong nó. Nó định nghĩa trạng thái ban đầu của các đường lưới (dọc và ngang).

Để tạo một CSS Grid, bạn chỉ cần thêm display: grid; cho class wapper hoặc container mà bạn đang làm việc trong document của mình.

Grid Item

Tất cả các item của các grid container được tham chiếu như là grid items.

Grid Line

Các đường lưới (grid lines) đại diện cho các đường dọc (vertical) và đường ngang (horizontal).

Thuộc tính grid-template-columns nghĩa các vị trí cột và grid-template-rows định nghĩa vị trí hàng.

Grid Cell

Đây là khu vực nhỏ nhất trong grid layout đó là không gian được xác định bởi bốn đường lưới.

Grid Area

Grid area là một vùng named-container-area chứa các khu vực được đặt tên cụ thể và xác định bởi các đường lưới được xác định khi viết css.

Học CSS Grid thông qua các ví dụ

1. Xây dựng gird layout website Airbnb

D:\Tiah\Toan\VPN\index.html

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<title>Document</title>
		<link rel="stylesheet" type="text/css" href="style.css">
	</head>
	<body>
		<div class="wrapper">
			<header class="header">Airbnb</header>
			<article class="content">
				<div class="panel">
					<img class="panel-img" src="https://a0.muscache.com/im/pictures/10356334/a831e142_original.jpg?aki_policy=large" />
					<span class="panel-title">I SETTE CONI - TRULLO EDERA</span>
					<span class="panel-subtitle">Entire house 2 beds</span>
				</div>
				<div class="panel">
					<img class="panel-img" src="https://a0.muscache.com/im/pictures/15273358/d7329e9a_original.jpg?aki_policy=large" />
					<span class="panel-title">I SETTE CONI - TRULLO EDERA</span>
					<span class="panel-subtitle">Entire house 2 beds</span>
				</div>
				<div class="panel">
					<img class="panel-img" src="https://a0.muscache.com/im/pictures/7cc3c855-f90e-4d0f-9b13-3b5c2a3c4bad.jpg?aki_policy=large" />
					<span class="panel-title">I SETTE CONI - TRULLO EDERA</span>
					<span class="panel-subtitle">Entire house 2 beds</span>
				</div>
				<div class="panel">
					<img class="panel-img" src="https://a0.muscache.com/im/pictures/10356334/a831e142_original.jpg?aki_policy=large" />
					<span class="panel-title">I SETTE CONI - TRULLO EDERA</span>
					<span class="panel-subtitle">Entire house 2 beds</span>
				</div>
				<div class="panel">
					<img class="panel-img" src="https://a0.muscache.com/im/pictures/15273358/d7329e9a_original.jpg?aki_policy=large" />
					<span class="panel-title">I SETTE CONI - TRULLO EDERA</span>
					<span class="panel-subtitle">Entire house 2 beds</span>
				</div>
				<div class="panel">
					<img class="panel-img" src="https://a0.muscache.com/im/pictures/7cc3c855-f90e-4d0f-9b13-3b5c2a3c4bad.jpg?aki_policy=large" />
					<span class="panel-title">I SETTE CONI - TRULLO EDERA</span>
					<span class="panel-subtitle">Entire house 2 beds</span>
				</div>
			</article>
			<aside class="sidebar">Sidebar - Map</aside>
		</div>
	</body>
</html>

D:\Tiah\Toan\VPN\style.css

*, *:before, *:after {
  box-sizing: border-box;
}
body {
  font-family: Courier, 'sans-serif';
  background-color: #fff;
  color: #141414;
}
h1, p {
  margin: 0 0 1em 0;
}
.wrapper {
  margin: 0 auto;
  display: grid;
  grid-template-columns: 65% 35%;
  grid-gap: 16px;
}
.wrapper > * {
  background-color: #fafafa;
  border-radius: 5px;
  font-size: 16px;
  margin-bottom: 10px;
}
.header,
.sidebar {
  padding: 24px;
}
.header, .footer {
  grid-column: 1 / -1;
  clear: both;
}
.content {
  padding: 8px;
  display: grid;
  margin: 0 auto;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)) ;
  grid-auto-rows: minmax(264px, auto);
  grid-gap: 16px;
}
.panel {
  margin-left: 5px;
  margin-right: 5px;
}
.panel-img {
  width: 100%;
  height: 80%;
}
@media (max-width: 1100px) {
  .wrapper {
    grid-template-columns: 1fr;
  }
  .sidebar {
    display: none;
  }
  .content {
    width: 100%;
    grid-template-columns: repeat(auto-fill, minmax(360px, 1fr) ) ;
    grid-auto-rows: minmax(300px, auto);
  }  
}
@supports (display: grid) {
  .wrapper > * {
    width: auto;
    margin: 0;
  }
}

2. Xây dựng layout Youtube bằng CSS Grid

D:\Tiah\Toan\VPN\index.html

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<title>Document</title>
		<link rel="stylesheet" type="text/css" href="style.css">
	</head>
	<body>
		<div class="wrapper">
			<header class="header">Youtube</header>
			<aside class="sidebar">Sidebar</aside>
			<article class="content">
				<div class="panel">
					<img class="panel-img" src="https://via.placeholder.com/200x150">
					<span class="panel-title">Lorem ipsum dolor sit amet, consectetur..</span>
					<span class="panel-subtitle">346,112 views</span>
				</div>
				<div class="panel">
					<img class="panel-img" src="https://via.placeholder.com/200x150">
					<span class="panel-title">Lorem ipsum dolor sit amet, consectetur..</span>
					<span class="panel-subtitle">346,112 views</span>
				</div>
				<div class="panel">
					<img class="panel-img" src="https://via.placeholder.com/200x150">
					<span class="panel-title">Lorem ipsum dolor sit amet, consectetur..</span>
					<span class="panel-subtitle">346,112 views</span>
				</div>
				<div class="panel">
					<img class="panel-img" src="https://via.placeholder.com/200x150">
					<span class="panel-title">Lorem ipsum dolor sit amet, consectetur..</span>
					<span class="panel-subtitle">346,112 views</span>
				</div>
				<div class="panel">
					<img class="panel-img" src="https://via.placeholder.com/200x150">
					<span class="panel-title">Lorem ipsum dolor sit amet, consectetur..</span>
					<span class="panel-subtitle">346,112 views</span>
				</div>
				<div class="panel">
					<img class="panel-img" src="https://via.placeholder.com/200x150">
					<span class="panel-title">Lorem ipsum dolor sit amet, consectetur..</span>
					<span class="panel-subtitle">346,112 views</span>
				</div>
				<div class="panel">
					<img class="panel-img" src="https://via.placeholder.com/200x150">
					<span class="panel-title">Lorem ipsum dolor sit amet, consectetur..</span>
					<span class="panel-subtitle">346,112 views</span>
				</div>
				<div class="panel">
					<img class="panel-img" src="https://via.placeholder.com/200x150">
					<span class="panel-title">Lorem ipsum dolor sit amet, consectetur..</span>
					<span class="panel-subtitle">346,112 views</span>
				</div>
				<div class="panel">
					<img class="panel-img" src="https://via.placeholder.com/200x150">
					<span class="panel-title">Lorem ipsum dolor sit amet, consectetur..</span>
					<span class="panel-subtitle">346,112 views</span>
				</div>
				<div class="panel">
					<img class="panel-img" src="https://via.placeholder.com/200x150">
					<span class="panel-title">Lorem ipsum dolor sit amet, consectetur..</span>
					<span class="panel-subtitle">346,112 views</span>
				</div>
				<div class="panel">
					<img class="panel-img" src="https://via.placeholder.com/200x150">
					<span class="panel-title">Lorem ipsum dolor sit amet, consectetur..</span>
					<span class="panel-subtitle">346,112 views</span>
				</div>
				<div class="panel">
					<img class="panel-img" src="https://via.placeholder.com/200x150">
					<span class="panel-title">Lorem ipsum dolor sit amet, consectetur..</span>
					<span class="panel-subtitle">346,112 views</span>
				</div>
			</article>
		</div>
	</body>
</html>

D:\Tiah\Toan\VPN\style.css

*, *:before, *:after {
  box-sizing: border-box;
}
body {
  background-color: #fff;
  color: #444;
}
h1, p {
  margin: 0 0 1em 0;
}
.wrapper {
  margin: 0 auto;
  display: grid;
  grid-template-columns: 15% 85%;
  grid-gap: 16px;
}
.wrapper > * {
  background-color: #fafafa;
  color: #242424;
  border-radius: 5px;
  font-size: 16px;
  margin-bottom: 10px;
}
.header {
  padding: 24px;
}
.header, .footer {
  grid-column: 1 / -1;
  clear: both;
}
.content {
  padding-right: 40px;
  padding-left: 40px;
  display: grid;
  margin: 0 auto;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  grid-auto-rows: minmax(150px, auto);
  grid-gap: 8px;
}
.panel {
  margin-left: 5px;
  margin-right: 5px;
}
.panel-img {
  width: 100%;
  height: 80%;
}
.panel-title {
  font-size: 14px;
  display: block;
}
.panel-subtitle {
  font-size: 12px;
  color: #8888888;
}
@media (max-width: 1200px) {
  .wrapper {
    grid-template-columns: 2fr;
  }
  .sidebar {
    display: none;
  } 
  .content {
    width: 100%;
    grid-template-columns: repeat(auto-fill, minmax(200px, 2fr));
    grid-auto-rows: minmax(150px, auto);
  }
}
@media (max-width: 768px) {
  .content {
    padding-right: 48px;
    padding-left: 48px;
    width: 100%;
    grid-template-columns: repeat(3, minmax(200px, 3fr));
    grid-auto-rows: minmax(150px, auto);
  }
}
@media (max-width: 700px) {
  .content {
    padding-right: 116px;
    padding-left: 116px;
    width: 100%;
    grid-template-columns: repeat(2, minmax(200px, 2fr));
    grid-auto-rows: minmax(150px, auto);
  }
}
@supports (display: grid) {
  .wrapper > * {
    width: auto;
    margin: 0;
  }
}

3. Xây dựng layout Pinterest bằng CSS Grid

D:\Tiah\Toan\VPN\index.html

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<title>Document</title>
		<link rel="stylesheet" type="text/css" href="style.css">
	</head>
	<body>
		<div class="wrapper">
			<header class="header">Pinterest</header>
			<article class="content">
				<div class="panel tall-panel">
					<img class="panel-img" src="https://i.pinimg.com/564x/bf/24/7b/bf247b7bdf016e38a0a507de0f5fabf9.jpg" />
				</div>
				<div class="panel">
					<img class="panel-img" src="https://i.pinimg.com/564x/fd/9a/1e/fd9a1e674ef0690532d77e9842e5ec09.jpg" />
				</div>
				<div class="panel">
					<img class="panel-img" src="https://i.pinimg.com/564x/fd/9a/1e/fd9a1e674ef0690532d77e9842e5ec09.jpg" />
				</div>
				<div class="panel">
					<img class="panel-img" src="https://i.pinimg.com/564x/fd/9a/1e/fd9a1e674ef0690532d77e9842e5ec09.jpg" />
				</div>
				<div class="panel tall-panel">
					<img class="panel-img" src="https://i.pinimg.com/564x/65/cd/8f/65cd8fc3a0b31bdc5c48b9ce09224d22.jpg" />
				</div>
				<div class="panel">
					<img class="panel-img" src="https://i.pinimg.com/564x/fd/9a/1e/fd9a1e674ef0690532d77e9842e5ec09.jpg" />
				</div>
				<div class="panel">
					<img class="panel-img" src="https://i.pinimg.com/564x/fd/9a/1e/fd9a1e674ef0690532d77e9842e5ec09.jpg" />
				</div>
				<div class="panel">
					<img class="panel-img" src="https://i.pinimg.com/564x/fd/9a/1e/fd9a1e674ef0690532d77e9842e5ec09.jpg" />
				</div>
				<div class="panel tall-panel">
					<img class="panel-img" src="https://i.pinimg.com/564x/bf/24/7b/bf247b7bdf016e38a0a507de0f5fabf9.jpg" />
				</div>
				<div class="panel">
					<img class="panel-img" src="https://i.pinimg.com/564x/fd/9a/1e/fd9a1e674ef0690532d77e9842e5ec09.jpg" />
				</div>
				<div class="panel">
					<img class="panel-img" src="https://i.pinimg.com/564x/fd/9a/1e/fd9a1e674ef0690532d77e9842e5ec09.jpg" />
				</div>
				<div class="panel">
					<img class="panel-img" src="https://i.pinimg.com/564x/fd/9a/1e/fd9a1e674ef0690532d77e9842e5ec09.jpg" />
				</div>
				<div class="panel">
					<img class="panel-img" src="https://i.pinimg.com/564x/fd/9a/1e/fd9a1e674ef0690532d77e9842e5ec09.jpg" />
				</div>
				<div class="panel">
					<img class="panel-img" src="https://i.pinimg.com/564x/fd/9a/1e/fd9a1e674ef0690532d77e9842e5ec09.jpg" />
				</div>
				<div class="panel">
					<img class="panel-img" src="https://i.pinimg.com/564x/fd/9a/1e/fd9a1e674ef0690532d77e9842e5ec09.jpg" />
				</div>
				<div class="panel">
					<img class="panel-img" src="https://i.pinimg.com/564x/fd/9a/1e/fd9a1e674ef0690532d77e9842e5ec09.jpg" />
				</div>
				<div class="panel">
					<img class="panel-img" src="https://i.pinimg.com/564x/fd/9a/1e/fd9a1e674ef0690532d77e9842e5ec09.jpg" />
				</div>
				<div class="panel">
					<img class="panel-img" src="https://i.pinimg.com/564x/fd/9a/1e/fd9a1e674ef0690532d77e9842e5ec09.jpg" />
				</div>
				<div class="panel">
					<img class="panel-img" src="https://i.pinimg.com/564x/fd/9a/1e/fd9a1e674ef0690532d77e9842e5ec09.jpg" />
				</div>
				<div class="panel">
					<img class="panel-img" src="https://i.pinimg.com/564x/fd/9a/1e/fd9a1e674ef0690532d77e9842e5ec09.jpg" />
				</div>
				<div class="panel">
					<img class="panel-img" src="https://i.pinimg.com/564x/fd/9a/1e/fd9a1e674ef0690532d77e9842e5ec09.jpg" />
				</div>
			</article>
		</div>
	</body>
</html>

D:\Tiah\Toan\VPN\style.css

*, *:before, *:after {
  box-sizing: border-box;
}
body {
  font-family: Courier, 'sans-serif';
  background-color: #fff;
  color: #242424;
}
h1, p {
  margin: 0 0 1em 0;
}
.wrapper {
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr;
  grid-gap: 16px;
}
.wrapper > * {
  background-color: #fafafa;
  color: #242424;
  border-radius: 5px;
  font-size: 16px;
  margin-bottom: 10px;
}
.header {
  padding: 24px;
}
.header, .footer {
  grid-column: 1 / -1;
  clear: both;
}
.content {
  padding-right: 40px;
  padding-left: 40px;
  display: grid;
  margin: 0 auto;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  grid-auto-rows: minmax(200px, auto);
  grid-gap: 16px;
}
.panel {
  margin-left: 5px;
  margin-right: 5px;
}
.panel-img {
  width: 100%;
  height: 80%;
}
.tall-panel {
  grid-row-end: span 2;
}
@media (max-width: 1200px) { 
  .content {
    padding-right: 72px;
    padding-left: 72px;
    width: 100%;
    grid-template-columns: repeat(3, minmax(220px, 1fr) ) ;
    grid-auto-rows: minmax(200px, auto);
  }  
}
@supports (display: grid) {
  .wrapper > * {
    width: auto;
    margin: 0;
  }
}

4. Build a Responsive Grid CSS Website Layout From Scratch

D:\Tiah\Toan\VPN\index.html

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<title>Document</title>
		<link rel="stylesheet" type="text/css" href="style.css">
	</head>
	<body>
		<div class="wrapper">
			<!-- Navigation -->
			<nav class="main-nav">
				<ul>
					<li>
						<a href="#">Home</a>
					</li>
					<li>
						<a href="#">About</a>
					</li>
					<li>
						<a href="#">Services</a>
					</li>
					<li>
						<a href="#">Contact</a>
					</li>
				</ul>
			</nav>
			<!-- Top Container -->
			<section class="top-container">
				<header class="showcase">
					<h1>Your Web Presence</h1>
					<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Modi, ipsam! Nihil quo minima nulla atque!</p>
					<a href="#" class="btn">Read More</a>
				</header>
				<div class="top-box top-box-a">
					<h4>Membership</h4>
					<p class="price">$199/mo</p>
					<a href="" class="btn">Buy Now</a>
				</div>
				<div class="top-box top-box-b">
					<h4>Pro Membership</h4>
					<p class="price">$299/mo</p>
					<a href="" class="btn">Buy Now</a>
				</div>
			</section>
			<!-- Boxes Section -->
			<section class="boxes">
				<div class="box">
					<i class="fas fa-chart-pie fa-4x"></i>
					<h3>Analytics</h3>
					<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quasi, expedita?</p>
				</div>
				<div class="box">
					<i class="fas fa-globe fa-4x"></i>
					<h3>Marketing</h3>
					<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quasi, expedita?</p>
				</div>
				<div class="box">
					<i class="fas fa-cog fa-4x"></i>
					<h3>Development</h3>
					<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quasi, expedita?</p>
				</div>
				<div class="box">
					<i class="fas fa-users fa-4x"></i>
					<h3>Support</h3>
					<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quasi, expedita?</p>
				</div>
			</section>
			<!-- Info Section -->
			<section class="info">
				<img src="https://image.ibb.co/j4Qz8x/pic1.jpg" alt="">
				<div>
					<h2>Your Business On The Web</h2>
					<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Vitae alias reiciendis deleniti possimus nemo non repellendus? Quae atque vero modi quidem! Autem cupiditate fugit doloribus ad amet, asperiores provident commodi.</p>
					<a href="#" class="btn">Learn More</a>
				</div>
			</section>
			<!-- Portfolio -->
			<section class="portfolio">
				<img src="https://source.unsplash.com/random/200x200" alt="">
				<img src="https://source.unsplash.com/random/201x200" alt="">
				<img src="https://source.unsplash.com/random/202x200" alt="">
				<img src="https://source.unsplash.com/random/203x200" alt="">
				<img src="https://source.unsplash.com/random/204x200" alt="">
				<img src="https://source.unsplash.com/random/205x200" alt="">
				<img src="https://source.unsplash.com/random/206x200" alt="">
				<img src="https://source.unsplash.com/random/207x200" alt="">
				<img src="https://source.unsplash.com/random/208x200" alt="">
			</section>
			<!-- Footer -->
			<footer>
				<p>GridBiz &copy; 2018</p>
			</footer>
		</div>
		<!-- Wrapper Ends -->
	</body>
</html>

D:\Tiah\Toan\VPN\style.css

/* CSS Variables */
:root {
  --primary: #ddd;
  --dark: #333;
  --light: #fff;
  --shadow: 0 1px 5px rgba(104, 104, 104, 0.8);
}
html {
  box-sizing: border-box;
  font-family: Arial, Helvetica, sans-serif;
  color: var(--dark);
}
body {
  background: #ccc;
  margin: 30px 50px;
  line-height: 1.4;
}
.btn {
  background: var(--dark);
  color: var(--light);
  padding: 0.6rem 1.3rem;
  text-decoration: none;
  border: 0;
}
img {
  max-width: 100%;
}
.wrapper {
  display: grid;
  grid-gap: 20px;
}
/* Navigation */
.main-nav ul {
  display: grid;
  grid-gap: 20px;
  padding: 0;
  list-style: none;
  grid-template-columns: repeat(4, 1fr);
}
.main-nav a {
  background: var(--primary);
  display: block;
  text-decoration: none;
  padding: 0.8rem;
  text-align: center;
  color: var(--dark);
  text-transform: uppercase;
  font-size: 1.1rem;
  box-shadow: var(--shadow);
}
.main-nav a:hover {
  background: var(--dark);
  color: var(--light);
}
/* Top Container */
.top-container {
  display: grid;
  grid-gap: 20px;
  grid-template-areas:
    'showcase showcase top-box-a'
    'showcase showcase top-box-b';
}
/* Showcase */
.showcase {
  grid-area: showcase;
  min-height: 400px;
  background: url(https://image.ibb.co/kYJK8x/showcase.jpg);
  background-size: cover;
  background-position: center;
  padding: 3rem;
  display: flex;
  flex-direction: column;
  align-items: start;
  justify-content: center;
  box-shadow: var(--shadow);
}
.showcase h1 {
  font-size: 4rem;
  margin-bottom: 0;
  color: var(--light);
}
.showcase p {
  font-size: 1.3rem;
  margin-top: 0;
  color: var(--light);
}
/* Top Box */
.top-box {
  background: var(--primary);
  display: grid;
  align-items: center;
  justify-items: center;
  box-shadow: var(--shadow);
  padding: 1.5rem;
}
.top-box .price {
  font-size: 2.5rem;
}
.top-box-a {
  grid-area: top-box-a;
}
.top-box-b {
  grid-area: top-box-b;
}
/* Boxes */
.boxes {
  display: grid;
  grid-gap: 20px;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
.box {
  background: var(--primary);
  text-align: center;
  padding: 1.5rem 2rem;
  box-shadow: var(--shadow);
}
/* Info */
.info {
  background: var(--primary);
  box-shadow: var(--shadow);
  display: grid;
  grid-gap: 30px;
  grid-template-columns: repeat(2, 1fr);
  padding: 3rem;
}
/* Portfolio */
.portfolio {
  display: grid;
  grid-gap: 20px;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
.portfolio img {
  width: 100%;
  box-shadow: var(--shadow);
}
/* Footer */
footer {
  margin-top: 2rem;
  background: var(--dark);
  color: var(--light);
  text-align: center;
  padding: 1rem;
}
/* Media Queries */
@media (max-width: 700px) {
  .top-container {
    grid-template-areas:
      'showcase showcase'
      'top-box-a top-box-b';
  }
  .showcase h1 {
    font-size: 2.5rem;
  }
  .main-nav ul {
    grid-template-columns: 1fr;
  }
  .info {
    grid-template-columns: 1fr;
  }
  .info .btn {
    display: block;
    text-align: center;
    margin: auto;
  }
}
@media (max-width: 500px) {
  .top-container {
    grid-template-areas:
      'showcase'
      'top-box-a'
      'top-box-b';
  }
}

5. Web Layouts – How to Use CSS Grid and Flex to Create a Responsive Web Page

D:\Tiah\Toan\VPN\index.html

<!DOCTYPE html>
<html lang="en">

	<head>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<title>Document</title>
		<link rel="stylesheet" type="text/css" href="style.css">
	</head>

	<body>
		<nav>
			<div class="logos-section">
				<h2 class="logo">snap</h2>
				<ul class="menu-items">
					<li> Features<svg width="10" height="6" xmlns="http://www.w3.org/2000/svg">
							<path stroke="#686868" stroke-width="1.5" fill="none" d="m1 1 4 4 4-4" />
						</svg>
					</li>
					<li> Company<svg width="10" height="6" xmlns="http://www.w3.org/2000/svg">
							<path stroke="#686868" stroke-width="1.5" fill="none" d="m1 1 4 4 4-4" />
						</svg>
					</li>
					<li>Careers</li>
					<li>About</li>
				</ul>
			</div>
			<ul class="cta-btns">
				<li>Login</li>
				<li>Register</li>
			</ul>
			<p class="mobile-nav">🌚</p>
		</nav>
		<main>
			<section id="text-side">
				<h1>Make <br />remote work</h1>
				<p> Get your team in sync, no matter your location. Streamline processes, create team rituals, and watch productivity soar. </p>
				<button>Learn more</button>
				<div class="clients-logos">
					<img src="https://i.postimg.cc/gJ9Y84m6/client-databiz.png" />
					<img src="https://i.postimg.cc/15DDqYSD/client-audiophile.png" />
					<img src="https://i.postimg.cc/5ybQqfbv/client-meet.png" />
					<img src="https://i.postimg.cc/g2NsxByN/client-maker.png" />
				</div>
			</section>
			<section id="img-side">
				<img class="desktop-img" src="https://i.postimg.cc/0Nt97Bhf/image-hero-desktop.png" />
				<img class="mobile-img" src="https://i.postimg.cc/ZnYfhwwW/image-hero-mobile.png" />
			</section>
		</main>
		<div class="attribution"> Challenge by <a href="https://www.frontendmentor.io?ref=challenge" target="_blank">Frontend Mentor</a>. Coded by <a href="https://codehemaa.com">Ophy Boamah</a>. </div>
	</body>

</html>

D:\Tiah\Toan\VPN\style.css

* {
  font-family: "Epilogue", sans-serif;
  font-size: 1.3rem;
}

.logo {
  font-size: 1.3rem;
}

li {
  list-style: none;
}

nav,
.cta-btns,
.menu-items {
  display: flex;
  align-items: center;
}

nav {
  margin: 0 1.5rem 1.5rem 1.5rem;
  justify-content: space-between;
}

.mobile-nav {
    display: none;
}

.logos-section {
  display: flex;
}

.menu-items li,
.cta-btns li {
  font-size: 0.7rem;
  margin-right: 1rem;
  color: hsl(0, 0%, 41%);
}

.cta-btns li:nth-last-child(1) {
  border: 1px solid gray;
  padding: 0.2rem 0.7rem;
  border-radius: 0.3rem;
}

/* Client Logos */
  
.clients-logos img {
  width: 8rem;
  margin-right: -3rem;
}

.clients-logos {
  margin-top: 1rem;
  margin-left: -2rem;
  display: flex;
  width: 10rem;
}

.clients-logos img:nth-child(2) {
  width: 7rem;
}

/* Main */
main {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  height: 70vh;
  align-items: center;
  justify-content: center;
  margin-left: 8rem;
}
/* Images */
.desktop-img {
  display: block;
}
.mobile-img {
  display: none;
}

main h1 {
  font-size: 3rem;
}

main p {
  font-size: 0.7rem;
  width: 18rem;
  color: hsl(0, 0%, 41%);
  line-height: 0.9rem;
}

main button {
  background-color: hsl(0, 0%, 8%);
  color: #fff;
  border: none;
  font-size: 0.7rem;
  padding: 0.6rem 1rem;
  border-radius: 0.4rem;
  margin-top: 1rem;
}

#text-side {
  margin-top: 3rem;
}
/* Hero Image */
#img-side img {
  width: 20rem;
}

.attribution {
  font-size: 0.7rem;
  text-align: center;
  margin-top: 5.5rem;
}

.attribution a {
  color: hsl(228, 45%, 44%);
  font-size: 0.7rem;
}

/* Responsive */
@media (min-width: 300px) and (max-width: 480px) {
  * {
    font-size: 1rem;
  }

  body {
    height: 100vh;
    width: 100vw;
    overflow-y: hidden;
    overflow-x: hidden;
  }

  nav {
    margin: 0 1.5rem 0 1.5rem;
  }

  nav ul {
    display: none;
  }
  
  .mobile-nav {
    display: block;
    margin-right: 2rem;
  }

  main {
    display: grid;
    grid-template-columns: 100%;
    margin: -3rem auto 0 auto;
  }

  /* Clients logos */
  .clients-logos {
    margin-top: 2rem;
  }
  
  .clients-logos img {
  width: 30rem;
}

.clients-logos {
  margin-top: 1rem;
  display: flex;
}

.clients-logos img:nth-child(2) {
  width: 7rem;
}

  /* Images */
  .desktop-img {
    display: none;
  }
  .mobile-img {
    display: block;
    margin-top: 3rem;
  }

  .cta-btns,
  .menu-items {
    display: none;
  }

  main h1 {
    font-size: 2.5rem;
  }

  /* Client Logos */
  .clients-logos img {
    width: 4.5rem;
    margin-right: 0.8rem;
  }

  .attribution {
    width: 13rem;
    margin: 10rem auto 0 auto;
    text-align: center;
  }
}

Web Layouts – How to Use CSS Grid and Flex to Create a Responsive Web Page

Your web layout is to your website what a floor plan is to a building. Without them, you’re just building castles in the air.

The first thing to do when you have a website or application to build or design is to decide on the layout. This is important because it is within this layout that you specify how elements are arranged so that you can assess them in their intended manner and hierarchy.

Basically, the aim of every web layout is to reduce confusion, enhance usability and to ultimately give your users an enjoyable experience. Some of the main elements of a layout are navigation, menus and content.

In web and front-end development, having a layout in mind ahead of building can help you decide on what CSS layout module to use: Flexbox or Grid.

In this article, we’re going to learn what each of these tools are and the best way to use them by building a simple yet beautiful landing page.

What We're Going To Build

Check it out on Codepen here.

Project Functionality

  1. Web Layout: Create a beautiful landing page

  2. Mobile Responsiveness

Prerequisites

  • Basic knowledge of HTML and CSS.

  • An IDE (text editor) like VS Code

  • A web browser

Setup

  1. Create a folder for your project and open in an IDE.

  2. Within your project folder, create index.html and style.css files.

  3. Create an asset folder to store images.

  4. Within your index.html file, create your HTML boilerplate and link your CSS file and font URL within the <head> tag.

Resources

How to Use Flexbox

Generally, HTML elements align according to their default display style. This means, without external styling with CSS, block elements like p and div will start on a new line. Inline elements like input and span, on the other hand, are arranged next to each other on the same line.

However, the concept of Flexbox allows you to easily place these elements either horizontally or vertically in what’s often referred to as one dimension. In order to achieve this, at least two elements are required: flex container and flex item. These refer to a parent and child element, respectively.

In responsive design, the purpose of Flexbox is to allow containers and their child elements to fill defined spaces or shrink depending on a device’s dimensions.

Flex-direction and Axes

Flex-direction is an important property of CSS Flexbox, because it is what determines the direction that flex items are arranged in. It does this by pointing out the main axis of a flex container.

There are two main axes, namely main axis and cross axis. The main axis is the defined direction of how your flex items are placed in the flex container, whilst the cross axis is always the axis at the opposite side of the main axis.

It can be dangerous to try using the concept of x and y axis from math to understand this. This is mainly because in Flexbox the main axis can be vertical or horizontal, always depending on the value of the flex-direction.

The values accepted by the flex-direction property include row (which is default), row-reverse, column, and column-reverse. For the purposes of this project, we’re going to look at row and column.

flexdirection
flex-direction: row

When the flex-direction attribute has a value of row, the main axis is horizontal and the cross axis is vertical, as shown in the image above. This means flex items will be arranged horizontally.

Since the row is the default value, if you display a container as flex but don't specify the flex-direction, the flex items will automatically be in a row.

flexdirectioncolumn
flex-direction: column

When the flex-direction attribute has a value of column, the main axis is vertical and the cross axis is horizontal, as shown in the image above. This means flex items will be arranged vertically.

How to Build the Navbar

Now that we know how Flexbox works, let’s start building our navbar. We'll first provide the content within it, that is the menu items and logo. We’ll give them descriptive classes so that we can easily reference them within our CSS file.

<nav>
      <h2 class="logo">snap</h2>
      <ul class="menu-items">
        <li>Features</li>
        <li>Company</li>
        <li>Careers</li>
        <li>About</li>
      </ul>
      <ul class="cta-btns">
        <li>Login</li>
        <li>Register</li>
      </ul>
</nav>

The image below is the output for the code above. Because both <ul> and <li> are block elements, each of the items we specified within them will be displayed on a new line.

preflexx-1
Navbar content output

Flexbox layout display is declared on parent containers and affects child elements. This means that if you had a list of groceries in an unordered list, display flex can’t be applied on the <li>s which are child elements in this case. Instead, to display them as flex, you’d first have to create a parent container and apply it to that.

In our CSS code below, we're defining the font style and size for our project as well as our navbar logo. We're also displaying our nav elements and some of the elements within those as flex.

The image below is the output for the code above. The elements have been displayed as flex. Yet because we didn't specify the flex-direction, they're automatically arranged in a row.

But as you can see below using the ruler (red line), the flex items are not aligned as they should be. Let's fix that by learning another important flex element.

How to use the align-items attribute

This is a Flexbox attribute that controls the arrangement of flex items on the cross axis. The values it takes are flex-start, flex-end and center depending on the element's alignment needs. The image below shows how each of them works.

From the image above, we can see that if we want to ensure that the flex items within our <nav> are aligned properly, on that element we must give the align-items attribute a value of center. So we have to add an attribute of align-items and a value of center to our flex container as shown in the CSS code below:

As you can see in the image below, the flex items are now aligned as they should be.

But once again there is something missing. We want to have our items spread out properly on the navbar: the logo on the extreme left, login and register at the extreme right, and the rest in the middle.

We can achieve this with the justify-content attribute. Let's learn about it next and then implement it.

How to use the justify-content attribute

This is a Flexbox attribute that controls the arrangement of flex items on the main axis. It also defines how browsers distribute space between and around flex items within a flex container.

To achieve responsiveness, it helps with allocating any excess space that is leftover after flex-items have been arranged.

From the styles associated with the various values of the justify-content attribute, we can see that the bottom two are more similar to what we're trying to achieve.

We can either go for the space around or the space-between and provide some padding on the sides to push the items on the extreme ends from the edges. We also give the list-syle attribute a value of none to remove the dots in front of the list items.

Now that we have the items placed at their desired positions, we need to create slight spaces between them. In this case, we're going to give each list item a margin-right of 1rem. We also set other styles like size of fonts, color and a border for the register item.

After implementing the above code, this is the final look of our navbar. And this marks the end of our Flexbox section. Next, we'll build the final part of our landing page with CSS Grid.

How to Use CSS Grid

CSS Grid is a life-changing tool for creating web layouts. It helps you make both simple and complex layouts. The main difference is that while Flexbox helps with one dimensional arrangement of elements, CSS grid is able to do two dimensional arrangements.

The concept of axes we learnt about under Flexbox still applies here. You can use CSS Grid to arrange elements on the main axis and cross axis at the same time.

In summary, Flexbox, allows you to either arrange elements horizontally (in a row) or vertically (in a column). But with CSS Grid you can align elements both vertically and horizontally.

The CSS Grid layout is declared only on parent elements or containers. In effect, all its children become grid items. Once you have the target container, you give it an attribute of display and value of grid. The size of a grid’s row and column can be determined with grid-template-rows and grid-template-columns, respectively.

How to Build the Homepage

Just like we did with the navbar, let's start by defining our content within a <main> section in our HTML file.

Looking at our target image, we have two main sections: the left section will have text and logos whilst the right section has a hero image. That’s for the web view of our project.

Let's start by defining our content. The section with class text-side contains: heading, paragraph text, button and logo. The section with class img-side only contains an image.

Within the main section, we created the two sections we needed and gave them descriptive id's: text-side and img-side.

Within the text-side, we added a heading, paragraph text, button and a div to display clients' logos. The only thing we need for the img-side is the display image.

Within our CSS file, we need to style the client logos div as well as the child elements. We also set a font-size for the heading and paragraph. Next, we style our button and assign a width to our image.

The image above shows how our web page will look after defining the content and styling just the heading, button and logos – that is, we haven't declared our container as a grid yet. Because almost all the elements we have here are block elements, we see them align on top of one another.

Grid Template Rows and Columns

The grid-template-columns property specifies the number and widths of columns in a grid, defining a grid container's column by specifying the size of its tracks and line names.

The grid-template-rows property is the direct opposite. It specifies the number and heights of rows in a grid, also defining a grid container's row by specifying the size of its tracks and line names.

As you can see in the image below, grid-template-rows arranges elements from the top to bottom of the device screen. grid-template-columns arranges elements from the left to right side of the device screen.

For our project, we're going to make use of grid-template-columns since we want to arrange our two sections side by side, letting each section occupy an equal part of the overall project width. We do this by assigning it as an attribute on the same container that we specified a display of grid on.

Now that the two sections inside our <main> tag have been placed equally using the grid-template-columns, we have two last things to do.

We need to align them horizontally, by positioning both elements in the center of the page, with the extra space on the left of the image, evenly distributed on both sides. We also need to align them vertically by positioning both of them in the center of the page, with the extra space on the bottom, evenly distributed above and beneath.

Align and Justify in CSS Grid

Good news – we don't have to learn any new concepts to achieve our desired alignments in CSS Grid Layouts. Because fortunately, align-items and justify-content, as we learnt earlier, are not exclusive to Flebox. You can also use them to position items both horizontally and vertically.

As you can see in the code above, we only had to give the value of center to both align-items and justify-content attributes on the parent tag (grid container).

To ensure that we see the effect of position in the perfect center, we also had to specify a height for the section. The image below is the final output of our project.

How to Make it Responsive

So far, everything we've built is for the web. But for the sake of users who want to access the landing page on mobile, we have to make our project accessible on smaller screens. In our case, we're looking at screens that are greater than 300px but less than 480px.

As you can see in the code below, we're hiding our nav items and displaying an emoji with class of mobile-nav. Beside that, we're hiding the desktop header image and showing the mobile header image.

Full Project Code

This is the project we’ve built together in this article:

Here's the full HTML code:

Here's the full CSS code:

Conclusion

As a web developer, layouts should be the first thing you consider before writing code. Thankfully, CSS Grid and Flexbox have revolutionized the way we structure and build website and web app layouts.

This makes these concepts a must know so you can specify the arrangement of elements on the web. We've discussed the fundamentals, so that you can easily build up on the knowledge and create beautiful web pages and apps.

Thanks for reading 👋🏾. I hope you found this helpful.

Last updated