Абсолютно относительно

В ЦССе постоянно приходится делать абсолютно позиционированные элементы внутри относительно позиционированных, чтобы «привязаться» к какой-то плавающей точке в нормал-флоу. Это тупизм, потому что это вынуждает в разметке добавлять лишние элементы. Например, нам надо пририсовать к слову значок суффикса, который у нас есть в виде гифовой картинки. Вот что хочется писать в разметке:

слов<img class="suffix" src="i/suffix.gif" />ечко

Но что написать в стилях?

.suffix {
  position: ???
  width: 1.5em; /* на три буквы чтоб */
  bottom: -1em;
}

Относительно позиционированный элемент занимает собой места в нормал-флоу столько же, сколько непозиционированный, а потом может быть сдвинут относительно этого места так, что нормал-флоу этого не заметит. В нашем случае это не подходит, потому что будет разрыв между «слов» и «ечко» шириной в картинку.

Абсолютно позиционированный элемент не участвует в нормал-флоу и позиционируется относительно ближайшего позиционированного предка, либо относительно границ браузера, если позиционированных предков нет. Это нам тоже не подходит, так как нам надо, чтобы позиционировалась картинка именно относительно той точки в слове, куда мы её поставили.

Поэтому всё время приходится делать так:

слов<span class="suffix"><img src="i/suffix.gif" /></span>ечко
.suffix { position: relative }
.suffix img {
  position: absolute;
  width: 1em;
  bottom: -1em;
}

Спан, конечно, красивее было бы закрыть после «ечк», но это не про семантику заметка. Так вот, весь этот спан, получается, существует только для того, чтобы задать «систему координат» для картинки. Но ведь она уже задана тем, куда вы воткнули эту картинку в разметке!

Так почему было не придумать какой-нибудь position: anchored, который бы участвовал в нормал-флоу, но с точки зрения нормал-флоу имел бы размеры 0 на 0? Можно было бы развить идею, введя anchored-x и anchored-y, чтобы, допустим, сделать сноски на поля, висящие на уровне того места, откуда на них ссылаются. Атрибут position: anchored-y означал бы, что left / right для этого элемента имеют смысл по принципу position: absolute; а top / bottom — по принципу position: anchored, т. е. относительно точки, где элемент встретился в разметке. Тогда текст, снесённый на поля, можно было бы размечать так:

Пушкин писал<sup>1</sup><div class="sidenote"><sup>1</sup> В «Капитанской дочке»</div>: «Береги честь смолоду».
.sidenote {
  position: anchored-y;
  left: 110%; /* чтобы отступить от самого текста 10% его ширины */
  top: 0;
}

Почему создатели стандартов придумывают всякую хрень (вроде box-shadow или анимации) раньше, чем решают базовые задачи вёрстки?

Добавлено несколько позже: Оказывается, я ничего не понимаю в вёрстке. Спасибо комментаторам за прояснение ситуации.

Дальше
22 комментария
Сергей Чикуёнок 2010

А если так?

img.suffix {
position: absolute;
width: 1.5em; /* на три буквы чтоб */
margin-bottom: -1em; /* или margin-top: 1em */
}

Илья Бирман 2010

А то, что абсолютные элементы остаются на месте, пока мы не указали координаты — это разве не случайность какая-то? На это можно полагаться?

Максим Захаров 2010

Как насчёт absolute без координат и margin?

Антон Вернигор 2010

Сноски на полях, «висящие на уровне», прекрасно реализуются абсолютным позиционированием.
А суффикс, теоретически, можно попробовать нарисовать фоном. Но тут надо чуть подумать и проанализировать разные ситуации с шириной/высотой строки и т. д.

Владимир Овсянников 2010

Солидарен полностью.
Для упрощения себе жизни советую написать небольшой JS, который ищет теги с определённым классом и обрамляет их «избыточным» тегом.
И красиво и удобно, хотя и через гланды =)

Максим Захаров 2010

Опоздал :)

Антон Вернигор 2010

Кстати, картинка внутри слова, если я правильно помню, является возможной точкой переноса, так что и при этом не все совсем гладко.

Антон Вернигор 2010

Илья,
!!А то, что абсолютные элементы остаются на месте, пока мы не указали координаты — это разве не случайность какая-то? На это можно полагаться?!!
Можно, так и должно быть. Именно поэтому и маргиналии на поля можно вынести абсолютным позиционированием.

Илья Бирман 2010

Крутяк, буду знать.

Александр Карпинский 2010

{

position: relative;
width: 1.5em; /* на три буквы чтоб */
margin-right: -1.5em;
bottom: -1em;
}

Дмитрий 2010

Если абсолютно спозиционированному элементу не указывать координаты, он располагается так, как если бы он находился в нормальном потоке. Как-то так.

Сергей Чикуёнок 2010

По спецификации если для абсолютно спозиционированного элемента не указывать позиционные координаты top/bottom/left/right, то элемент остаётся там, где он был бы в нормальном потоке, при этом, естественно, на поток не влияет. Так что «относительное смещение абсолютных элементов» через margin — вполне законный трюк, я им очень давно пользуюсь.

Konstantyn A. Galayko 2010

Чем плохо так:
.suffix:before {
content: url(i/suffix.gif);
}

Ну кроме ослика, конечно.

Александр Сорокин 2010

Потому что хотят «красиво», а потом уже правильно.

Ярик Глухов 2010

Если нужно разместить рядом с текстом иконку, то достаточно использовать vertical-align c необходимым значением.

Алик Кириллович 2010

Абсолютно позиционированный элемент не участвует в нормал-флоу и позиционируется относительно ближайшего позиционированного предка, либо относительно границ браузера, если позиционированных предков нет.

Позиционированные предки не могут отсутствовать. Формально, «границы браузера» являются таким же «ближайшим позиционированным предком».

Вот цитата (http://www.w3.org/TR/2008/REC-CSS2-20080411/visuren.html#containing-block):

«The root of the document tree generates a box that serves as the initial containing block for subsequent layout».

Георгий Тудоси 2010

слов<span class=«suffix3»>ечк</span>о

{ background: url(suffix3.gif) no-repeat 50% 0%; }

suffix3 вместо suffix подразумевает, что картинки для 1-, 2-, 3- и более (а бывает?) -буквенных суффиксов разные.

Георгий Тудоси 2010

Ха-ха, кавычки в коде затипографились ;-). См. мой недавний стёб на тему: http://yaker.livejournal.com/261175.html

egorinsk 2010

Гм, а по моему так правильно сделать слов[span class=«suffix»]ечко[/span] — а картинку фоном в спане, да и семантичнее. И вообще, img для презентационной графики уже лет 10 никто не использует :) (как и гиф, хехе)

Ярик Глухов 2010

egorinsk прав с небольшой поправкой. Лучше всего это делать спрайтами.

Эдуард Гомоляко 2010

Илья, а где зелененькие бордюры слева у «отмеченных» комментариев? Раньше было удобней читать комментарии )

Сергей К. 2010

Согласен с уважаемыми Георгием и  egorinsk.

Илья, у меня почему-то на http://ilyabirman.ru/meanwhile/ не видна иконка сайта в ФФ. И в Хроме тоже. Не связано ли это с тегом base?

subzey 2010

Алик Кириллович> The root of the document tree generates a box that serves as the initial containing block for subsequent layout
Но он не то же самое, что «границы браузера».

Артём 2010

Илья, пропишите абсолютный адрес фавиконки блога или добавьте её в папку /meanwhile/ ;)

Мои книги