Трансформация элементов. Часть 2.
В этой статье мы продолжим изучать трансформации элементов, рассмотрим функции преобразования элементов, которые позволяют сдвигать элементы как в двухмерном, так и трехмерном пространстве, детально познакомимся с перспективой обзора элемента, поговорим о матрицах преобразований и научимся изменять точку преобразования элемента.
Сдвиг элементов
Следующая функция преобразования translate(), определяет двухмерное преобразование путем сдвига элемента влево, вправо, вверх или вниз, используя координаты по оси X и Y (отрицательные значения отвечают за сдвиг влево и вверх, положительные за сдвиг вправо и вниз).
Обращаю Ваше внимание, что элемент, к которому применяется сдвиг не влияет на поток документа (элемент перекрывает другие элементы), это правило верно и для других трансформаций.
Давайте перейдем к примеру:
<!DOCTYPE html> <html> <head> <meta charset = "UTF-8"> <title>Сдвиг элементов</title> <style> .static { display: inline-block; /* блочно-строчные элементы (выстраиваем элементы в линейку) */ margin: 10px; /* внешние отступы со всех сторон */ background: gray; /* цвет заднего фона */ } div { width: 180px; /* ширина элемента */ height: 100px; /* высота элемента */ line-height: 100px; /* высота строки (выраывниваем по вертикали) */ text-align: center; /* горизонтальное выравнивание текста по центру */ transition: 0.2s; /* переходный эффект составляет 200 миллисекунд (0,2 секунды) */ } .test2, .test4, .test6 {background: orange;} /* цвет заднего фона */ .test, .test3, .test5 {background: plum;} /* цвет заднего фона */ .test:hover { transform: translate(20px, 20px); /* сдвиг элемента при наведении */ } .test2:hover { transform: translate(-20px, -20px); /* сдвиг элемента при наведении */ } .test3:hover { transform: translate(20px, 0); /* сдвиг элемента при наведении */ } .test4:hover { transform: translate(-20px, 0); /* сдвиг элемента при наведении */ } .test5:hover { transform: translate(0, 20px); /* сдвиг элемента при наведении */ } .test6:hover { transform: translate(0, -20px); /* сдвиг элемента при наведении */ } </style> </head> <body> <div class = "static"><div class = "test">translate(20px, 20px)</div></div> <div class = "static"><div class = "test2">translate(-20px, -20px)</div></div> <div class = "static"><div class = "test3">translate(20px, 0)</div></div><br> <div class = "static"><div class = "test4">translate(-20px, 0)</div></div> <div class = "static"><div class = "test5">translate(0, 20px)</div></div> <div class = "static"><div class = "test6">translate(0, -20px)</div></div> </body> </html>
В этом примере мы использовали различные значения для функции translate(). Первое значение функции определяет горизонтальный сдвиг элемента (положительное значение сдвигает элемент вправо по оси X, а отрицательное влево по оси X). Второе значение функции определяет вертикальный сдвиг элемента (положительное значение сдвигает элемент вниз по оси Y, а отрицательное вверх по оси Y). Если указать значение 0 для любой оси, то элемент не будет по ней сдвигаться, по аналогии с другими функциями.
Результат нашего примера:
Вы можете проводить преобразование путем сдвига элемента и для конкретной оси, для этого в CSS существуют функции преобразования translateX(), translateY() и translateZ(). Рассмотрим их в следующем примере:
<!DOCTYPE html> <html> <head> <meta charset = "UTF-8"> <title>Сдвиг элементов по конкретным осям</title> <style> .static { display: inline-block; /* блочно-строчные элементы (выстраиваем элементы в линейку) */ margin: 10px; /* внешние отступы со всех сторон */ background: gray; /* цвет заднего фона */ } div { width: 180px; /* ширина элемента */ height: 100px; /* высота элемента */ line-height: 100px; /* высота строки (выраывниваем по вертикали) */ text-align: center; /* горизонтальное выравнивание текста по центру */ transition: 0.2s; /* переходный эффект составляет 200 миллисекунд (0,2 секунды) */ } .test2, .test4, .test6 {background: orange;} /* цвет заднего фона */ .test, .test3, .test5 {background: plum;} /* цвет заднего фона */ .test:hover { transform: translateX(20px); /* сдвиг элемента по оси X при наведении */ } .test2:hover { transform: translateX(-20px); /* сдвиг элемента по оси X при наведении */ } .test3:hover { transform: translateY(20px); /* сдвиг элемента по оси Y при наведении */ } .test4:hover { transform: translateY(-20px); /* сдвиг элемента по оси Y при наведении */ } .test5:hover { transform: perspective(500px) rotateX(45deg) translateZ(30px); /* используем несколько функций преобразования для элемента при наведении (перспектива, поворот по оси X, сдвиг элемента по оси Z ) */ } .test6:hover { transform: perspective(500px) rotateX(45deg) translateZ(-30px); /* используем несколько функций преобразования для элемента при наведении (перспектива, поворот по оси X, сдвиг элемента по оси Z ) */ } </style> </head> <body> <div class = "static"><div class = "test">translateX(20px)</div></div> <div class = "static"><div class = "test2">translateX(-20px)</div></div> <div class = "static"><div class = "test3">translateY(20px)</div></div><br> <div class = "static"><div class = "test4">translateY(-20px)</div></div> <div class = "static"><div class = "test5">translateZ(30px)</div></div> <div class = "static"><div class = "test6">translateZ(-30px)</div></div> </body> </html>
В этом примере были использованы различные значения функций translateX(), translateY() и translateZ(), благодаря которым, мы сдвигаем элементы по необходимой оси.
Для демонстрации работы трехмерного сдвига элемента функцией translateZ(), мы добавили функцию rotateX(), которая поворачивает наш элемент по оси X и функцию преобразования perspective(), которая определяет перспективу обзора элемента, создавая для пользователя иллюзию глубины.
Результат нашего примера:
Трехмерный сдвиг элементов
Следующая функция - translate3d() позволяет нам задать трехмерное преобразование путем сдвига элемента, используя координаты трёх осей (X,Y и Z). Перейдем к примеру:
<!DOCTYPE html> <html> <head> <meta charset = "UTF-8"> <title>Трехмерный сдвиг элементов</title> <style> .static { display: inline-block; /* блочно-строчные элементы (выстраиваем элементы в линейку) */ margin: 10px; /* внешние отступы со всех сторон */ background: gray; /* цвет заднего фона */ } div { width: 180px; /* ширина элемента */ height: 100px; /* высота элемента */ line-height: 100px; /* высота строки (выраывниваем по вертикали) */ text-align: center; /* горизонтальное выравнивание текста по центру */ transition: 0.2s; /* переходный эффект составляет 200 миллисекунд (0,2 секунды) */ } .test2, .test4, .test6 {background: orange;} /* цвет заднего фона */ .test, .test3, .test5 {background: plum;} /* цвет заднего фона */ .test:hover { transform: perspective(500px) rotateX(45deg) translate3d(20px,20px,20px); /* используем несколько функций преобразования для элемента при наведении (перспектива, поворот по оси X, трехмерный сдвиг элемента) */ } .test2:hover { transform: perspective(500px) rotateX(45deg) translate3d(-20px,-20px,-20px); /* используем несколько функций преобразования для элемента при наведении (перспектива, поворот по оси X, трехмерный сдвиг элемента) */ } .test3:hover { transform: perspective(500px) rotateX(45deg) translate3d(-20px,-20px,-80px); /* используем несколько функций преобразования для элемента при наведении (перспектива, поворот по оси X, трехмерный сдвиг элемента) */ } .test4:hover { transform: perspective(500px) rotateX(45deg) translate3d(0,0,-80px); /* используем несколько функций преобразования для элемента при наведении (перспектива, поворот по оси X, трехмерный сдвиг элемента) */ } .test5:hover { transform: perspective(500px) rotateX(45deg) translate3d(20px,0, 40px); /* используем несколько функций преобразования для элемента при наведении (перспектива, поворот по оси X, трехмерный сдвиг элемента) */ } .test6:hover { transform: perspective(500px) rotateX(45deg) translate3d(0,20px, 40px); /* используем несколько функций преобразования для элемента при наведении (перспектива, поворот по оси X, трехмерный сдвиг элемента) */ } </style> </head> <body> <div class = "static"><div class = "test">translate3d(20px,20px,20px)*</div></div> <div class = "static"><div class = "test2">translate3d(-20px,-20px,-20px)*</div></div> <div class = "static"><div class = "test3">translate3d(-20px,-20px,-80px)*</div></div><br> <div class = "static"><div class = "test4">translate3d(0,0,-80px)*</div></div> <div class = "static"><div class = "test5">translate3d(20px,0, 40px)*</div></div> <div class = "static"><div class = "test6">translate3d(0,20px, 40px)*</div></div> </body> </html>
По аналогии с ранее рассмотренными функциями сдвига элементов, функция translate3d() задаёт сдвиг одновременно по осям X,Y и Z. Первое значение функции определяет горизонтальный сдвиг элемента (положительное значение сдвигает элемент вправо по оси X, а отрицательное влево по оси X). Второе значение функции определяет вертикальный сдвиг элемента (положительное значение сдвигает элемент вниз по оси Y, а отрицательное вверх по оси Y). Третее значение функции определяет сдвиг по оси Z (отрицательное значение отдаляет элемент). Если указать значение 0 для любой оси, то элемент не будет по ней сдвигаться, по аналогии с другими функциями.
Результат нашего примера:
Перспектива обзора элемента
Давайте более детально рассмотрим функцию perspective(), она как мы выяснили ранее, определяет перспективу обзора элемента, создавая для пользователя иллюзию глубины. Чем больше значение, указанное для функции перспективы, тем дальше от пользователя расположен элемент. Значение должно быть больше нуля.
Рассмотрим пример:
<!DOCTYPE html> <html> <head> <meta charset = "UTF-8"> <title>Указание перспективы обзора элемента</title> <style> .static { display: inline-block; /* блочно-строчные элементы (выстраиваем элементы в линейку) */ margin: 10px; /* внешние отступы со всех сторон */ background: gray; /* цвет заднего фона */ } div { width: 180px; /* ширина элемента */ height: 100px; /* высота элемента */ line-height: 100px; /* высота строки (выраывниваем по вертикали) */ text-align: center; /* горизонтальное выравнивание текста по центру */ transition: 0.2s; /* переходный эффект составляет 200 миллисекунд (0,2 секунды) */ } .test2, .test4, .test6 {background: orange;} /* цвет заднего фона */ .test, .test3, .test5 {background: plum;} /* цвет заднего фона */ .test:hover { transform: perspective(50px) rotateX(45deg); /* используем несколько функций преобразования для элемента при наведении (перспектива, поворот по оси X) */ } .test2:hover { transform: perspective(100px) rotateX(45deg); /* используем несколько функций преобразования для элемента при наведении (перспектива, поворот по оси X) */ } .test3:hover { transform: perspective(200px) rotateX(45deg); /* используем несколько функций преобразования для элемента при наведении (перспектива, поворот по оси X) */ } .test4:hover { transform: perspective(300px) rotateX(45deg); /* используем несколько функций преобразования для элемента при наведении (перспектива, поворот по оси X) */ } .test5:hover { transform: perspective(400px) rotateX(45deg); /* используем несколько функций преобразования для элемента при наведении (перспектива, поворот по оси X) */ } .test6:hover { transform: perspective(500px) rotateX(45deg); /* используем несколько функций преобразования для элемента при наведении (перспектива, поворот по оси X) */ } </style> </head> <body> <div class = "static"><div class = "test">perspective(50px)*</div></div> <div class = "static"><div class = "test2">perspective(100px)*</div></div> <div class = "static"><div class = "test3">perspective(200px)*</div></div><br> <div class = "static"><div class = "test4">perspective(300px)*</div></div> <div class = "static"><div class = "test5">perspective(400px)*</div></div> <div class = "static"><div class = "test6">perspective(500px)*</div></div> </body> </html>
Для демонстрации функции perspective() мы дополнительно на элемент воздействуем функцией rotateX(), благодаря, которой поворачиваем элемент по оси X на 45 градусов.
Результат нашего примера:
Матрицы преобразований
В CSS все трансформации (функции, которые контролируют преобразования элементов) основаны на следующих двух функциях:
- для двухмерных преобразований это функция matrix(), она определяет двухмерное преобразование с помощью матрицы из шести значений.
- для трехмерных преобразований это функция matrix3d(), она определяет трехмерное преобразование с помощью матрицы 4x4 из шестнадцати значений в порядке столбцов.
Давайте рассмотрим из чего состоит матрица для двухмерных преобразований:
Рис. 185 Матрица двумерной трансформации.- а и d определяют масштабирование по осям X и Y (scale).
- b и c определяют наклон по осям X и Y (skew).
- e и f определяют сдвиг элемента по осям X и Y (translate).
Когда мы применяем двумерную трансформацию, браузер умножает матрицу на вектор [x, y, 1]. Значения X и Y — координаты конкретной точки в локальном пространстве координат.
Рис. 186 Умножение матрицы на вектор.Матрица для элемента, без преобразования будет выглядеть следующим образом:
transform: matrix(1, 0, 0, 1, 0, 0);
Достаточно будет понять того, что у каждого типа трансформаций — своя собственная матрица, давайте рассмотрим пример их использования:
<!DOCTYPE html> <html> <head> <meta charset = "UTF-8"> <title>Матрицы преобразований в CSS</title> <style> .static { display: inline-block; /* блочно-строчные элементы (выстраиваем элементы в линейку) */ margin: 10px; /* внешние отступы со всех сторон */ background: gray; /* цвет заднего фона */ } div { width: 180px; /* ширина элемента */ height: 100px; /* высота элемента */ line-height: 100px; /* высота строки (выраывниваем по вертикали) */ text-align: center; /* горизонтальное выравнивание текста по центру */ transition: 0.2s; /* переходный эффект составляет 200 миллисекунд (0,2 секунды) */ } .test2, .test4, .test6 {background: orange;} /* цвет заднего фона */ .test, .test3, .test5 {background: plum;} /* цвет заднего фона */ .test:hover { transform: matrix(0.5,0,0,1,0,0); /* используем двухмерную матрицу преобразования при наведении */ } .test2:hover { transform: matrix(1,0,0,1.5,0,0); /* используем двухмерную матрицу преобразования при наведении */ } .test3:hover { transform: matrix(0,-1, 1,0,0,0); /* используем двухмерную матрицу преобразования при наведении */ } .test4:hover { transform: matrix(1,0, -1,1,0,0); /* используем двухмерную матрицу преобразования при наведении */ } .test5:hover { transform: matrix(1,0, 0,1,50,0); /* используем двухмерную матрицу преобразования при наведении */ } .test6:hover { transform: matrix3d(0.3, -0.4, 0.8, 0, 0.2, 0.9, 0.4, 0, -0.9, 0, 0.4, 0, 0, 0, 0, 1); /* используем трехмерную матрицу преобразования при наведении */ } </style> </head> <body> <div class = "static"><div class = "test">matrix(0.5,0,0,1,0,0)</div></div> <div class = "static"><div class = "test2">matrix(1,0,0,1.5,0,0)</div></div> <div class = "static"><div class = "test3">matrix(0,-1, 1,0,0,0)</div></div><br> <div class = "static"><div class = "test4">matrix(1,0, -1,1,0,0)</div></div> <div class = "static"><div class = "test5">matrix(1,0, 0,1,50,0)</div></div> <div class = "static"><div class = "test6">matrix3d()</div></div> </body> </html>
В этом примере с помощью функций matrix() и matrix3d() мы производим различные двухмерные и трехмерные трансформации элементов.
Результат нашего примера:
При необходимости, вы можете получить более подробное описание функции matrix3d() здесь (на русском), либо в стандарте W3C - разделы 20 и 21.
Точка преобразования элемента
При использовании любого преобразования, браузер пользователя по умолчанию использует в качестве точки начала преобразования центр элемента. В CSS свойство transform-origin позволяет указать произвольное начало координат преобразования элемента. Вспомните, похожее поведение имеет свойство background-position, которое позволяет задать положение (позицию) фонового изображения, мы подробно рассматривали это свойство в статье "Работа с фоном элемента в CSS".
Обратите внимание, что свойство transform-origin используется только совместно со свойством transform, которое применяет двухмерные или трехмерные трансформации к элементу (функции преобразования элемента).
Для наглядности логика работы свойства transform-origin отображена на изображении:
Рис. 188 Логика работы свойства transform-origin.- Первое значение указывает положение на оси X. Допускается использование числовых значений длины (допустимые единицы измерения CSS), процентное соотношение или одно из следующих трех ключевых слов: left (указывает 0% длины по оси X), center (указывает среднюю точку) или right (указывает 100%). Может быть указано вторым значением при использовании ключевых слов. Допускаются отрицательные значения.
- Второе значение указывает положение на оси Y. Допускается использование числовых значений длины (допустимые единицы измерения CSS), процентное соотношение или одно из следующих трех ключевых слов: top (указывает 0% длины по оси Y), center (указывает среднюю точку) или bottom (указывает 100%). Может быть указано первым значением при использовании ключевых слов. Допускаются отрицательные значения.
- Третье значение указывает положение на оси Z. Допускается использование только числовых значений длины (допустимые единицы измерения CSS). Допускаются отрицательные значения.
Перейдем к примеру.
<!DOCTYPE html> <html> <head> <meta charset = "UTF-8"> <title>Пример изменения точки преобразования элемента</title> <style> .static { display: inline-block; /* блочно-строчные элементы (выстраиваем элементы в линейку) */ margin: 10px; /* внешние отступы со всех сторон */ background: gray; /* цвет заднего фона */ } div { width: 180px; /* ширина элемента */ height: 100px; /* высота элемента */ line-height: 100px; /* высота строки (выраывниваем по вертикали) */ text-align: center; /* горизонтальное выравнивание текста по центру */ transition: 0.2s; /* переходный эффект составляет 200 миллисекунд (0,2 секунды) */ } .test2, .test4, .test6 {background: orange;} /* цвет заднего фона */ .test, .test3, .test5 {background: plum;} /* цвет заднего фона */ .test:hover { transform: rotate(15deg); /* поворачиваем элемент при наведении */ transform-origin: 50% 50% 0; /* изменяем точку преобразования элемента при наведении */ } .test2:hover { transform: rotate(15deg); /* поворачиваем элемент при наведении */ transform-origin: left top; /* изменяем точку преобразования элемента при наведении */ } .test3:hover { transform: rotate(15deg); /* поворачиваем элемент при наведении */ transform-origin: center bottom; /* изменяем точку преобразования элемента при наведении */ } .test4:hover { transform: rotate(15deg); /* поворачиваем элемент при наведении */ transform-origin: 100% 0%; /* изменяем точку преобразования элемента при наведении */ } .test5:hover { transform: rotate(15deg) perspective(500px); /* используем несколько функций преобразования для элемента при наведении (перспектива, поворот) */ transform-origin: 50% 50% -250px; /* изменяем точку преобразования элемента при наведении */ } .test6:hover { transform: rotate(15deg) perspective(500px); /* используем несколько функций преобразования для элемента при наведении (перспектива, поворот) */ transform-origin: 50% top 250px; /* изменяем точку преобразования элемента при наведении */ } </style> </head> <body> <div class = "static"><div class = "test">50% 50% 0</div></div> <div class = "static"><div class = "test2">left top</div></div> <div class = "static"><div class = "test3">center bottom</div></div><br> <div class = "static"><div class = "test4">100% 0%</div></div> <div class = "static"><div class = "test5">50% 50% -250px</div></div> <div class = "static"><div class = "test6">50% top 250px</div></div> </body> </html>
В этом примере мы использовали для свойства transform-origin различные значения, которые определяют точку начала преобразования элемента. Для пятого и шестого блока мы дополнительно указали значение функции преобразования perspective() для возможности демонстрации изменения точки преобразования по оси Z.
Результат нашего примера:
Обращаю Ваше внимание на то, что свойство transform-origin не влияет на те элементы, которые находятся только под действием функции преобразования translate().
Мы с Вами рассмотрели все функции преобразования элементов, которые в настоящее время используются в той, или иной степени. Если Вас заинтересовала эта тема, вы можете самостоятельно изучить такие современные, но мало используемые свойства CSS, как:
- perspective - определяет перспективу обзора элемента, создавая для пользователя иллюзию глубины (значение перспективы устанавливается для вложенных (дочерних) элементов (находящихся под действием трехмерной трансформации), а не к самому элементу, как мы это делали с использованием функции perspective().
- perspective-origin - устанавливает начало координат для свойства перспективы (позиционирование перспективы происходит для вложенных (дочерних) элементов).
- transform-style - определяет как вложенные (дочерние) элементы отображаются в трехмерном пространстве. По умолчанию все дочерние элементы отображаются плоскими в двухмерной плоскости (находятся в плоскости самого элемента), свойство позволяет вложенным (дочерним) элементам изменить это поведение и трансформироваться в их собственной трёхмерной плоскости (Internet Explorer не поддерживает).
Вопросы и задачи по теме
Перед тем как перейти к изучению следующей темы пройдите практические задания:
- Для выполнения задания вам понадобится скачать архив и скопировать содержимое архива (HTML файл) в любую папку на вашем жестком диске:
Используя полученные знания составьте следующий документ в котором элементы имеют различную трансформацию, продвинутым заданием будет считаться трансформация родительского элемента:
Подсказка:
- Для начала Вам необходимо спозиционировать родительский элемент и задать его детям, абсолютное позиционирование. Эту тему мы подробно рассматривали ранее в статье "Позиционирование элементов в CSS".
- Вам необходимо для двух вложенных элементов применить трансформацию с функцией rotate(), а для двух других translateY(). Кроме того, необходимо для двух элементов изменить точку начала преобразования.
- Для того, чтобы запустить трансформацию родительского элемента, после того как закончится трансформация вложенных элементов, Вам необходимо указать для всех элементов свойство эффекта перехода - transition, при том для родительского элемента необходимо задать задержку начала эффекта перехода между двумя состояниями. Эту тему мы подробно рассматривали ранее в статье "Переходные эффекты в CSS".
Если у Вас возникают трудности при выполнении практического задания, Вы всегда можете открыть пример в отдельном окне и проинспектировать страницу, чтобы понять какой код CSS был использован.
Кажется, вы используете блокировщик рекламы :(
Этот ресурс не является коммерческим проектом и развивается на энтузиазме автора сайта, который посвящает все свое свободное время этому проекту.
Добавьте, пожалуйста, basicweb.ru в исключения блокировщика рекламы, этим вы поможете развитию проекта.