CSS-функция `anchor()`
Базовая поддержка Ограниченная доступность
Эта функция не входит в базовый набор, поскольку не работает в некоторых наиболее широко используемых браузерах.
anchor() — это CSS-функция, которую можно использовать в значениях свойств смещения элемента, позиционируемого относительно якоря. Она возвращает значение длины относительно положения краёв связанного с ним якорного элемента.
Синтаксис
/* side or percentage */ top: anchor(bottom); top: anchor(50%); top: calc(anchor(bottom) + 10px) inset-block-end: anchor(start); /* side of named anchor */ top: anchor(--my-anchor bottom); inset-block-end: anchor(--my-anchor start); /* side of named anchor with fallback */ top: anchor(--my-anchor bottom, 50%); inset-block-end: anchor(--my-anchor start, 200px); left: calc(anchor(--my-anchor right, 0%) + 10px);
Параметры
Синтаксис функции anchor() выглядит следующим образом:
anchor(<anchor-name> <anchor-side>, <length-percentage>)
Параметры:
-
<anchor-name>Необязательно -
Значение свойства
anchor-nameякорного элемента, относительно которого нужно расположить сторону элемента. Это значение типа<dashed-ident>. Если параметр не указан, используется якорь по умолчанию элемента, заданный в его свойствеposition-anchorили связанный с элементом с помощью HTML-атрибутаanchor.Примечание: указание
<anchor-name>внутри функцииanchor()не связывает элемент с якорем, а только позиционирует элемент относительно этого якоря. Для создания такой связи по-прежнему необходимо CSS-свойствоposition-anchorили HTML-атрибутanchor. -
<anchor-side> - Задаёт сторону якоря или относительное расстояние от стороны
start, относительно которой позиционируется элемент. Если используется физическое или логическое значение, несовместимое со свойством смещения, в котором задана функцияanchor(), используется резервное значение. Допустимые значения:-
top - Верхняя сторона якорного элемента.
-
right - Правая сторона якорного элемента.
-
bottom - Нижняя сторона якорного элемента.
-
left - Левая сторона якорного элемента.
-
inside - Та же сторона, что и у свойства смещения.
-
outside - Противоположная сторона относительно свойства смещения.
-
start - Логическое начало контейнерного блока якорного элемента вдоль оси свойства смещения, в котором задана функция
anchor(). -
end - Логический конец контейнерного блока якорного элемента вдоль оси свойства смещения, в котором задана функция
anchor(). -
self-start - Логическое начало содержимого якорного элемента вдоль оси свойства смещения, в котором задана функция
anchor(). -
self-end - Логический конец содержимого якорного элемента вдоль оси свойства смещения, в котором задана функция
anchor(). -
center - Центр оси свойства смещения, в котором задана функция
anchor(). -
<percentage> - Задаёт расстояние в процентах от начала содержимого элемента вдоль оси свойства смещения, в котором задана функция
anchor().
-
-
<length-percentage>Необязательно - Задаёт резервное значение, которое функция должна использовать, если функция
anchor()иначе оказалась бы недопустимой.
Возвращаемое значение
Возвращает значение типа <length>.
Описание
Функция anchor() позволяет позиционировать элемент относительно краёв якорного элемента. Она допустима только в значениях свойств смещения, заданных для элементов с абсолютным или фиксированным позиционированием.
Она возвращает значение типа <length>, задающее расстояние от края контейнерного блока, соответствующего свойству смещения, до края якорного элемента, указанного значением <anchor-side>. Поскольку функция возвращает значение типа <length>, её можно использовать в других функциях CSS, принимающих значения длины, включая calc(), clamp() и другие.
Если якоря с именем, указанным в <anchor-name>, не существует или если с позиционируемым элементом не связан якорь (например, с помощью свойства position-anchor), первый параметр считается недопустимым, и используется резервное значение <length-percentage>, если оно доступно. Например, если для позиционируемого элемента задано top: anchor(bottom, 50px), но с ним не связан якорь, будет использовано резервное значение, поэтому вычисленное значение top будет равно 50px.
Подробные сведения о возможностях и использовании якорей см. в модуле Позиционирование якорей в CSS и руководстве Использование позиционирования якорей в CSS.
Свойства, принимающие значения функции anchor()
К свойствам смещения CSS, которые принимают функцию anchor() в качестве компонента значения, относятся:
topleftbottomright- сокращённое свойство
inset inset-block-startinset-block-end- сокращённое свойство
inset-block inset-inline-startinset-inline-end- сокращённое свойство
inset-inline
Совместимость свойств смещения и значений <anchor-side>
При использовании функции anchor() в значении свойства смещения параметр <anchor-side>, указанный внутри функции anchor(), должен быть совместим с осью, к которой относится свойство смещения.
Это означает, что физические значения <anchor-side> можно использовать в значениях физических свойств смещения, если у свойства и <anchor-side> совпадает направление оси. Иными словами, стороны top и bottom недопустимы в значениях свойств left и right, а стороны left и right недопустимы в значениях свойств top и bottom. Например, top: anchor(bottom) допустимо, поскольку оба значения относятся к вертикальной оси, а top: anchor(left) недопустимо, поскольку left относится к горизонтальной оси. Если задано top: anchor(left, 50px), будет использовано резервное значение, поэтому вычисленное значение top будет равно 50px. Если резервное значение не задано, свойство смещения ведёт себя так, как если бы ему было присвоено значение auto.
Логические значения <anchor-side> можно использовать как с логическими, так и с физическими свойствами смещения, поскольку логические значения <anchor-side> относятся к соответствующей оси свойства смещения независимо от того, является ли это свойство логическим или физическим. Например, top: anchor(start), top: anchor(self-end), inset-block-start: anchor(end) и inset-inline-end: anchor(self-start) допустимы.
Ситуация усложняется при использовании физических параметров <anchor-side> в значениях логических свойств смещения: физическая сторона должна соответствовать оси, к которой относится свойство смещения в текущем режиме письма. Например:
- В горизонтальном режиме письма направление блока — сверху вниз, поэтому
inset-block-end: anchor(bottom)допустимо, аinset-block-end: anchor(left)несовместимо. Если заданоinset-block-end: anchor(left, 50px), вычисленное значение будет50px, и позиционируемый элемент будет расположен на расстоянии50pxот конца блока (нижней стороны) ближайшего позиционированного предка или области просмотра — в зависимости от заданного значенияposition. - В вертикальном режиме письма направление блока — справа налево или слева направо, поэтому
inset-block-end: anchor(left)допустимо, аinset-block-end: anchor(top)несовместимо. Если заданоinset-block-end: anchor(top, 50px), вычисленное значение будет50px, и позиционируемый элемент будет расположен на расстоянии50pxот конца блока (левой или правой стороны в зависимости от режима письма) ближайшего позиционированного предка или области просмотра — в зависимости от заданного значенияposition.
Чтобы избежать путаницы с этими значениями, рекомендуется использовать логические свойства смещения с логическими значениями <anchor-side>, а физические свойства смещения — с физическими значениями <anchor-side>. По возможности отдавайте предпочтение логическим значениям, поскольку они лучше подходят для интернационализации.
Значения center и <percentage> допустимы в функции anchor() для всех логических и физических свойств смещения.
В таблице ниже перечислены свойства смещения и совместимые с ними значения параметра <anchor-side>. Здесь приведены только развернутые свойства смещения; из них составляются значения сокращённых свойств смещения.
| Свойство смещения | Совместимое значение <anchor-side> |
|---|---|
| Все | center |
| Все | <percentage> |
top и bottom
|
top, bottom, start, end, self-start, self-end
|
left и right
|
left, right, start, end, self-start, self-end
|
inset-block-start и inset-block-end
|
start, end, self-start и self-endtop и bottom в горизонтальном режиме письмаleft и right в вертикальном режиме письма |
inset-inline-start и inset-inline-end
|
start, end, self-start и self-endleft и right в горизонтальном режиме письмаtop и bottom в вертикальном режиме письма |
Использование anchor() для позиционирования всплывающих окон
При использовании anchor() для позиционирования всплывающих окон имейте в виду, что стили всплывающих окон по умолчанию могут конфликтовать с нужным вам расположением. Чаще всего этому мешают стили свойств margin и inset, поэтому рекомендуется сбросить их:
.positionedPopover {
margin: 0;
inset: auto;
}
Рабочая группа CSS рассматривает способы отказаться от этой обходной меры.
Использование anchor() внутри calc()
Если функция anchor() ссылается на сторону якоря по умолчанию, при необходимости можно задать margin, чтобы создать промежуток между краями якоря и позиционируемого элемента. Также для добавления промежутка можно использовать функцию anchor() внутри функции calc().
В этом примере правый край позиционируемого элемента выравнивается по левому краю якорного элемента, а затем добавляется внешний отступ, чтобы создать промежуток между краями:
.positionedElement {
right: anchor(left);
margin-right: 10px;
}
В этом примере логический нижний край позиционируемого элемента располагается на расстоянии 10px от логического верхнего края якорного элемента:
.positionedElement {
inset-block-end: calc(anchor(start) + 10px);
}
Позиционирование элемента относительно нескольких якорей
Элемент можно позиционировать относительно нескольких якорей, указав разные значения <anchor-name> в функции anchor() разных свойств смещения одного элемента (см. раздел Элемент, позиционируемый относительно нескольких якорей ниже). Это позволяет реализовать полезные функции, например маркеры перетаскивания в углах позиционируемого элемента, с помощью которых его можно изменить в размере.
Позиционируемый элемент можно расположить относительно нескольких якорных элементов, но связать его можно только с одним якорем, заданным свойством position-anchor (или HTML-атрибутом anchor). При прокрутке страницы элемент будет прокручиваться вместе с этим якорем; этот якорь также можно использовать, чтобы управлять условным скрытием элемента.
Формальный синтаксис
<anchor()> = anchor( <anchor-name>? && <anchor-side>, <length-percentage>? ) <anchor-name> = <dashed-ident> <anchor-side> = inside | outside | top | left | right | bottom | start | end | self-start | self-end | <percentage> | center <length-percentage> = <length> | <percentage>
Примеры
Типичное использование
В этом примере функция anchor() используется, чтобы задать высоту элемента, позиционируемого относительно якоря, равной высоте якоря: нижняя и верхняя стороны элемента привязываются к нижней и верхней сторонам якоря. Затем функция anchor() внутри функции calc() используется для смещения позиционируемого относительно якоря элемента.
HTML
Мы добавляем элемент <div>, который будет якорем, и элемент <p>, который мы расположим относительно этого якоря:
<div class="anchor">⚓︎</div> <p class="positionedElement">This is a positioned element.</p>
CSS
Чтобы связать элементы, мы задаём значение anchor-name якорного элемента в качестве значения свойства position-anchor позиционируемого элемента, а затем задаём три свойства смещения для элемента, позиционируемого относительно якоря. Первые два свойства располагают верхний край элемента вплотную к верхнему краю якоря, а нижний край — вплотную к нижнему краю якоря. В третьем свойстве смещения функция anchor() используется внутри функции calc(), чтобы расположить левый край элемента на расстоянии 10px справа от правого края якоря.
.anchor {
anchor-name: --infobox;
background: palegoldenrod;
font-size: 3em;
width: fit-content;
border: 1px solid goldenrod;
}
.positionedElement {
position: absolute;
position-anchor: --infobox;
margin: 0;
top: anchor(top);
left: calc(anchor(right) + 10px);
bottom: anchor(bottom);
background-color: olive;
border: 1px solid darkolivegreen;
}
Результат
Сравнение разных значений anchor-side
В этом примере элемент позиционируется относительно якоря с помощью свойств top и left, заданных с использованием функций anchor(). Здесь также есть два раскрывающихся списка, позволяющих менять значения <anchor-side> в этих функциях anchor() и наблюдать за результатом.
HTML
Мы задаём два элемента <div>: один с классом anchor, другой — с классом infobox. Первый будет якорным элементом, а второй — связанным с ним позиционируемым элементом.
Кроме того, мы добавляем текст-заполнитель вокруг двух элементов <div>, чтобы увеличить высоту <body> и сделать его прокручиваемым. В этом примере также есть два элемента <select>, которые создают раскрывающиеся списки для выбора разных значений <anchor-side>, используемых для позиционирования элемента. Для краткости мы скрыли текст-заполнитель и элементы <select>.
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<div class="anchor">⚓︎</div> <div class="infobox"> <p>This is an information box.</p> </div>
<p>
Nisi quis eleifend quam adipiscing vitae proin sagittis nisl rhoncus. In arcu
cursus euismod quis viverra nibh cras pulvinar. Vulputate ut pharetra sit amet
aliquam.
</p>
<p>
Malesuada nunc vel risus commodo viverra maecenas accumsan lacus. Vel elit
scelerisque mauris pellentesque pulvinar pellentesque habitant morbi
tristique. Porta lorem mollis aliquam ut porttitor. Turpis cursus in hac
habitasse platea dictumst quisque. Dolor sit amet consectetur adipiscing elit.
Ornare lectus sit amet est placerat. Nulla aliquet porttitor lacus luctus
accumsan.
</p>
<form>
<div>
<label for="top-anchor-side">
Choose a vertical <code>anchor()</code> value:
</label>
<select id="top-anchor-side" name="top-anchor-side">
<option value="top">top: anchor(top)</option>
<option value="bottom" selected>top: anchor(bottom)</option>
<option value="start">top: anchor(start)</option>
<option value="end">top: anchor(end)</option>
<option value="center">top: anchor(center)</option>
<option value="0%">top: anchor(0%)</option>
<option value="25%">top: anchor(25%)</option>
<option value="50%">top: anchor(50%)</option>
<option value="75%">top: anchor(75%)</option>
<option value="100%">top: anchor(100%)</option>
</select>
</div>
<div>
<label for="left-anchor-side">
Choose a horizontal <code>anchor()</code> value:
</label>
<select id="left-anchor-side" name="left-anchor-side">
<option value="left">left: anchor(left)</option>
<option value="right" selected>left: anchor(right)</option>
<option value="self-start">left: anchor(self-start)</option>
<option value="self-end">left: anchor(self-end)</option>
<option value="center">left: anchor(center)</option>
<option value="0%">left: anchor(0%)</option>
<option value="25%">left: anchor(25%)</option>
<option value="50%">left: anchor(50%)</option>
<option value="75%">left: anchor(75%)</option>
<option value="100%">left: anchor(100%)</option>
</select>
</div>
</form>
CSS
Мы объявляем anchor <div> якорным элементом, задавая ему имя якоря с помощью свойства anchor-name. Затем мы связываем его с позиционируемым элементом, задавая то же значение для свойства position-anchor. top: anchor(--my-anchor bottom) располагает верхний край информационного блока вплотную к нижнему краю якоря, а left: anchor(right) располагает левый край информационного блока вплотную к правому краю якоря. Так задаётся начальное положение, которое будет изменяться при выборе других значений в раскрывающихся списках.
.anchor {
font-size: 2rem;
color: white;
text-shadow: 1px 1px 1px black;
background-color: hsl(240 100% 75%);
width: 100px;
height: 100px;
text-align: center;
line-height: 100px;
border-radius: 10px;
border: 1px solid black;
padding: 3px;
}
body {
width: 80%;
margin: 0 auto;
}
form {
background: white;
border: 1px solid black;
padding: 5px;
position: fixed;
top: 0;
right: 2px;
}
select {
display: block;
margin-top: 5px;
}
form div:last-child {
margin-top: 10px;
}
.infobox {
color: darkblue;
background-color: azure;
border: 1px solid #dddddd;
padding: 10px;
border-radius: 10px;
font-size: 1rem;
}
.anchor {
anchor-name: --my-anchor;
}
.infobox {
position: fixed;
position-anchor: --my-anchor;
top: anchor(--my-anchor bottom);
left: anchor(right);
}
JavaScript
Мы отслеживаем событие change, возникающее при выборе нового значения <anchor-side>, и задаём выбранное значение в качестве <anchor-side> функции anchor() в соответствующем свойстве смещения информационного блока (top или left).
const infobox = document.querySelector(".infobox");
const topSelect = document.querySelector("#top-anchor-side");
const leftSelect = document.querySelector("#left-anchor-side");
topSelect.addEventListener("change", (e) => {
const anchorSide = e.target.value;
infobox.style.top = `anchor(--my-anchor ${anchorSide})`;
});
leftSelect.addEventListener("change", (e) => {
const anchorSide = e.target.value;
infobox.style.left = `anchor(${anchorSide})`;
});
Результат
Выбирайте разные значения в раскрывающихся списках, чтобы увидеть, как они влияют на положение информационного блока.
Элемент, позиционируемый относительно нескольких якорей
В этом примере элемент позиционируется относительно двух разных якорей, которые задают положение верхнего левого и нижнего правого углов элемента, позиционируемого относительно якоря. Якоря можно перемещать с помощью клавиатуры или перетаскивать, изменяя размер позиционируемого элемента.
HTML
Всего мы задаём три элемента <div>. Первые два имеют класс anchor и будут объявлены якорями; каждому из них присвоено отдельное значение id, чтобы задать для них разные параметры позиционирования. Последний элемент <div> имеет класс infobox и будет позиционируемым элементом. Мы добавляем атрибут tabindex, чтобы элементы могли получать фокус клавиатуры.
<div id="anchor1" class="anchor" tabindex="0">⚓︎1</div> <div id="anchor2" class="anchor" tabindex="0">⚓︎2</div> <div class="infobox"> <p>This is an information box.</p> </div>
CSS
body {
width: 150vw;
height: 150vh;
}
.anchor {
font-size: 1rem;
color: white;
text-shadow: 1px 1px 1px black;
background-color: hsl(240 100% 75%);
width: fit-content;
border-radius: 10px;
border: 1px solid black;
padding: 3px;
&:focus {
background-color: hsl(60 100% 75%);
}
}
.infobox {
color: darkblue;
background-color: azure;
border: 1px solid #dddddd;
padding: 10px;
border-radius: 10px;
font-size: 1rem;
}
Каждому якорю задаётся своё значение свойства anchor-name, значение свойства position равное absolute и отдельные значения свойств смещения, чтобы расположить якоря прямоугольником.
.anchor {
position: absolute;
}
#anchor1 {
anchor-name: --my-anchor1;
top: 50px;
left: 100px;
}
#anchor2 {
anchor-name: --my-anchor2;
top: 200px;
left: 350px;
}
Элементу, позиционируемому относительно якоря, свойству position задаётся значение fixed, и он связывается с одним якорем с помощью свойства position-anchor. Позиционирование относительно двух якорей задаётся двумя разными значениями <anchor-name> в функциях anchor(), установленных в свойствах смещения элемента. В этом примере для параметра <anchor-side> используются значения <percentage>, задающие расстояние от начала оси свойства смещения, в котором задана функция.
.infobox {
position-anchor: --my-anchor1;
position: fixed;
top: anchor(--my-anchor1 100%);
left: anchor(--my-anchor1 100%);
bottom: anchor(--my-anchor2 0%);
right: anchor(--my-anchor2 0%);
}
// grab all the anchors and make each one draggable
const anchors = document.querySelectorAll(".anchor");
anchors.forEach((anchor) => makeDraggable(anchor));
function makeDraggable(elem) {
let pos1, pos2, pos3, pos4;
elem.onmousedown = dragMouseDown;
elem.addEventListener("keyup", (e) => {
switch (e.key) {
case "d":
elem.style.left = `${elem.offsetLeft + 5}px`;
break;
case "a":
elem.style.left = `${elem.offsetLeft - 5}px`;
break;
case "w":
elem.style.top = `${elem.offsetTop - 5}px`;
break;
case "s":
elem.style.top = `${elem.offsetTop + 5}px`;
break;
}
e.preventDefault();
});
function elementMove(e) {
console.dir(e);
// calculate the new cursor position:
pos1 = pos3 - e.offsetLeft;
pos2 = pos4 - e.offsetTop;
pos3 = e.offsetLeft;
pos4 = e.offsetTop;
// set the element's new position:
elem.style.top = `${elem.offsetTop - pos2}px`;
elem.style.left = `${elem.offsetLeft - pos1}px`;
}
function dragMouseDown(e) {
// get the mouse cursor position at startup:
pos3 = e.clientX;
pos4 = e.clientY;
document.onmouseup = closeDragElement;
// call a function whenever the mouse moves:
document.onmousemove = elementDrag;
}
function elementDrag(e) {
// calculate the new cursor position:
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
// set the element's new position:
elem.style.top = `${elem.offsetTop - pos2}px`;
elem.style.left = `${elem.offsetLeft - pos1}px`;
}
function closeDragElement() {
// stop moving when mouse button is released:
document.onmouseup = null;
document.onmousemove = null;
}
}
Результат
Позиционируемый элемент располагается относительно обоих якорных элементов. Перетаскивайте их мышью или переходите к ним клавишей Tab и перемещайте клавишами W, A, S и D вверх, вниз, влево и вправо. Посмотрите, как это меняет их положение и, следовательно, область позиционируемого элемента. Прокрутите страницу, чтобы увидеть, как сохраняется положение всех элементов.
Примечание: этот пример служит для проверки концепции и не предназначен для использования в рабочем коде. Помимо прочих недостатков, пример перестаёт работать, если попытаться переместить якоря так, чтобы они пересеклись по горизонтали или вертикали.
Спецификации
Совместимость с браузерами
| Настольные | Мобильные | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome для Android | Firefox для Android | Opera для Android | Safari на iOS | Samsung Internet | WebView для Android | WebView на iOS | |
anchor |
125 |
125 |
147 |
111 |
26 |
125 |
147 |
83 |
26 |
27.0 |
125 |
26 |
is_transitionable |
125 |
125 |
Нет |
111 |
26 |
125 |
Нет |
83 |
26 |
27.0 |
125 |
26 |
См. также
position-anchorposition-area- функция
anchor-size() - руководство Использование позиционирования якорей в CSS
- руководство Резервные варианты и условное скрытие при переполнении
- модуль Позиционирование якорей в CSS
© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/anchor