Recreating YouTube Using HTML and CSS
Tags: html, css, webdev, tutorial
Published: 2023-12-21 11:15:54

So far, we have covered the basics of [HTML and CSS](https://www.ericsdevblog.com/courses/html-css/), discussed different techniques that allow you to position elements in a webpage, and explored the concept of responsive design, which enables you to create webpages that automatically adapt to different screen sizes. In this chapter, we will put everything we have learned so far together to recreate YouTube using only HTML and CSS.

▶️ [YouTube Demo](https://www.ericsdevblog.com/courses/html-css/6/images/youtube.gif)

> 📧 Subscribe to my newsletter: https://ericsdevblog.ck.page/profile

## Creating the page layout

Let's start by discussing the basic page layout. We will follow the mobile-first rule and start from the small screen. On a small screen, there should be a top navigation bar and a content section. The navigation bar has the logo on the left and some buttons on the right. The content section should include several card components showing individual videos.

![page layout on small screen](https://www.ericsdevblog.com/courses/html-css/6/images/layout-sm.excalidraw.png)

On a medium screen (`>= 640px`), more icons should be displayed in the navigation bar. We will skip this step for now and revisit this topic when we start building the navigation menu.

On a large screen (`>= 768px`), the page should have a small sidebar. The navigation bar should display a search box at the center instead of just an icon. The content section should also be multi-column.

![page layout on large screen](https://www.ericsdevblog.com/courses/html-css/6/images/layout-lg.excalidraw.png)

And lastly, on an x-large screen (`>= 1024px`), the webpage should have a full-sized sidebar, a fully expanded navigation bar with all the icons and search boxes, and the content section should have more columns.

![page layout on x-large screen](https://www.ericsdevblog.com/courses/html-css/6/images/layout-xlg.excalidraw.png)

### The HTML document

Now, let's see if you can construct this layout. We'll start with the HTML document. We will start with the navigation bar:

```html
<header>
  <nav>
    <div class="start">
      <div>Button</div>
      <div>Logo</div>
    </div>
    <div class="center">
      <div>Search</div>
      <div>Microphone</div>
    </div>
    <div class="end">
      <div>Button</div>
      <div>Button</div>
      <div>Button</div>
    </div>
  </nav>
</header>
```

And then the sidebars:

```html
<main>
  <aside class="sidebar-sm">Small sidebar</aside>
  <aside class="sidebar-full">Full sidebar</aside>
  . . .
</main>
```

There should also be a content section inside the `<main>` element:

```html
<section class="content">
  <section class="video">
    <div class="video-thumbnail">
      <img src="video_thumbnail1.jpg" alt="Video Thumbnail" />
    </div>
    <div class="video-info">
      <img src="channel1.jpg" alt="Channel Logo" />
      <div>
        <h2>Video Title 1</h2>
        <p>Channel Name</p>
        <p>1M views • 1 day ago</p>
      </div>
    </div>
  </section>
  . . .
</section>
```

Remember your HTML should have all the components required for all screen sizes. If an element is not required for a certain screen, you can remove it by setting `display` to `none`.

This example contains a navigation bar, defined by the `<nav>` element. The navigation bar has three sections, `start`, `center`, and `end`. The class names correspond to their respective positions in the navigation bar. This layout can be created with a flexbox, and the `justify-content` property should be set to `space-between`. The `center` section should be removed until the screen is big enough.

The `<main>` section has two sidebars, a small sidebar (`sidebar-sm`) and a full-sized sidebar (`sidebar-full`). The small sidebar should be displayed on large screens, and the full-sized sidebar should be displayed only on x-large screens.

Lastly, for the `content` section, you can use a CSS grid with the [responsive-layout-without-breakpoint technique](/courses/html-css/5/#responsive-layouts-without-media-queries) we discussed in the previous chapter. For now, we are not going to worry about how the card components are created.

Now we can move on to the CSS file. Let's remove the default margins and paddings and set [the `box-sizing` property](/courses/html-css/3/#box-sizing) to `border-box`. You can also add a border to each section to make their respective positions more clear.

```css
* {
  box-sizing: border-box;
  padding: 0px;
  margin: 0px;
}

nav,
.sidebar-sm,
.sidebar-full,
.content {
  border: black solid 2px;
}
```

### Navbar layout

Next, the navigation bar should be a [flexbox](/courses/html-css/4/#flexbox-layout) with its direction set to `row`, and `justify-content` set to `space-between`, so that each subsection has equal spaces between each other. The subsections should also be row flexboxes so that the logo and icons are also placed horizontally. However, since we are starting from the small screen, the `center` section should be removed (`display: none;`) for now.

```css
nav {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
}

.start {
  display: flex;
  flex-direction: row;
}

.center {
  display: none; /* Not displayed on small screens */
}

.end {
  display: flex;
  flex-direction: row;
}
```

For large screens, the `center` section should be designed just like its siblings.

```css
/* Large screen */
@media screen and (min-width: 768px) {
  .center {
    display: flex;
    flex-direction: row;
  }
}
```

### Sidebars

Next, the `<main>` section should be a row flexbox, or a grid with two columns, so that the sidebar and the content are on the same row.

```css
main {
  display: flex;
  flex-direction: row;
}
```

The sidebars are removed on small screens.

```css
.sidebar-sm {
  display: none;
}

.sidebar-full {
  display: none;
}
```

The small sidebar is displayed on large screens. By setting `flex` to `0`, you make sure the sidebar has a fixed size and only the content section changes as the viewport changes.

```css
/* Large screen */

@media screen and (min-width: 768px) {
  .center {
    display: flex;
    flex-direction: row;
  }

  .sidebar-sm {
    display: flex;
    flex-direction: column;

    flex: 0;
  }
}
```

The full-sized sidebar is displayed on x-large screens, and the small sidebar will be removed.

```css
/* X-Large screen */

@media screen and (min-width: 1024px) {
  .sidebar-sm {
    display: none;
  }

  .sidebar-full {
    display: flex;
    flex-direction: column;

    flex: 0;
  }
}
```

### The content section

Lastly, for the content section:

```css
.content {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(20em, 1fr));
  grid-gap: 1em;

  flex: 1;
}

.video {
  border: red solid 2px;
  width: 100%;
}
```

For now, we'll set the maximum width of a video card to be `20em`. This is how this layout looks like as the viewport changes:

▶️ [YouTube layout](https://www.ericsdevblog.com/courses/html-css/6/images/youtube-page-layout.gif)

## Building the navigation bar

Next, let's focus on the navigation bar. The `start` section has a menu icon and a logo. The `center` section includes a search form and a search icon. Lastly, the `end` section contains several icons and a profile photo. In order to make this example shorter, I left out the actual icon elements, defined by `<svg>`, but you can copy these resources from YouTube directly.

You can also purchase my E-book: "[HTML & CSS: A Practical Guide](https://ericsdevblog.ck.page/products/html-css-a-practical-guide)", which includes the complete source code for this chapter.

```html
<nav>
  <div class="start">
    <div class="menu-icon">. . .</div>
    <img src="images/logo.png" alt="YouTube Logo" />
  </div>
  <div class="center">
    <form action="/">
      <input type="text" placeholder="Search" />
      <button>
        <div class="search-form-icon">. . .</div>
      </button>
    </form>
    <div class="mic-icon-center">. . .</div>
  </div>
  <div class="end">
    <div class="search-icon">. . .</div>
    <div class="mic-icon">. . .</div>
    <div class="camera-icon">. . .</div>
    <div class="notification-icon">. . .</div>
    <img src="images/profile.jpg" alt="Profile Image" />
  </div>
</nav>
```

First of all, all the icons should have a unified style. They should be rounded and have equal paddings. The icons should also have a background when the cursor is hovered on top.

```css
.menu-icon,
.search-icon,
.mic-icon,
.mic-icon-center,
.camera-icon,
.notification-icon {
  border-radius: 100%;
  padding: 10px;
}

svg {
  display: block;
  width: 100%;
  height: 100%;
}

.menu-icon:hover,
.search-icon:hover,
.mic-icon:hover,
.mic-icon-center:hover,
.camera-icon:hover,
.notification-icon:hover {
  background-color: #e5e5e5;
}
```

![icon style](https://www.ericsdevblog.com/courses/html-css/6/images/icon-style.png)

On a small screen, most of these icons should be removed, as the horizontal space on a mobile device is very valuable. In this case, we'll only keep the logo, the search icon, and the profile picture. All the other elements will be removed.

![navbar small screen](https://www.ericsdevblog.com/courses/html-css/6/images/nav-sm.png)

```css
.menu-icon,
.mic-icon,
.mic-icon-center,
.camera-icon,
.notification-icon {
  display: none;
}
```

And then, style the `start`, `center` and `end` sections of the navbar.

```css
/* Navbar start section */

.start {
  display: flex;
  flex-direction: row;
  flex: 1;

  gap: 10px;
  padding: 8px;
  align-items: center;
}

.start > img {
  width: 90px;
}

/* Navbar center section */

.center {
  display: none;
  flex: 2;
}

/* Navbar end section */

.end {
  display: flex;
  flex-direction: row;

  padding: 8px;
  align-items: center;
  justify-content: end;
  flex: 1;
}

.end > img {
  width: 40px;
  border-radius: 100%;
  object-fit: cover;
  margin-left: 10px;
}
```

`start` and `end` will have equal size, and `center` will grow faster than its siblings as the viewport grows. `center` will be removed on a small screen, so for now, there are only `start` and `end`.

On a medium screen, more icons will appear, but the `center` section is still removed.

![navbar medium screen](https://www.ericsdevblog.com/courses/html-css/6/images/nav-md.png)

```css
@media screen and (min-width: 640px) {
  /* Display the menu, mic, camera, and notification icons for medium screen */
  .menu-icon,
  .mic-icon,
  .camera-icon,
  .notification-icon {
    display: block;
  }
}
```

On a large screen, the center section will be displayed, the mic icon will be moved to the center, and the right search icon will be removed. I left out the styles for the search form.

![navbar large screen](https://www.ericsdevblog.com/courses/html-css/6/images/nav-lg.png)

```css
@media screen and (min-width: 768px) {
  .sidebar-sm {
    display: flex;
    flex-direction: column;

    flex: 0;
  }

  /* Display the center section for large screens */
  .center {
    display: flex;
    flex-direction: row;

    gap: 10px;
    padding: 8px;
    align-items: center;
    justify-content: center;
  }

  . . .

  /* Hide the search and right mic icons */
  .search-icon,
  .mic-icon {
    display: none;
  }

  /* Display the center mic icon */

  .mic-icon-center {
    display: block;
  }
}
```

## Building the sidebar

Now, let's move on to the sidebar. The small sidebar will be displayed on large screens, and the full-sized sidebar will be displayed on x-large screens.

```html
<aside class="sidebar-sm">
  <div class="side-icon">
    <div class="icon">. . .</div>
    <div class="text">Home</div>
  </div>
  . . .
</aside>
```

```html
<aside class="sidebar-full">
  <section class="guide">
    <div class="item">
      <div class="icon">. . .</div>
      <div class="text">Home</div>
    </div>
    . . .
    <div class="divider"></div>
    <div class="item">
      <div class="icon">. . .</div>
      <div class="text">Library</div>
    </div>
    . . .
  </section>
  <div class="divider"></div>
  <section class="subscriptions">
    <p>Subscriptions</p>
    <div class="item">
      <img src="images/1.jpg" alt="Channel1" />
      <div class="text">First channel</div>
    </div>
    . . .
  </section>
  <div class="divider"></div>
  <section class="explore">
    <p>Explore</p>
    <div class="item">
      <div class="icon">. . .</div>
      <div class="text">Trending</div>
    </div>
    . . .
  </section>
  <div class="divider"></div>
  <section class="mf-ytb">
    <p>More from YouTube</p>
    <div class="item">
      <div class="icon">. . .</div>
      <div class="text">YouTube Premium</div>
    </div>
    . . .
  </section>
</aside>
```

The small sidebar contains four buttons arranged vertically. Each individual button should also be a flexbox, aligned vertically.

![small sidebar](https://www.ericsdevblog.com/courses/html-css/6/images/sidebar-small.png)

```css
@media screen and (min-width: 768px) {
  .sidebar-sm {
    display: flex;
    flex-direction: column;

    flex: 0;
  }

  .side-icon {
    width: 80px;
    height: 100px;
    border-radius: 10px;

    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
  }

  .side-icon:hover {
    background-color: #f2f2f2;
  }

  .side-icon svg {
    width: 25px;
  }

  .side-icon > .text {
    font-size: 10px;
    margin-top: 5px;
  }

  . . .
}
```

As for the full-sized sidebar, it should only be displayed on x-large screens. The sidebar should have a fixed width (`flex: 0 250px;`) so that it does not change as the viewport size changes. The height is defined as 100 percent of the viewport height (`100vh`), and the overflow is set to `auto`. This configuration ensures that the sidebar is treated as an individual section in the webpage. When you scroll the sidebar up and down, it will not affect other parts of the page.

![full sized sidebar](https://www.ericsdevblog.com/courses/html-css/6/images/sidebar-full.png)

```css
@media screen and (min-width: 1024px) {
  .sidebar-sm {
    display: none;
  }

  .sidebar-full {
    display: flex;
    flex-direction: column;
    flex: 0 250px;

    height: 100vh;
    overflow-y: auto;

    padding: 8px;
  }

  . . .
}
```

For individual items in the sidebar, the setup should be easy to understand.

```css
@media screen and (min-width: 1024px) {
  .sidebar-sm {
    display: none;
  }

  .sidebar-full {
    display: flex;
    flex-direction: column;
    flex: 0 250px;

    height: 100vh;
    overflow-y: auto;

    padding: 8px;
  }

  /* Section titles */

  .subscriptions > p,
  .explore > p,
  .mf-ytb > p {
    font-size: 16px;
    padding: 10px;
  }

  /* Individual items */

  .item {
    display: grid;
    grid-template-columns: 25px auto;
    gap: 20px;

    align-items: center;
    justify-items: stretch;

    padding: 10px;

    border-radius: 10px;
  }

  .item:hover {
    background-color: #f2f2f2;
  }

  .item > .text {
    font-size: 14px;
  }

  /* Channel images */

  .item > img {
    width: 30px;
    aspect-ratio: 1/1;
    border-radius: 100%;
    object-fit: cover;
  }

  /* Divider */

  .divider {
    border: #e5e5e5 solid 1px;
    margin: 10px 0px;
  }
}
```

## Building the video card component

As for the content section, we already have the general layout ready. All you need to do here is build the video card component.

![video card](https://www.ericsdevblog.com/courses/html-css/6/images/video-card.png)

```html
<section class="content">
  <section class="video">
    <div class="video-thumbnail">
      <img src="images/1.jpg" alt="Video Thumbnail" />
    </div>
    <div class="video-info">
      <img src="images/2.jpg" alt="Channel Logo" />
      <div>
        <h2>Lorem ipsum dolor sit amet consectetur adipisicing elit</h2>
        <p>Channel Name</p>
        <p>1M views • 1 day ago</p>
      </div>
    </div>
  </section>
  . . .
</section>
```

```css
/* Video card */

.video {
  width: 100%;
  height: min-content;
}

.video-thumbnail > img {
  width: 100%;
  height: 15em;
  object-fit: cover;
  border-radius: 10px;
}

.video-info {
  display: grid;
  grid-template-columns: 50px auto;
  gap: 10px;

  padding: 10px 0px;
}

.video-info > img {
  width: 50px;
  height: 50px;
  border-radius: 100%;
  object-fit: cover;
}

.video-info > div {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.video-info h2 {
  font-weight: 700;
  font-size: 20px;
}

.video-info p {
  color: #606060;
  font-size: 14px;
}
```

The `content` element itself should also be independent, like the sidebar.

```css
.content {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(22em, 1fr));
  grid-gap: 1em;

  align-content: start;

  flex: 1;

  padding: 10px;

  height: 100vh;
  overflow-y: auto;
}
```

## Conclusion

In this chapter, we took everything we have learned so far about HTML and CSS and recreated the homepage of YouTube. With this example, we pretty much covered everything you should know about HTML and CSS. In the following chapter, we will discuss some commonly used CSS tools and frameworks that might come in handy when creating your webpage.

Here are some of my other articles if you are interested:

- [HTML & CSS: A Practical Guide](https://www.ericsdevblog.com/courses/html-css/)
- [CSS and Responsive Design](https://www.ericsdevblog.com/courses/html-css/5/)
- [How to Center A Div in CSS](https://www.ericsdevblog.com/posts/how-to-center-a-div-in-css/)
- [How to Optimize Your Website](https://www.ericsdevblog.com/posts/how-to-optimize-your-website/)
- [Delve into CSS Grid and Flexbox](https://levelup.gitconnected.com/delve-into-css-grids-and-flexboxes-eba532677bab)
- [How to Create Transitions and Animations Using CSS](https://levelup.gitconnected.com/how-to-create-transitions-and-animations-using-css-f5fff20dcaa2)
- [How to Position and Align Elements Using CSS](https://levelup.gitconnected.com/how-to-position-and-align-elements-using-css-73db2ef3d6ac)
- [Working with Typography in CSS](https://blog.devgenius.io/working-with-typography-in-css-ca700859fe27)
- [Three Ways of Defining Colors in CSS](https://medium.com/devdive/three-ways-of-defining-colors-in-css-7b2f98a3fbf3)