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

Как создать 3D-эффекты в CSS

Существует аналогия, которая сравнивает языки программирования с домом: HTML — это структура дома (стены, перегородки), CSS — декор и оформление (мебель, интерьер), а JavaScript — функциональность (электроснабжение, сантехника).

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

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

Понимание трехмерности изображений

В трехмерном пространстве объекты имеют три величины: длина, ширина и высота. Разработчики в своем широком кругу общения ширину воспринимают так же как и длину, но она более короткая. Так же дела обстоят и с высотой, обычно под ней подразумевается глубина. При обычном взгляде на экран вы видите только 2D, для создания 3D-эффекта вам понадобится свойство CSS transform.

Благодаря свойству transform можно управлять трехмерными размерами и положением элемента. Управление горизонтальным положением возможна с помощью translateX(), вертикальным положением — translateY(), а высотой/глубиной — translateZ().

Возьмем для примера иллюстрацию, в котором два прямоугольных элемента — один маленький, а другой большой. Маленький элемент — дочерний (Child), и он вложен в больший родительский элемент (Parent):

При изменении положения дочернего элемента по горизонтали и вертикали используя translate, вы увидите, что он перемещается:

Изменяя положение элемента child по оси Z с помощью функции translateZ(), мы ожидаем увидеть эффект глубины — элемент должен казаться удаляющимся или приближающимся к зрителю. Однако на практике этого не происходит, так как отсутствует перспектива.

Перспектива — это визуальный эффект, который позволяет передать ощущение объема и глубины. В CSS для этого используются свойства perspective и оператор perspective(), специально предназначенные для работы с 3D-преобразованиями.

Чтобы создать эффект перспективы, нужно задать свойство perspective родительскому элементу, а для дочернего элемента использовать функцию perspective() в сочетании со свойством transform

Рассмотрим на примере, как свойство perspective влияет на функцию translateZ(). Мы создадим простую анимацию, демонстрирующую этот эффект. 

Вот HTML и CSS для родительского и дочернего элементов.:

HTML
<div class="parent">
    <div class="child">
    </div>
  </div>
CSS
.parent {
  display: flex;
  justify-content: center;
  align-items: center;
  background: rgba(255, 255, 255, 0.07);
  width: 400px;
  height: 500px;
  border: 0.5px solid rgba(255, 255, 255, 0.15);
  border-radius: 5px;
  z-index: 0;
}
.child {
  background: rgba(255, 255, 255, 0.25);
  width: 200px;
  height: 250px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 5px;
  z-index: 1;
}

В этом проекте сначала добавим perspective к родительскому элементу, затем к дочернему преобразование анимации (animation: transform)

CSS
.parent{
  perspective: 1000px;
}
.child{
   animation: transform 5s infinite ease-in-out alternate-reverse;
}
@keyframes transform{
  0%{
    transform: translateZ(-200px)
  }
  100%{
    transform: translateZ(200px)
  }
}

И в результате мы увидим:

Такая анимация проиграется в случае применения оператора perspective(). Если же вы воспользовались функцией rotate(), то исход был бы другим.

Давайте рассмотрим пример в котором мы повернем дочерний объект вдоль оси X:

CSS
.child{
  transform: perspective(10px) rotateX(2deg);
}

В скриншоте это выглядит следующим образом:

Поэкспериментируем с небольшим смещением по оси Z:

Интересно, насколько далеко можно «растянуть» границы объектов:

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

В своем проекте мы также можем использовать автономное свойство:

CSS
.parent {
  perspective: 10px;
}
.child {
  transform: rotateX(2deg) translateZ(5px);
}

Результат будет аналогичным, но объект не выйдет за границы области просмотра. Как мы уже заметили, у каждого подхода есть свои преимущества. В следующих разделах мы подробно рассмотрим остальные операции transform

Важно отметить, что значение perspective в данном примере использовалось для усиления 3D-эффекта, чтобы вы могли увидеть, как работает свойство. Поскольку мы смотрим на элемент сверху, значение perspective не превышает 1000px. Небольшие значения перспективы создают более заметный эффект глубины.

Здесь вы можете посмотреть код с анимацией 3D-преобразования:

Перейдем к самой интересной части — созданию 3D-эффектов с помощью CSS!

Эффект отражения и тень

Взаимодействие света позволяет нам легко определить местоположение объекта в трехмерном пространстве. Чтобы создать иллюзию отражения и тени в CSS, мы можем использовать оператор perspective(), что придаст элементу эффект плавания в трехмерном пространстве.

3D-отражение текста

На примере мы используем свойство text, но вы можете выбрать и другие HTML-элементы:

HTML
<div class="content">
    <h1>Text in space</h1>
  </div>

Свет нам поможет создать отражение и для этого мы воспользуемся свойством text-shadow (тень текста):

CSS
.content h1 {
  position: relative;
  font-size: 5rem;
  font-weight: 600;
  color: #fff;
  margin: 3px;
  text-shadow: 0px 0px 10px #b393d350, 0px 0px 20px #b393d350;
  text-transform: uppercase;
}

Результатом будет эффект светящегося текста:

Теперь добавим отражение с помощью псевдоэлемента:

CSS
  .content h1::before {
    content: "";
    position: absolute;
    top: 80%;
    left: 0;
    height: 100%;
    width: 100%;
    background: #b393d3;
    transform: perspective(10px) rotateX(10deg) scale(1,0.2);
    filter: blur(1em);
    opacity: 0.5;
  }

Сначала мы применяем к псевдоэлементу те же размеры и цвет фона, что и к основному объекту — тексту. Затем используем свойство transform с операторами perspective, rotateX и scale.

С первыми двумя операторами мы уже знакомы. Остановимся на scale (масштабирование). В предыдущем примере мы видели, как изображение выходило за границы области просмотра. Чтобы избежать этого, можно изменить размер элемента по осям X и Y.

В нашем примере созданное отражение сохраняет свой первоначальный размер по оси X, но уменьшается примерно в два раза по оси Y. Благодаря непрозрачности и фильтру создается ощущение потери света.

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

3D-тень (3D shadow)

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

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

Пропишем код HTML:

HTML
<div class="content">
    <div class="rocket">
      <img src="rocket.png" alt="">
    </div>
  </div>

В блоке кода CSS мы определим нужные нам размеры, а затем добавим псевдоэлемент:

CSS
.rocket::before {
  content: "";
  position: absolute;
  bottom: -10%;
  left: 0;
  height: 50px;
  width: 100%;
  border-radius: 50%;
  background: radial-gradient(rgba(0, 0, 0, 0.8), transparent, transparent);
  transition: 0.5s;
}

Свойство border-radius: 50% придает тени овальную форму. Вы можете самостоятельно определять высоту или ширину объекта. Тени обычно рисуются в более темных тонах, чем фон, и границы делаются размытыми с помощью радиального градиента, переходящего от черного к прозрачному. 

Вот пример того, как выглядит наше изображение на данный момент:

И добавим в код немного анимации:

CSS
.rocket:hover img{
  transform: translateY(-40px);
}
.rocket:hover::before {
  opacity: 0.8;
  transform: scale(0.8);
}

С анимацией наша ракета перемещается вверх и вниз, тем самым ее тень будет уменьшаться или увеличиваться. 

Полный код и результат вы увидете ниже:

Анимация текста 3D

Создать 3D-текст мы сможем с помощью свойства CSS box-shadow. Для этого мы воспользуемся несколькими слоями теней.

Для примера возьмем этот код HTML:

HTML
<div class="content">
    <h1>3D text in 3D space</h1>
  </div>

Чтобы превратить его в 3D-текст нам понадобится CSS. Мы наклоним текст под углом, используя perspective и transform.

CSS
.content {
  position: relative;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  perspective: 1500px;
  transform-style: preserve-3d;
}
.content h1 {
  font-size: 5rem;
  font-weight: 600;
  color: #b393d3;
  text-shadow: 1px 4px 1px #480d35, 
               1px 5px 1px #480d35, 
               1px 6px 1px #480d35,/* to create the sides*/
               1px 10px 5px rgba(16, 16, 16, 0.5), 
               1px 15px 10px rgba(16, 16, 16, 0.4),
               1px 20px 30px rgba(16, 16, 16, 0.3); /* real shadow */
  margin: 3px;
  transform: rotateX(15deg) rotateY(-20deg) rotateZ(10deg);
  text-transform: uppercase;

На данном этапе это будет выглядеть следующим образом:

Добавляем анимацию:

CSS
.content:hover h1{
  transform: rotateX(2deg) rotateY(0deg) rotateZ(0deg);
  font-size: 4rem;
  transition: 500ms ease-in-out;
}

Вот такой результат мы увидим:

Эффект 3D наклона

На данном этапе предлагаем поэксперементировать с изображениями. Для примера возьмем изображение:

В работу возьмем следующий код HTML:

HTML
<div class="text">
      <h2>Hover on the image</h2>
      <p>It uses a combination of all the rotate operators</p>
      <div class="tilt-img">
        <img src="7.jpg" alt="">
      </div>
    </div>

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

Чтобы наклонить изображение под углом и вернуть его в исходное положение при наведении курсора, используйте свойство transform в CSS:

CSS
.tilt-img {
  width: 600px;
  height: auto;
  margin-top: 20px;
  perspective: 1000px;
}
.tilt-img img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: 10px;
 transform: rotateX(15deg) rotateY(-5deg) rotateZ(1deg);
  box-shadow: 5px 5px 2px rgba(0, 0, 0, 0.5);
  transition: 2s;
}
.tilt-img:hover img{
  transform: none;
  box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.5);
}

Вы можете изменять наклон (tilt) и добавлять при наведении курсора мыши или же скорректировать значения transform:

Продемонстрируем наклон 3D-изображения с помощью CSS:

Наклон и отслеживание мыши

В этом примере мы научимся наклонять элемент и следить за движением мыши при наведении на него. Для этого мы воспользуемся vanilla-tilt.js — библиотекой JavaScript.

Так выглядит результат, к которому мы будем стремиться:

Создадим карточку и добавим немного текста с HTML:

HTML
<div class="box">
    <div class="elements">
      <h2>Hello!</h2>
      <p>I'm a 3D card</p>
    </div>
    <div class="card">
    </div>
  </div>

Следующим шагом мы задаем стили с помощью CSS:

CSS
.box {
  position: relative;
  border-radius: 20px;
  transform-style: preserve-3d;
}
.box .card {
  position: relative;
  background: rgba(255, 255, 255, 0.07);
  width: 300px;
  min-height: 400px;
  backdrop-filter: blur(10px);
  border: 0.5px solid rgba(255, 255, 255, 0.15);
  border-radius: 20px;
  box-shadow: 0 25px 45px rgba(0,0,0,0.05);
}
.elements{
  position: absolute;
  top: 100px;
  left: 50px;
  width: 200px;
  height: auto;
  text-align: center;
  background: transparent;
  transform: translateZ(80px);
}
.elements h2{
  font-size: 3rem;
  font-weight: 600;
  color: #f6d8d5;
  text-transform: uppercase;
}
.elements p{
  font-size: 1.5rem;
  color: #b393d3;
}

В этом коде два ключевых свойства CSS отвечают за создание 3D-эффекта на карточке: transform и transform-style. В котором:

  • transform-style: preserve-3d определяет, что карточка находится в трехмерном пространстве. 
  • transform: translateZ(80px) применяется к элементу elements (родительскому элементу текста) и сдвигает текст на 80 пикселей в направлении зрителя.

Сочетание этих свойств создает эффект парящего текста над карточкой.

Для подключения библиотеки, вам необходимо перейти на сайт cdnjs.com и найти CDN Vanilla-tilt.js. Далее поставить ссылку на библиотеку в секцию <head> вашего HTML-документа. Чтобы инициализировать Vanilla-tilt мы на сайте main site скопируем функцию VanillaTilt.init(), которая управляет наклоном и добавим ее непосредственно перед закрывающим тегом </body> в нашем HTML.

HTML
<script type="text/javascript">
        VanillaTilt.init(document.querySelector(".your-element"), {
                max: 25,
                speed: 400
        });
</script>

Теперь нам всего лишь нужно заменить .your-element на имя класса нашего элемента, чтобы применить эффект 3D-наклона.

По умолчанию максимальный угол наклона и скорость перехода задаются параметрами max и speed соответственно. Вы также можете добавить блик (glare), сглаживание (easing) или указать направление (tilt) и угол наклона (angle).

Пример того, как получить эффект, приведенный выше

HTML
<script>
    VanillaTilt.init(document.querySelector(".box"), {
      max: 10,
      speed: 200,
      easing: "cubic-bezier(.03,.98,.52,.99)",
      reverse: true,
      glare: true,
      "max-glare": 0.1,
    });
  </script>

Библиотека выполняет не всю работу, и важно использовать свойства transform и transform-style для 3D-эффекта. Без применения данных свойств все выглядело бы примерно так:

В текущем варианте текст отображается на одном уровне с карточкой, и остается только эффект наклона. Это выглядит неплохо, но не так впечатляюще, как 3D-эффект, который мы получаем при включении transform и transform-style.

Давайте рассмотрим еще один практический пример использования этого 3D-эффекта. 

Используя ту же карточку, мы добавим фоновое изображение и подпись, которая будет появляться при наведении курсора мыши:

CSS
.box .card {
  position: relative;
  background: url(/Captions/8.jpg) center;
  background-size: cover;
  background-repeat: no-repeat;
  width: 300px;
  min-height: 400px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 10px;
  box-shadow: 0 25px 45px rgba(0,0,0,0.05);
  z-index: 0;
}
.elements{
  position: absolute;
  top: 60%;
  left: 30%;
  width: 250px;
  height: auto;
  padding: 10px;
  border-radius: 5px;
  text-align: center;
  background: rgba(255, 255, 255, 0.25);
  transform: translateZ(80px);
  z-index: 2;
  opacity: 0;
  transition: opacity 500ms;
}
.box:hover .elements{
  opacity: 1;
}

Так выглядит результат создания 3D-карточки с подписью, появляющейся при наведении.

3D-кнопки

Кнопки — это неотъемлемая часть веб-дизайна. Они бывают разных форм, размеров и функций, но у всех есть одно общее: чтобы активироваться, их нужно нажать. Но как часто вы видите, чтобы кнопки действительно "нажимались"?

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

Для этого мы будем использовать CSS-свойство transform.

Мы замечаем, что кнопка состоит из отдельных частей — первая с текстом «Click Me» и вторая с нижним и боковым светлым фоном. 

Код HTML для кнопки:

HTML
<button class="btn"><span class="txt">Click Me</span></button>

В CSS же мы начнем со второй части, с button с именем класса btn:

CSS
.btn {
  position: relative;
  background: #17151d;
  border-radius: 15px;
  border: none;
  cursor: pointer;
}

И после мы оформляем верхнюю часть кнопки:

CSS
.text {
  display: block;
  padding: 10px 40px;
  border-radius: 15px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  background: #480d35;
  font-size: 1.5rem;
  font-weight: 500;
  color: #b393d3;
  transform: translateY(-6px);
  transition: transform ease 0.1s;
}

Ключевым элементом создания 3D-эффекта при нажатии на кнопку является свойство transform

Все, что нам нужно сделать, это немного «сдвинуть»‎ кнопку при нажатии, используя transform на несколько пикселей:

CSS
.btn:active .text{
  transform: translateY(-2px);
}

Вот пример 3D-кнопки, которую вы можете попробовать прямо сейчас:

Кроссбраузерная совместимость

Свойство transform и его операторы отлично поддерживаются всеми основными браузерами, за исключением Internet Explorer. Вы можете проверить совместимость самостоятельно на сайте CanIuse:

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

Рекомендуем сравнить производительность в разных браузерах и попробовать использовать разную толщину границ, чтобы найти оптимальное решение.

Веб-дизайн — это творчество! Веб — это ваша творческая площадка, а CSS — ваша кисть. В этой статье вы узнали, как создавать интересные 3D-эффекты с помощью свойства transform. Попробуйте придумать другие интересные эффекты!

Источник:

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

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу