Позиционирование и двумерные трансформации — Тренажёр HTML Academy
На время бросаем стройку сеток и погружаемся в стилизацию. Разберёмся как сделать красиво и чтобы всё не рухнуло. Для начала научимся позиционировать и трансформировать элементы.
Этот блок и, как я понимаю, последующие блоки по HTML/CSS идут уже без какой-то сквозной темы. То есть мы начинаем пылесосить нюансы или отдельные фишки, функции. Там недалеко уже и «Продвинутый уровень», где уже совсем тонкости. Правда, тут еще два монструозных блока по JavaScript надо преодолеть, но все по порядку.
Так как нет сквозной темы, то и как-то переформатировать части не получится. Да и не особо уже хочется, особенно после предыдущих частей про построение сеток. На форматировался пока! Поэтому буду конспектировать в указанном в тренажёре порядке. Кстати, почему-то с этой части пропали «Конспекты».
Позиционирование
Очень небольшая, но очень важная часть посвященная свойству position
. Оно отвечает за режим позиционирования элемента и вещь эта достаточно трудноусваиваемая. По крайней мере была для меня.
По умолчанию все элементы находятся в потоке, согласно стандартной блочной модели, и их значение position: static;
— статично. Это обычно опускается, но именно благодаря значению по умолчанию для меня стала понятна логика этого свойства.
Позиция статична static
относительно чего? Относительно своего положения в потоке. При работе со свойством position
, да и не только, стоит отделять сам бокс элемента от его положения — это две сущности. Можно представить, что у каждого элемента есть два слоя — видимый бокс и невидимый, но занимающий место под ним.
И как раз значение static
фиксирует их вместе — бокс занимает место в соответствии с видимыми размерами. Так и работает вся блочная система, это просто и логично. Остальные же значения свойства position
меняют это поведение.
Относительное позиционирование relative
Значение relative
отделяет «видимый» бокс от его занимаемого места или положения в потоке и позволяет управлять позицией относительно него. Это и называется относительным позиционированием. При этом занимаемая место область остается на месте, двигается только видимая.
Мы можем смещать бокс в стороны с помощью свойств top
, bottom
, left
, right
, которые работает только с позиционируемыми элементами и для режима относительного позиционирования работают как интервалы от края бокса до края занимаемой области с указанной стороны.
Если попроще — они работают как margin
, но только для видимой части бокса, оставляя занимаемую область на месте. При этом сам margin
работает — занимаемому месту можно задавать отступы, при этом видимая часть будет корректно реагировать на них.
Абсолютное позиционирование absolute
Совсем иначе работает другой режим — абсолютное позиционирование, которое задается значением position: absolute;
. При этом режиме позиционирования элемент полностью выпадает из потока — занимаемое место пропадает.
Его поведение становится очень похожим на элемент со свойством float
, но в данном случае выпадает и содержимое блока, то есть соседние элементы начинают игнорировать даже контент.
Кстати, свойство position: absolute;
имеет приоритет над свойством float
и при одновременном указании этих свойств float
игнорируется.
Также при установке абсолютного позиционирования любому элементу присваивается свойство блочного бокса display: block;
, даже если изначально это был строчный элемент. Поэтому любым абсолютно позиционированным элементам можно задать размерные свойства width
и height
.
Итак, занимаемого места у нас нет, элемент выпал из потока. По умолчанию, если не задавать свойств позиционирования top
, bottom
, left
и right
, элемент останется на месте, но сожмётся до размера содержимого.
Для position: absolite;
свойства позиционирования работают иначе. Эти свойства работают как интервалы от границы бокса до границы документа или до ближайшего родителя с относительным позиционированием relative
.
Граница документа — это уже я сформулировал по своему, иначе я не могу подобрать термин, так как совсем сухое обозначение «исходный содержащий блок» еще более непонятный. Хотя, кому как, конечно.
Это не viewport — окно браузера, и не исходный родитель <body>
или <html>
, это именно какая-то внешняя граница документа. Я даже проверил поигравшись с позиционированием и margin
'ами для всех тегов.
Фиксированное fixed и липкое sticky позиционирование
Следующее значение свойства position: fixed;
похоже на абсолютное, но отвечает за позиционирование, как раз, относительно окна браузера viewport.
Элемент тоже полностью выпадает из потока и теперь существует как стикер на экране — он не прокручивается с контентом страницы, а остается зафиксированный на экране.
С помощью позиционных свойств top
, left
и др. можно задать расположение элемента относительно краёв экрана. Например, с помощью этих свойств я видел реализацию поп-ап элементов.
В тренажёре его почему-то не рассмотрели, возможно позже, но куда более интересным является «липкое» позиционирование position: sticky;
.
Это своего рода гибрид относительного позиционирования relative
и фиксированного fixed
. Такой элемент фиксируется на экране в рамках своего родительского элемента на позиции заданной с помощью позиционных свойств.
Например, какому-то блоку на странице задано:
.sticky-box { position: sticky; top: 10px; }
До момента попадания блока на позицию 10px
от верха экрана он будет сохранять свойства относительного позиционирования relative
. Но как только прокрутка опустится ниже — элемент прикрепится к верху экрана и будет находится там, пока родительский элемент липкого бокса помещается в экран.
С помощью этого свойства делают разные «липкие» сайдбары, меню, баннеры и много чего еще.
В тренажёре в этой части еще раз упомянуто и разобрано свойство z-index, отвечающее за слои или «плановость» элементов. Честно, не знаю как это назвать. Мы уже разбирали это свойство и ничего нового в этой части не написано, поэтому опустим.
Испытание
В части только одно испытание полностью на понимание абсолютного позиционирования. Нужно расставить элементы и составить надпись по миллиметровке, которую мы уже видели в части про блочную модель.
Двумерные трансформации
Часть почти полностью посвящена свойству transform
отвечающего за какую-либо, собственно, трансформацию элемента. Оно позволяет перемещать, крутить, наклонять и много чего еще, но мы рассмотрим только простейшие варианты.
Отмечу, что половина этой части сделана очень круто в виде игры — трансформируем бедного Пендальфа Синего, кидаемся фаерболами и зачищаем подземелье от монстров. И ребусы разгадываем!
Во второй половине уже делаем на реальных примерах — интерактивные кнопки, иконки и круговое меню. Менее увлекательно, но тоже интересно.
Базовые функции трансформации
Итак, первым заклинанием из фолианта трансформации transform
Пендальфа мы рассмотрим функцию перемещения translate(x, y)
. Она принимает два аргумента — смещение по горизонтали X и по вертикали Y:
.move-block { transform: translate(10px, 20px); /* переместит на 10px вправо и 20px вниз */ }
Отрицательные значения перемещают элемент в обратную сторону, то есть по оси X влево, а по оси Y вверх. В тренажёре повествование начали с них, я про них просто упомяну — для каждой из осей есть своя отдельная функция:
.move-block-x { transform: translateX(-50px); /* 50px влево */ } .move-block-y { transform: translateY(-10px); /* 10px вверх */ }
С помощью этого заклинания Пендальф поразил мишень фаерболом:
Следующее заклинание Пендальфа — это функция поворота объекта rotate()
, которая принимает одно числовое значение в единицах deg
обозначающие градус поворота:
.roll-block { transform: rotate(30deg); }
Положительные значения поворачивают объект по часовой стрелке, а отрицательные против часовой.
Нюанс при использовании функции поворота — элемент поворачивается не только визуально, но с ним поворачивается и его система координат, что влияет на функцию перемещения translate()
:
При одновременном использовании этих функции можно легко запутаться, поэтому желательно заранее продумать — что в итоге нужно сделать с элементом.
С помощью изученных двух заклинаний Пендальф восстановил упавший частокол в городе и отразил нападение волков:
Следующее на очереди заклинание — функция изменения размера scale()
. Она принимает числовые значения множителей размера объекта:
.big-block { transform: scale(2); /* увеличит в 2 раза */ } .small-block { transform: scale(0.5); /* уменьшит или в 2 раза */ } .zero-block { transform: scale(0); /* гипермассивная точка в пространстве */ } .normal-block { transform: scale(1); /* базовое значение */ }
Функция умеет принимать два значения scale(x, y)
и, как и в функции перемещения, они отвечают за размер по горизонтали X и по вертикали Y. Также имеются аналогичные отдельные функции scaleX()
и scaleY()
:
.fat-block { transform: scale(2, 0); /* растянет по горизонтали в 2 раза */ } .thin-block { transform: scaleY(2); /* растянет по вертикали или в 2 раза */ }
С помощью уменьшающего заклинания Пендальф смог проникнуть в подземелье через потайной ход:
У этой функции также есть интересный эффект — если указать отрицательное значение, то элемент начнет «разворачиваться» в обратом направлении от указанного. Таким образом можно создавать зеркальные отражения элемента:
Последними заклинаниями в фолианте трансформация transform
у Пендальфа указаны заклинания функций наклона skewX()
и skewY()
. Они принимают числовое значение градусах deg
и отвечают за наклон элемента вдоль своей оси. Здесь уместнее показать картинкой:
В тренажёре упомянуто общая функция skew()
которая работает по аналогии с предыдущими. Но я её опустил, так как умные дяди и тёти из тренажёра пишут, что эта функция уже рудиментарная и лучше ей не пользоваться.
В итоге, с помощью всех вышеуказанных функций и помощи героя, Пендальф смог одолеть босса подземелья:
Я думаю, всем понятно, что мне очень понравился такой подход в виде РПГ. Конечно, все задания так не сделаешь, но хотелось бы.
Итак, основные заклинания изучили. Их на самом деле там целая библиотека CSS-магии, но их мы рассмотрим позже. Либо в блоке тренажёра про анимацию, который будет в «Продвинутом уровне», либо уже отдельно где-то еще.
Точка отсчета transform-origin
Важным нюансом трансформаций в CSS является понятие точки отсчета элемента. Вышеописанные функции взаимодействуют не совсем с боксом элемента или с его границами, как это, например, работает в свойствах позиционирования для position
.
Функции трансформации работают с точкой отсчета, которая по умолчанию находится по центру элемента. Именно эту точку мы перемещаем с помощью translate()
и вокруг неё крутим элемент с помощью rotate()
.
За расположение этой точки относительно бокса элемента отвечает свойство transform-origin
. Свойство принимает два значения — расположение точки по горизонтали и по вертикали. Оно принимает как размерные значения, например в пикселях px
, процентах %
, так и ключевые слова top
, left
, right
, bottom
и center
.
Как уже написал, по умолчанию точка находится в центре и свойство имеет значение transform-origin: 50% 50%;
. С координатами точки отсчета работает такая же система координат, что и с позиционированием:
.top-left-anchor { transform-orign: 0 0; /* эквивалент */ transform-orign: top left; } .bottom-righ-anchor { transform-orign: 100% 100%; /* эквивалент */ transform-orign: bottom right; }
Только теперь «позиционируется» точка отсчёта в боксе элемента, а не сам элемент в документе.
Для тех, кто работал в графических редакторах типа Photoshop есть супер простой способ понять что такое точка отсчета элемента. У каждого объекта при свободной трансформации Ctrl+T тоже появляется точка отсчета, которая там называется anchor-point. Это по своей сути тоже самое что и transform-origin
.
Остальная часть тренажёра посвящена как раз тренировке использования этого свойства в комбинации с функциями трансформации. А также примеры использования трансформаций на кнопках и, внезапно, игральных картах.
На кнопках, кстати, применяется свойство transition
, о нем мы точно поговорим в блоке «Динамические эффекты», а пока нам его кинули на затравку, мол «Смотрите как можно красиво сделать!», но без детального рассмотрения.
Отдельно упомяну прикольный приём создания нестандартной тени:
Получается реалистичный эффект листа бумаги, который немного выгибается по краям. Я, честно признаюсь, делал этот эффект через .png
и был приятно удивлён такому интересному подходу.
Испытания
Испытания целых три — два с Пендальфом и одно в самом конце уже без Пендальфа. К тому моменту он ушел на пенсию.
Первое испытание в основном на rotate (). Пендальф нашел разорванную карту сокровищ и нам нужно её собрать перемещая и поворачивая куски:
Второе испытание сразу на все функции — из босса выпал какой-то кристалл и раскололся, а мы с Пендальфом его собираем воедино:
Опять, правда, подбор циферок, но тут не так сложно. Главное идти от верхних элементов к нижним.
Третье испытание с игральными картами. Привет, «Селекторы». Правда, в этот раз попроще — надо просто повернуть и переместить карты. На самом деле, слишком простое испытание для последнего в части.
Наконец-то в тренажёрах мы дошли до трансформаций и скоро будут анимации. Я еще по курсу в мобильном приложении понял, что мне максимально нравится именно эта тема!
Огромное вам спасибо за внимание!
Ссылки на предыдущие статьи по HTML Academy:
Знакомство с Веб-разработкой
Знакомство с HTML и CSS
Знакомство с JavaScript
Знакомство с PHP
Таблицы и подробно о формах
Наследование, каскады и селекторы
Блочная модель, поток и сетка на float
Гибкие флексбоксы display: flex
Удобные сетки на гридах display: grid
Пропуск блока «Погружение»
Позиционирование и двумерные трансформации <- Вы здесь
Теневое искусство и линейные градиенты
CSS-фильтры и Кекстаграм
Мастерские
Продвинутые Мастерские
...
Остальные статьи можно посмотреть у меня на главной странице блога.
Также мои соц. сетки, которые я продолжаю вести:
Мой Twitter
Мой Telegram
Мой Паблик ВК
Заходите куда удобно вам и подписывайтесь! Еще раз спасибо за внимание!