Статьи

Создание винтажного телевидения с использованием BEM, CSS3 и JavaScript

Многие графические эффекты, которые раньше были возможны только с помощью графического редактора, теперь осуществимы благодаря комбинации простых правил CSS. Эта тенденция часто упоминается как «CSS Art», термин, который указывает на использование CSS для создания графических экспериментов, где CSS управляет шоу — будь то изображения или реальная анимация.

Несколько прекрасных примеров CSS-искусства, которые вы, возможно, видели, включают Гомера Симпсона и Дарта Вейдера , оба из которых созданы с использованием чистого CSS.

В этой статье я покажу вам, как нарисовать маленький старинный телевизор, созданный с использованием HTML5 и CSS3, с добавлением нескольких строк JavaScript, чтобы имитировать возможность показывать разные каналы (фактически видео, взятые с YouTube).

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

Вот демонстрация CodePen, показывающая, что мы будем создавать:

Краткое введение БЭМ

Для этого проекта мы будем использовать методологию BEM для именования наших классов CSS.

Подробное объяснение БЭМ выходит за рамки этой статьи, но здесь я кратко расскажу об этом.

BEM акроним расшифровывается как Модификатор блочного элемента . Эта методология предлагает структурированный способ именования классов, основанный на свойствах и роли рассматриваемого элемента. Чтобы придерживаться методологии BEM, мы должны придерживаться соглашения об именах, которое следует этому шаблону:

  • block представляет собой более высокий уровень абстракции или компонента.
  • block__element представляет потомок блока, который помогает сформировать block в целом.
  • block–modifier представляет другое состояние или версию block .

БЭМ позволяет нам быть более наглядным и понятным, поскольку мы можем понять отношения с другими элементами нашего кода посредством именования. Читая HTML-код с назначенными классами, вы можете увидеть, как куски (блоки, элементы, варианты или модификаторы этих элементов) связаны и как они работают.

Давайте посмотрим, как работает БЭМ; тогда мы увидим, что это применимо к нашему телевидению.

Для быстрого примера, подумайте о том, как связаны следующие элементы и как они названы:

 <article class="book"> <img src="/path/to/image.jpg" class="book__cover book__cover--large" /> <h1 class="book__title">The little prince</h1> </article> 

Это должно дать вам хорошее представление о том, что такое БЭМ. Для более глубокого обсуждения, проверьте статью Гарри Робертса . Теперь давайте перейдем к коду для нашего телевидения.

HTML для телевидения

Разметка, лежащая в основе телевидения, как и в случае с большим количеством CSS-рисунков, довольно глубокая, но не слишком сложная для понимания, если взглянуть на названия классов на основе БЭМ:

 <div class="television"> <div class="television__top"> <div class="television__antenna television__antenna--left"></div> <div class="television__antenna television__antenna--right"></div> <div class="television__antenna__base"></div> </div><!-- television__top --> <div class="television__center"> <div class="television__screen"> <iframe src="" frameborder="0" allowfullscreen></iframe> </div><!-- television__screen --> <div class="television__channels-wrapper"> <ul class="television__channels"> <li class="television__channel"><a href="http://www.youtube.com/embed/SRu6YRr1KtM" title="Channel 1"></a></li> <li class="television__channel"><a href="http://www.youtube.com/embed/oRdxUFDoQe0" title="Channel 2"></a></li> <li class="television__channel"><a href="http://www.youtube.com/embed/EGikhmjTSZI" title="Channel 3"></a></li> <li class="television__channel"><a href="http://www.youtube.com/embed/06qJVpUSKZY" title="Channel 4"></a></li> <li class="television__channel"><a href="http://www.youtube.com/embed/v_09wFxoaeQ" title="Channel 5"></a></li> <li class="television__channel"><a href="http://www.youtube.com/embed/Tj75Arhq5ho" title="Channel 6"></a></li> </ul> </div><!-- television__channels-wrapper --> </div><!-- television__center --> <div class="television__base"> <div class="television__foot television__foot--left"></div> <div class="television__foot television__foot--right"></div> </div><!-- television__base --> </div><!-- television --> 

Вот краткий обзор того, что мы сделали здесь в HTML:

  • Внутри контейнера .television находятся три основных раздела: верх, центр и основание.
  • Верхняя часть — это то, что держит части антенны
  • Центр держит экран и каналы
  • База держит ножки телевизора

Обратите внимание, что эти три основных раздела, а также внутренние элементы названы с использованием двойного подчеркивания, которое в БЭМ представляет элемент блока более высокого уровня.

Рядом с некоторыми из этих классов (например, при создании антенны) у нас есть имена, такие как television__antenna--left антенны television__antenna--left и television__antenna--right антенны television__antenna--right . Причина таких имен в том, что, хотя элемент является антенной, мы должны изменить элемент, чтобы он действовал как левая или правая антенна соответственно. Итак, последняя часть названия предполагает, что все правила, которые мы применим к этому конкретному классу, будут определять его стиль. В этом случае они определят стиль левой или правой антенны нашего винтажного телевизора.

Вопрос не так сложен для понимания, и этот пример должен подкрепить концепции, объясненные при обсуждении БЭМ. Существует блок, который может содержать один или несколько элементов, и эти дочерние элементы могут иметь одну или несколько конкретных характеристик, предназначенных в качестве модификаторов. Остальная часть HTML следует похожему шаблону БЭМ.

Элементlevision__screen имеет единственный дочерний элемент, iframe , который мы будем использовать для отображения видео, загруженных с YouTube. television__channels--wrapper канал television__channels--wrapper содержит неупорядоченный список ( <ul> ), который будет содержать видео, которые мы хотим воспроизвести при нажатии одной из шести кнопок канала. Атрибут href будет использоваться для изменения загрузки предполагаемого видео, о котором мы поговорим позже.

Также обратите внимание, что в этом проекте мы использовали <div> потому что нам не нужны теги с любым семантическим значением.

Теперь пришло время перейти к нашему CSS.

CSS для нашего телевидения

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

 iframe { box-sizing: border-box; width: 100%; height: 100%; overflow: hidden; border: 10px solid; border-radius: 32px; } .television { width: 450px; margin: 0 auto; } .television__top { width: 40%; margin: auto; position: relative; } .television__antenna { width: 5px; height: 100px; background-color: #3b3733; margin-bottom: -10px; } .television__antenna--left { transform: rotate(-30deg); float: left; } .television__antenna--right { transform: rotate(30deg); float: right; } .television__antenna__base { height: 20px; background-color: #3b3733; border-top-left-radius: 48px; border-top-right-radius: 48px; margin-bottom: 10px; clear: both; position: relative; z-index: 2; } 

Вот краткое описание важных аспектов CSS:

  • Мы использовали свойство transform для позиционирования частей антенны, одна вращалась по часовой стрелке, а другая против часовой стрелки.
  • Отрицательное поле и свойство float помогают нам установить положение частей антенны по отношению к телевизору и друг к другу.
  • Кроме того, мы используем clear и z-index чтобы гарантировать, что поплавок не вызовет проблем в расположении последующих элементов, а элементы антенны будут уложены правильно.
  • Чтобы гарантировать, что iframe выглядит «округленным» во всех браузерах, мы используем трюк с рамкой .

Давайте теперь посмотрим на код для центральной части телевизора:

 .television__center { position: relative; z-index: 2; width: 350px; height: 200px; background-color: #7a4e27; border: solid 3px #eef4c4; box-shadow: -10px -10px #d64832; border-radius: 48px; margin: 0 auto; padding: 10px 15px; } .television__screen { width: 270px; height: 190px; background-color: #eed5b6; border-radius: 48px; float: left; } .television__channels-wrapper { width: 70px; height: 190px; background-color: #efd6b7; border-radius: 48px; float: right; } .television__channels { padding: 0; } .television__channel { list-style-type: none; background-color: #7f4b23; width: 25px; height: 25px; border-radius: 50%; margin: 5px; float: left; position: relative; } .television__channel a { display: block; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: #e6a146; width: 12px; height: 12px; border-radius: 50%; } .television__channel a:active { box-shadow: inset rgba(255,255,255,0.6) 0 2px 2px, inset rgba(0,0,0,0.15) 0 -2px 5px, /* inner shadow */ rgba(100,100,100,0.6) 0 2px 1px, rgba(100,100,100,0.6) 0 2px 1px; /* color border */ } 

Вот основные моменты из кода выше:

  • z-index используется для правильной укладки телевизора на ноги
  • «Винтажный» эффект для нашего телевидения создается сочетанием теней, границ, цветов и отступов.
  • Кнопки канала создаются с border-radius 50%, который создает круг с любым размером элемента.
  • Кнопки каналов по отдельности центрируются по вертикали, по горизонтали и по вертикали с помощью transform: translate(-50%, -50%) .
  • Мы используем псевдокласс :active чтобы стилизовать состояние каналов, по которому щелкнули, используя тени и границы для создания эффекта.

Наконец, давайте посмотрим на последний раздел нашего CSS, показанный ниже.

 .television__base { width: 60%; margin: auto; } .television__base:after { clear: both; content: ""; display: table; } .television__foot { width: 20px; height: 70px; margin-top: -20px; background-color: #7d4d25; border: solid 3px #eed5b6; border-radius: 48px; } .television__foot--left { transform: rotate(30deg); float: left; } .television__foot--right { transform: rotate(-30deg); float: right; } 

А вот описание ключевых частей приведенного выше кода:

  • Мы используем метод clearfix, чтобы исправить проблему с плавающей запятой / очисткой.
  • Мы применили такое же вращение антенн на 30 градусов и к ножкам телевизора, а также float: left и float: right чтобы приблизить их.

JavaScript для работы каналов

Последний раздел этой статьи посвящен небольшому коду JavaScript, который позволяет демонстрации показывать некоторые видео при нажатии кнопки канала. С помощью элемента iframe в нашей разметке загрузка видео с YouTube очень проста. Наша цель — прикрепить обработчик, который будет выполняться при нажатии кнопки на панели.

Вот код:

 var buttons = document.querySelectorAll('.television__channel a'); for(var i = 0; i < buttons.length; i++) { buttons[i].addEventListener('click', function(event) { document.querySelector('.television__screen iframe').src = this.href; event.preventDefault(); }); } 

Здесь мы используем querySelectorAll выбора кнопок, то есть элементов a внутри элементов списка, имеющих класс .television__channel , который в переменной называется buttons . Затем мы перебираем каждый извлеченный элемент, чтобы присоединить обработчик, используя метод addEventListener() который запускается при срабатывании на нем события click .

Внутри обработчика кликов мы должны выполнить только два действия. Первый заключается в том, чтобы установить именно этот URL в качестве источника элемента iframe . Вторым является предотвращение действия по умолчанию, которое в этом случае заключается в загрузке страницы, указанной URL-адресом атрибута href . После установки этих строк браузер загрузит видео с YouTube, готовое к воспроизведению. Круто, не правда ли?

Демо и Заключение

Еще раз, вот демо-дисплей нашего рабочего телевизора:

Как упоминалось во введении, эти типы экспериментов CSS не всегда являются наиболее практичным способом создания графики. Это больше способ увидеть, что возможно с CSS, и, возможно, поможет вам изучить некоторые приемы.

И хотя мы могли бы использовать псевдоэлементы для создания многих элементов, на самом деле все это может быть проще сделать в HTML, поэтому ясно, где размещены наши различные элементы.