DevGang
Авторизоваться

Воссоздаем YouTube с помощью HTML и CSS

До сих пор мы рассматривали основы HTML и CSS, обсуждали различные методы, позволяющие размещать элементы на веб-странице, и изучали концепцию адаптивного дизайна, которая позволяет создавать веб-страницы, автоматически адаптирующиеся к различным размерам экрана. В этой главе мы объединим все, что мы узнали до сих пор, чтобы воссоздать YouTube, используя только HTML и CSS.

▶️ YouTube Demo

📧 Подпишитесь на мою рассылку: https://ericsdevblog.ck.page/profile

Создание макета страницы

Давайте начнем с обсуждения базового макета страницы. Мы будем следовать правилу "сначала для мобильных устройств" и начнем с маленького экрана. На маленьком экране должна быть верхняя панель навигации и раздел содержимого. Панель навигации имеет логотип слева и несколько кнопок справа. Раздел содержимого должен включать несколько компонентов-карточек, показывающих отдельные видеоролики.

На экране среднего размера (>= 640 пикселей) на панели навигации должно отображаться больше значков. Мы пока пропустим этот шаг и вернемся к этой теме, когда начнем создавать навигационное меню.

На большом экране (>= 768 пикселей) страница должна иметь небольшую боковую панель. На панели навигации должно отображаться окно поиска в центре, а не просто значок. Раздел содержимого также должен быть многоколоночным.

И, наконец, на экране x-large (>= 1024 пикселей) веб-страница должна иметь полноразмерную боковую панель, полностью развернутую панель навигации со всеми значками и полями поиска, а в разделе содержимого должно быть больше столбцов.

HTML-документ

Теперь давайте посмотрим, сможете ли вы создать этот макет. Мы начнем с 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>

А затем боковые панели:

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

Внутри элемента <main> также должен быть раздел content:

<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>

Помните, что ваш HTML-код должен содержать все компоненты, необходимые для всех размеров экрана. Если элемент не требуется для определенного экрана, вы можете удалить его, установив значение display равным none.

Этот пример содержит панель навигации, определяемую элементом <nav>. Панель навигации состоит из трех разделов: start, center и end. Названия классов соответствуют их соответствующим позициям на панели навигации. Этот макет можно создать с помощью flexbox, а для свойства justify-content должно быть установлено значение space-between. Центральную секцию следует снимать до тех пор, пока экран не станет достаточно большим.

Раздел <main> имеет две боковые панели: небольшую боковую панель (sidebar-sm) и полноразмерную боковую панель (sidebar-full). Маленькая боковая панель должна отображаться на больших экранах, а полноразмерная боковая панель должна отображаться только на экранах x-large.

Наконец, для раздела содержимого вы можете использовать CSS-сетку с адаптивным макетом без точки останова, который мы обсуждали в предыдущей главе. На данный момент мы не будем беспокоиться о том, как создаются компоненты карты.

Теперь мы можем перейти к файлу CSS. Давайте уберем поля и отступы по умолчанию и установим для свойства box-sizing значение border-box. Вы также можете добавить рамку к каждому разделу, чтобы сделать их соответствующие позиции более четкими.

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

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

Макет навигационной панели

Далее, панель навигации должна представлять собой flexbox с направлением, установленным на строку, и параметром justify-content, установленным на пространство между ними, чтобы каждый подраздел имел равные промежутки между собой. Подразделы также должны представлять собой flexbox строк, чтобы логотип и значки также располагались горизонтально. Однако, поскольку мы начинаем с маленького экрана, центральную часть на данный момент следует удалить (display: none;).

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.

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

Боковые панели

Далее, раздел <main> должен представлять собой флексбокс строк или сетку с двумя столбцами, чтобы боковая панель и контент находились в одной строке.

main {
  display: flex;
  flex-direction: row;
}
The sidebars are removed on small screens.

.sidebar-sm {
  display: none;
}

.sidebar-full {
  display: none;
}

Маленькая боковая панель отображается на больших экранах. Установив для flex значение 0, вы гарантируете, что боковая панель имеет фиксированный размер и при изменении области просмотра изменяется только раздел контента.

/* Large screen */

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

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

Полноразмерная боковая панель отображается на больших экранах, а маленькая боковая панель будет удалена.

/* X-Large screen */

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

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

Раздел контента

Наконец, для раздела контента:

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

  flex: 1;
}

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

На данный момент мы установим максимальную ширину видеокарты равной 20 мкм. Вот как выглядит этот макет при изменении области просмотра:

Построение панели навигации

Далее давайте сосредоточимся на панели навигации. В разделе "Пуск" есть значок меню и логотип. Центральная секция содержит форму поиска и значок поиска. Наконец, конечная секция содержит несколько значков и фотографию профиля. Чтобы сделать этот пример короче, я опустил фактические элементы значков, определенные с помощью <svg>, но вы можете скопировать эти ресурсы непосредственно с YouTube.

<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>

Прежде всего, все значки должны иметь единый стиль. Они должны быть округлыми и иметь одинаковые отступы. У значков также должен быть фон при наведении курсора сверху.

.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;
}

На маленьком экране большинство этих значков следует удалить, поскольку горизонтальное пространство на мобильном устройстве очень ценно. В этом случае мы сохраним только логотип, значок поиска и изображение профиля. Все остальные элементы будут удалены.

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

А затем оформите начальную, центральную и конечную части навигационной панели.

/* 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 и end будут иметь одинаковый размер, а center будет увеличиваться быстрее, чем его братья и сестры, по мере увеличения области просмотра. center будет удален на маленьком экране, поэтому пока есть только начало и конец.

На экране среднего размера появится больше значков, но центральная часть по-прежнему удалена.

@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;
  }
}

На большом экране отобразится центральная часть, значок микрофона будет перемещен в центр, а значок поиска справа будет удален. Я не указал стили для формы поиска.

@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;
  }
}

Создание боковой панели

Теперь перейдем к боковой панели. Небольшая боковая панель будет отображаться на больших экранах, а полноразмерная боковая панель — на больших экранах.

<aside class="sidebar-sm">
  <div class="side-icon">
    <div class="icon">. . .</div>
    <div class="text">Home</div>
  </div>
  . . .
</aside>
<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>

Небольшая боковая панель содержит четыре кнопки, расположенные вертикально. Каждая отдельная кнопка также должна представлять собой гибкий блок, выровненный по вертикали.

@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;
  }
  . . .
}

Что касается полноразмерной боковой панели, то она должна отображаться только на экранах x-large. Боковая панель должна иметь фиксированную ширину (flex: 0 250 пикселей;), чтобы она не менялась при изменении размера окна просмотра. Высота определяется как 100 процентов от высоты окна просмотра (100vh), а для переполнения установлено значение auto. Эта конфигурация гарантирует, что боковая панель рассматривается как отдельный раздел веб-страницы. Когда вы прокручиваете боковую панель вверх и вниз, это не повлияет на другие части страницы.

@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;
  }
  . . .
}

Для отдельных элементов на боковой панели настройка должна быть простой для понимания.

@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;
  }
}

Сборка компонента видеокарты

Что касается раздела контента, то у нас уже готов общий макет. Все, что вам нужно сделать, это создать компонент видеокарты.

<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>
/* 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;
}

Сам элемент content также должен быть независимым, как боковая панель.

Вывод

В этой главе мы взяли все, что мы узнали до сих пор о HTML и CSS, и воссоздали домашнюю страницу YouTube. На этом примере мы в значительной степени рассмотрели все, что вам следует знать о HTML и CSS.

#CSS #HTML
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться