Популярный пост
position-anchor — позиционирование от якоря
Итак, сюрприз. Раньше мы могли позиционировать элементы только от ближайшего предка, имеющего position, отличный от static. А теперь можем вообще от любого элемента на странице. Дальше речь пойдет об экспериментальных технологиях, поэтому проверяйте поддержку свойств на caniuse.com
Редакторский черновик CSS Anchor Positioning
position-anchor
Синтаксис
position-anchor: auto | <dashed-ident>;
auto — Связывает позиционируемый элемент с его неявным элементом привязки, если таковой имеется — например, как установлено нестандартным anchor атрибутом HTML.
<dashed-ident> — Имя элемента привязки, с которым связывается
позиционируемый элемент, должно начинаться с --.
Применение
Свойство position-anchor связывает абсолютно-позиционируемый элемент с любым элементом на странице.
Элемент, относительно которого происходит позиционирование, называется
якорем.
.anchor {
anchor-name: --my-anchor;
}
.label {
position-anchor: --my-anchor;
}
Этот код только связывает элемент с якорем. Чтобы позиционирование заработало, нужно задать абсолютное (absolute)
или фиксированное (fixed) позиционирование для .label
<div class="anchor">Якорь, элемент к которому привязываем</div>
<div class="label">Позиционируемый элемент</div>
.anchor {
anchor-name: --my-anchor;
}
.label {
position: absolute;
position-anchor: --my-anchor;
}
position-area
Свойство position-area объявляет, где размещается позиционируемый элемент относительно якоря. Вот
несколько значений, которые оно принимает:
top left
top right
bottom left
bottom right
Это значения относятся к физическим направлениям: верх, низ, лево, право. Также можно использовать логические значения. Они адаптируются к языкам, написанным справа налево или вертикально:
block-start
block-end
inline-start
inline-end
Например, в качестве альтернативы top right мы можем использовать block-start inline-end. А
также краткие записи start start, start end, end start и так далее. Первый
аргумент всегда относится к оси блока, а второй — к inline.
А также по центру:
top center
bottom center
left center
right center
Можно опустить второй аргумент position-area, чтобы охватить всю сторону якоря, а не только его центр:
top
bottom
left
right
Одиночное значение top это сокращенный эквивалент от top span-all
Ещё один набор аргументов, которые принимает position-area. Они охватывают якорь в одном направлении
span-top
span-bottom
span-left
span-right
See the pen (@Websitio) on CodePen.
Чтобы разместить метку поверх якоря в его центре, нужно задать:
position-area: center center;
position-visibility
Свойство position-visibility используется для определения видимости позиционируемого элемента при
различных условиях.
always — (значение по умолчанию) метка остается видимой, даже если якорь, к которому она привязана, не виден.
anchors-visible — При этом значении метка видна только тогда, когда якорь тоже виден.
no-overflow — метка исчезает, как только начинает выходить за пределы видимости.
Прокручивайте блок, пока якорь не пропадет. (Возможно, потребуется открыть песочницу в отдельном окне). Как только якорь полностью скроется за границей блока, метка тоже пропадёт.
See the pen (@Websitio) on CodePen.
Попробуйте применить другие значения. Чтобы увидеть эффект от no-overflow, поменяйте позицию bottom на top. То есть, если position-area: top; и край метки чуть заходит за верх основного блока, то она исчезает.
See the pen (@Websitio) on CodePen.
position-try-fallbacks
А вот это свойство — просто мечта разработчика 🩷
До этого мы рассматривали примеры, в которых метка просто исчезала. Но ведь хочется сделать так, чтобы она оставалась, не обрезалась и меняла положение на какую-то другую сторону.
Свойство position-try-fallbacks может справиться с этим. Оно принимает следующие значения: flip-block, flip-inline, flip-start. Оно также может принимать альтернативные значения position-area.
При прокручивании блока, в тот момент, когда метка перестает помещаться сверху от якоря, она меняет положение на указанное в position-try-fallbacks.
See the pen (@Websitio) on CodePen.
position-try-fallbacks также принимает альтернативные значения position-area, такие как top right и bottom right.
Можно задавать position-try-fallbacks несколько значений, разделенных запятыми, например, position-try-fallbacks: left, right
flip-block, flip-inline обрабатывает переполнения в вертикальном или горизонтальном направлениях. Но это не очень хорошо работает, когда метка переполняется и вертикально, и горизонтально одновременно. Чтобы справиться с этим, можно добавить третье значение, которое объединяет первые два: flip-block flip-inline.
Получается вот что:
position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
position-try-order
Свойство position-try-order определяет стратегию, используемую для определения того, какой резервный вариант применяется. Значения включают:
normal
most-height
most-width
most-block-size
most-inline-size
По умолчанию резервный вариант активируется, когда метка начинает переполняться. Можно изменить это поведение, чтобы выбрать резервный вариант с самой доступной высотой, например, установив position-try-order на most-height.
.label {
position: absolute;
position-anchor: --my-anchor;
position-area: top;
position-try-fallbacks: bottom;
position-try-order: most-height;
}
position-try
position-try — это сокращенное свойство, которое объединяет position-try-order и position-try-fallbacks
При этом можно указывать только значения position-try-fallbacks — значение position-try-order необязательно.
Таким образом
position-try: most-width left;
можно сократить до
position-try: left;
@position-try
Чудеса ещё не закончились.
Можно определить своё собственное, пользовательское, положение с помощью @position-try
В него может входить что угодно: дополнительные сдвиги top, left, внешние отступы margin, размеры width, max-width, height...
Пользовательское положение нужно назвать используя то же правило, что и в названии якорей, т.е. начиная с --
.label {
position: absolute;
position-anchor: --my-anchor;
position-area: top;
position-try-fallbacks: --custom-bottom;
}
@position-try --custom-bottom {
position-area: bottom;
width: 150px;
margin: 20px;
}
В результате, когда метка сверху, она будет своей обычной ширины. А когда снизу, то ширина станет 150px.
anchor()
top: anchor(bottom);
Таким образом также можно выравнивать метки по якорям. Установка top: anchor(bottom) для метки выровняет её верхний край с нижним краем якоря.
.anchor {
anchor-name: --my-anchor;
}
.label {
position: absolute;
position-anchor: --my-anchor;
top: anchor(bottom);
}
Или с центром якоря:
top: anchor(center);
Также в процентах или пикселях:
top: anchor(30%);
Можно использовать и логический значения start и end
left: anchor(start)
Следующие две записи идентичны и установят метку вниз и направо от правого нижнего угла якоря. Разумеется, только при направлении письма слева направо и сверху вниз.
position-area: bottom right;
top: anchor(end);
left: anchor(end);
anchor-center
Хотя anchor(), в сочетании с top и left, обеспечивает более детальный контроль по сравнению с
position-area, этот подход не позволяет центрировать элемент по его якорю.
Значение anchor() можно использовать с такими свойствами, как justify-self, align-self и place-self. Вот пример горизонтального центрирования с помощью justify-self: anchor-center
.anchor {
anchor-name: --my-anchor;
}
.label {
position: absolute;
position-anchor: --my-anchor;
top: anchor(bottom);
justify-self: anchor-center;
}
anchor-size()
Кроме положения метки можно управлять и её размерами в зависимости от размеров якоря.
Сделаем метку ровно по ширине якоря:
width: anchor-size(width);
Если параметр измерения, в данном случае это ширина, совпадает, то аргумент можно опустить.
width: anchor-size();
Другой вариант использования: установим ширину по высоте.
width: anchor-size(height);
А что ещё?
Сочетание с calc(), min() и max()
А ещё, функции anchor() и anchor-size() можно комбинировать с общими функциями CSS, такими как
calc(), min() и max().
Установим ширину метки в два раза больше ширины якоря:
.label {
position: absolute;
position-anchor: --my-anchor;
top: anchor(bottom);
width: calc(2 * anchor-size(width));
}
Найдём самый нижний из якорей с помощью функции max() и привяжем к нему метку
See the pen (@Websitio) on CodePen.
К одному якорю можно привязать несколько элементов
.anchor {
anchor-name: --my-anchor;
}
.label-1 {
position: absolute;
position-anchor: --my-anchor;
position-area: right top;
}
.label-2 {
position: absolute;
position-anchor: --my-anchor;
position-area: left top;
}
See the pen (@Websitio) on CodePen.
У одного элемента может быть несколько имен якорей
.anchor {
anchor-name: --my-anchor-1, --my-anchor-2;
}
Это позволит перецеплять метки (элементы привязки) с помощью JS.
Один элемент можно привязать к двум якорям
Задачка из игры про якоря.
.anchor-1 { anchor-name: --my-anchor-1; }
.anchor-2 { anchor-name: --my-anchor-2; }
.label {
position: absolute;
left: anchor(--my-anchor-1 end);
top: anchor(--my-anchor-1 start);
right: anchor(--my-anchor-2 start);
bottom: anchor(--my-anchor-2 end);
}
See the pen (@Websitio) on CodePen.
То есть видим ещё один вариант привязки метки к конкретному якорю, без использования position-anchor:
top: anchor(--a2 bottom)
Помощь в изучении
Создатели таких прекрасных игр как Flexbox Froggy и Grid Garden придумали и игру по якорному позиционированию. Рекомендую.
