Позиционирование и двумерные трансформации — Тренажёр 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
Мой Паблик ВК
Заходите куда удобно вам и подписывайтесь! Еще раз спасибо за внимание!