Приветствую тебя читатель. Сегодня я хочу рассказать о своем опыте создания заглушки с ошибкой «Sorry, your browser doesn't support WebGL». Эту заглушку я придумал, работая над одним из своих компонентов, где я использовал технологию WebGL.

WebGL хорошо работает в основных современных десктопных браузерах, но в мобильном вебе дела не так хороши. Поэтому, для обработки ошибки я использовал вызов диалогового сообщения — alert. Согласитесь, что это не очень элегантное решение. Поэтому и пришла идея сделать красивое сообщение об ошибке.

Реализация фона


Для начала реализации нам потребуется создать тег div с классом demo-smile, который будет служить обверткой для нашей заглушки.

<div class="demo-smile"></div>


Теперь нам нужно растянуть этот элемент на весь viewport браузера. Для этого мы будем использовать свойство width со значением 100% и свойство height со значением 100vh.

.demo-smile{
    width: 100%;
    height: 100vh;
}


Далее установим цвет фона при помощи свойства background-color.

.demo-smile{
    width: 100%;
    height: 100vh;
    background: #32bfd3;
}


В результате в браузере мы увидим.



Реализация смайлика


Реализовывать смайлик мы будем при помощи круга. Для этого добавим внутрь demo-smile тег div с классом sad-smile.

  <div class="demo-smile">
    <div class="sad-smile"></div>
  </div>


Для создания круга при помощи CSS нам потребуется сделать квадрат и, используя border-radius: 50%, закруглить у него углы.

.sad-smile{
    width: 250px;
    height: 250px;
    border-radius: 50%;
}


Теперь закрасим круг при помощи линейного градиента, а также добавим внутреннюю тень для большей реалистичности.

.sad-smile{

    width: 250px;
    height: 250px;
    border-radius: 50%;

    background: linear-gradient(to bottom, #efee5f, #ecc837);
    box-shadow: inset 0px -14px 14px rgba(0, 0, 0, .3), 0px 2px 20px rgba(0, 0, 0, .6);
}




Расположим наш будущий смайлик по центру. Для решения этой задачи нам помогут флексбоксы. Добавим к элементу demo-smile свойства display со значением flex, justify-content со значением center и align-items со значением center.

.demo-smile{

    width: 100%;
    height: 100vh;
    background: #32bfd3;

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




Голова у нас готова! Дальше мы добавим глаза. Для этого нам потребуется создать два тега div с классом sad-smile__eyes. Потом для левого глаза добавим класс sad-smile__lefteye, а для правого — sad-smile__righteye.

<div class="demo-smile">
    <div class="sad-smile">
        <div class="sad-smile__eyes sad-smile__lefteye"></div>
        <div class="sad-smile__eyes sad-smile__righteye"></div>
    </div>
</div>


Для позиционирования элементов мы будем использовать position: absolute, поэтому элементу sad-smile нужно добавить position: relative.

.sad-smile{

    width: 250px;
    height: 250px;

    position: relative;
    border-radius: 50%;

    background: linear-gradient(to bottom, #efee5f, #ecc837);
    box-shadow: inset 0px -14px 14px rgba(0, 0, 0, .3), 0px 2px 20px rgba(0, 0, 0, .6);
}


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

.sad-smile__eyes{

  background-color: #fff;
  border: 8px solid #000;
  border-radius: 50% 50% 0 0;

  height: 20%;
  width: 20%;
}


Теперь нужно расположить глаза. Левый глаз будет позиционироваться относительно левого верхнего угла элемента sad-smile, а правый глаз относительно правого верхнего угла.

.sad-smile__eyes{

  position: absolute;
  top: 13.3%;

  background-color: #fff;
  border: 8px solid #000;
  border-radius: 50% 50% 0 0;

  height: 20%;
  width: 20%;
}

.sad-smile__lefteye{
  left: 20%;
}

.sad-smile__righteye{
  right: 20%;
}




Дальше требуется добавить зрачки в виде кружочков. Реализовывать мы их будем, используя псевдоэлемент :after. Также, их требуется расположить в левом нижнем углу относительно элемента sad-smile__eyes.

.sad-smile__eyes:after{

    content: "";
    display: block;
    background-color: #000;

    position: absolute;
    left:0;
    bottom: 0;

    width: 41.7%;
    height: 41.7%;
    border-radius: 50%; 
}




Теперь мы добавим нашему смайлику брови. Для этого используем псевдоэлемент :before и свойства width, height и border-radius. С помощью width и height мы создадим прямоугольники, а border-radius поможет нам скруглить углы.

.sad-smile__eyes:before{

    content: "";
    display: block;
    position: absolute;
    background-color: #000;

    border-radius: 100% 100% 0 0;
    height: 13.3%;
    width: 66.7%;

    right: 16.7%;
    top: -33.3%;
}




Мы почти закончили. Нам осталось только добавить рот. Для его реализации мы добавить div с классом sad-smile__mouth.

<div class="demo-smile">
    <div class="sad-smile">
        <div class="sad-smile__eyes sad-smile__lefteye"></div>
        <div class="sad-smile__eyes sad-smile__righteye"></div>
        <div class="sad-smile__mouth"></div>
    </div>
</div>


Зададим размеры элементу и установим свойство border. Также отцентрируем и прижмем его к низу элемента sad-smile.

.sad-smile__mouth{

  width: 66.7%;
  height: 30%;

  border-bottom: 7px solid #222;
  border-right: 7px solid transparent;
  border-left: 7px solid transparent;

  position: absolute;
  bottom: 5%;
  left: 50%;
  transform: translate(-50%, 0);
}




Для создания дуги осталось добавить border-radius: 50%.

.sad-smile__mouth{

  width: 66.7%;
  height: 30%;

  border-bottom: 7px solid #222;
  border-right: 7px solid transparent;
  border-left: 7px solid transparent;
  border-radius: 50%;

  position: absolute;
  bottom: 5%;
  left: 50%;
  transform: translate(-50%, 0);
}




А теперь мы сделаем грустный смайлик, добавив rotateX(180deg) к свойству transform.

.sad-smile__mouth{

  width: 66.7%;
  height: 30%;

  border-bottom: 7px solid #222;
  border-right: 7px solid transparent;
  border-left: 7px solid transparent;
  border-radius: 50%;

  position: absolute;
  bottom: 5%;
  left: 50%;
  transform: rotateX(180deg) translate(-50%, 0);
}




Наш смайлик готов!

Реализация слез


Для начала реализации слез создадим в элементах sad-smile__eyes по одному тегу div с классом sad-smile__tear.

<div class="demo-smile">
    <div class="sad-smile">
        <div class="sad-smile__eyes sad-smile__lefteye">
            <div class="sad-smile__tear"></div>
        </div>
        <div class="sad-smile__eyes sad-smile__righteye">
            <div class="sad-smile__tear"></div>
        </div>
        <div class="sad-smile__mouth"></div>
    </div>
</div>


Так как слезы имеют треугольную форму, реализовывать мы их будет при помощи равнобедренного CSS треугольника. Для этого требуется обнулить геометрические размеры элементов с классом sad-smile__tear и задать им свойства border-left, border-right и border-bottom. Важным моментом является то, что значение у свойства border-bottom должно быть в 3 раза больше, чем border-left и border-right.

.sad-smile__tear{

  position: absolute;
  top: 50%;
  left: 0%;
  z-index: 2;

  width: 0;
  height: 0;

  border-right: 8px solid transparent;
  border-left: 8px solid transparent;
  border-bottom: 24px solid #1ca5e2;

  transform: translateZ(0) translate(0, 0);
}




И добавим border-radius: 50%.

.sad-smile__tear{

  position: absolute;
  top: 50%;
  left: 0%;
  z-index: 2;

  width: 0;
  height: 0;

  border-right: 8px solid transparent;
  border-left: 8px solid transparent;
  border-bottom: 24px solid #1ca5e2;
  border-radius: 50%

  transform: translateZ(0) translate(0, 0);
}




Анимация для слез


Для начала реализации анимации требуется скрыть слезы, поэтому нужно удалить z-index, добавить opacity: 0 и scale(0) в классе sad-smile__tear.

.sad-smile__tear{

  position: absolute;
  top: 50%;
  left: 0%;

  width: 0;
  height: 0;
  opacity: 0;

  border-right: 8px solid transparent;
  border-left: 8px solid transparent;
  border-bottom: 24px solid #1ca5e2;
  border-radius: 50%;

  transform: translateZ(0) translate(0, 0) scale(0);
}


Далее напишем сценарий анимации.

@keyframes animation-tear{

    5%{
        opacity: 1;
    }

    10%{
        transform: translateZ(0) translate(0, 25px) scale(1);
    }

    100%{
        transform: translateZ(0) translate(0, 125px) scale(1);
    }

}  


И добавим в селекторе sad-smile__tear вызов анимации.

.sad-smile__tear{

  position: absolute;
  top: 50%;
  left: 0%;

  width: 0;
  height: 0;
  opacity: 0;

  border-right: 8px solid transparent;
  border-left: 8px solid transparent;
  border-bottom: 24px solid #1ca5e2;
  border-radius: 50%;

  transform: translateZ(0) translate(0, 0) scale(0);
  animation: animation-tear 2.5s cubic-bezier(0.63, 0.49, 1,-0.15) .2s infinite;
}


Важно отметить, что для создания временной функции я использовал инструменты devTools браузера Google Chrome.



Также нам нужно добавить задержку в 1 секунду для правой слезинки.

.sad-smile__righteye .sad-smile__tear{
  animation-delay: 1s;
}




Реализация сообщения


Для реализации сообщения нам требуется создать тег span с текстом “Sorry, your browser doesn't support WebGL” и добавить ему класс demo-smile__label.

<div class="demo-smile">
    <div class="sad-smile">
        <div class="sad-smile__eyes sad-smile__lefteye">
            <div class="sad-smile__tear"></div>
        </div>
        <div class="sad-smile__eyes sad-smile__righteye">
           <div class="sad-smile__tear"></div>
        </div>
        <div class="sad-smile__mouth"></div>
    </div>
    <span class="demo-smile__label"> Sorry, your browser doesn't support WebGL</span>
</div>


Далее стилизуем сообщение.

.demo-smile__label{
  margin-left: 20px;
  font-size: 30px;
  font-family: arial;
  color: #fff;
}




Заключение


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

PS: Если вам понравилась моя работа, то ставьте лайки и подписывайтесь на мои новости на сайте codepen.io.
Поделиться с друзьями
-->

Комментарии (25)


  1. k12th
    18.05.2016 19:00
    +1

    Глупый вопрос: а где поддерживается flex-box, но не поддерживается webgl?


    1. melnik909
      18.05.2016 19:06

      Android 4.4. Плюс поддержка WebGL еще зависит от графической карты. Но флексы это не догма. Можно переверстать, используя старые практики. Идея в том, чтобы делать веб более эффектным. Благо инструменты есть.


      1. k12th
        18.05.2016 19:08

        Не, принципиальных возражений-то у меня нет, все правильно сделано.


        1. melnik909
          18.05.2016 19:11

          Спасибо.


    1. Dolios
      19.05.2016 13:24

      https://www.khronos.org/webgl/wiki/BlacklistsAndWhitelists


      1. k12th
        19.05.2016 13:40

        Не думал, что железячно-драйверные проблемы еще остались…


  1. lain8dono
    18.05.2016 21:20
    +3

    Сразу вспомнился тест браузеров Acid2.


    Там тоже смайлик был

    image


    1. melnik909
      18.05.2016 21:22
      -1

      Прикольно. Раньше не встречал его.


      1. kashey
        19.05.2016 08:58
        +4

        Смайлик, или IE7?
        PS: Счастливый человек!


    1. KhodeN
      19.05.2016 07:52

      Забавно, что мой последний хром не проходит этот тест.
      http://www.webstandards.org/files/acid2/test.html
      Косяк в области глаз и подбородка.


      1. foxyrus
        19.05.2016 11:11

        Плагины стоят?


        1. Labunsky
          19.05.2016 11:55

          Аналогично в последней опере без плагинов. Видимо, стандарт уже особо никому не нужен


          1. homm
            20.05.2016 17:15

            Всё дело в ретине.


        1. KhodeN
          19.05.2016 12:21

          В инкогнито расширения отключены. Плагины обычные — flash, pdf.
          Ось — OS X.

          Кстати, проблема с глазами повторяется и в FF.


      1. Shance
        19.05.2016 12:20
        +1

        Хром 50 на линуксе — полёт нормальный, с глазами всё хорошо :)


      1. k12th
        19.05.2016 12:35

        Chrome 50 на win — все нормально с глазами и подбородками.


        1. XAHOK
          19.05.2016 15:55

          Хром 50 на win. Есть дефект глаз на долю секунды:
          http://screencast.com/t/F6foBhTS


          1. k12th
            19.05.2016 15:57

            Действительно, есть:(


      1. Dolios
        19.05.2016 13:34

        Chrome 50.0.2661.102 (64-bit) Ubuntu тест пройден успешно
        проблема на вашей стороне (с)


    1. DaMneD_SoUL
      19.05.2016 15:12

      Всё правильно, так улыбается счастливый пользователь IE7.


  1. koloritnij
    19.05.2016 23:22

    Разве vh не поддерживается только в новых мобильных браузерах (http://caniuse.com/#feat=viewport-units). Поправьте, если я не прав.


    1. melnik909
      19.05.2016 23:24

      vh хорошо поддерживается на десктопных и на мобильных устройствах. Ваша ссылка этому доказательство. Если вас смущает использование vh, то можно использовать старую технику. Как писал выше, использование новых возможностей это не догма.


      1. koloritnij
        19.05.2016 23:30

        Просто поддержка webgl начинается с тех же версий(http://caniuse.com/#search=webgl) вот это и смутило. Я говорю про мобильные браузеры.


        1. melnik909
          19.05.2016 23:33

          посмотрите ссылку, которую прислал Dolios. И Android 4.4 поддерживает vh, а webgl — нет.


          1. koloritnij
            19.05.2016 23:35

            Понял, спасибо, извините :)