овёрнутый текст
Некоторое время назад я уже делился этим решением в соцсетях, но на этот раз хочу написать о нём немного подробнее.
Задача: получить повёрнутый на 90 градусов текст.
Проблема: широко известно, что при использовании transform
, блок ведёт себя аналогично сдвигу через position:relative
— продолжает занимать место в потоке по состоянию до трансформации, так что, по факту, изменение происходит только визуальное.
Однако, довольно часто можно захотеть повернуть блок так, чтобы этот поворот влиял и на поток. Например, если мы захотим выстроить несколько вертикальных блоков в ряд, подобно книгам на полке, или если мы захотим использовать повёрнутый текст в качестве заголовков таблицы — в этих случаях нам нужно будет гарантировать, что высота станет равна ширине блока, в то время как ширина — высоте.
У меня получилось решить эту задачу с одним допущением: нужно знать высоту поворачиваемого элемента. В этом случае реализация становится очень простой:
-
Нам понадобится дополнительный элемент. HTML каждого блока будет примерно таким:
<span class="rotated-text"> <span class="rotated-text__inner"> Rotated foo </span> </span>
-
Врапперу мы задаём вот такие стили:
.rotated-text { display: inline-block; overflow: hidden; width: 1.5em; line-height: 1.5; }
Здесь мы делаем элемент инлайн-блочным (это не критично, сработало бы и блочное отображение, но инлайн-блок чаще бывает нужен), затем обрезаем все выступающие части (пригодится позже), далее задаём ширину, равную текущей высоте блока, — то самое допущение (
line-height
тут приведён в качестве примера того, что сейчас определяет высоту блока, а так как все элементы, используемые в примере, однострочные, то это и будет его высотой). -
Внутренний элемент делаем инлайн-блочным, чтобы его ширина схлопнулась по контенту. После чего задаём
white-space:nowrap
для того, чтобы ничего никуда не переносилось (ведь выше мы ограничили ширину), ну и поворачиваем блок, считая верхний левый угол точкой отсчёта (для читаемости свойства приведены без префиксов):.rotated-text__inner { display: inline-block; white-space: nowrap; transform: translate(0,100%) rotate(-90deg); transform-origin: 0 0; }
-
А теперь самое главное: нам нужно сделать этот внутренний элемент «квадратным» — это сделает высоту конечного элемента равной ширине, ну а ширина у нас обрезается враппером. Для того, чтобы сделать наш элемент квадратным, я применяю вот такой вот трюк:
.rotated-text__inner:after { content: ""; float: left; margin-top: 100%; }
Вроде всё довольно просто, но немногие знают о том, что вертикальные маджины и паддинги, заданные в процентах, исчисляются не от высоты блока, а от его ширины. Это поведение редко используется на практике, но у нас как раз тот случай, когда оно пригодилось.
В итоге мы получаем квадратный элемент, обрезаемый враппером до ширины своей прошлой высоты, такой элемент можно использовать в любом контексте, для него будут работать разные свойства вроде text-align
или vertical-align
, так что можно сказать, мы получили «честный» повёрнутый блок.
Ну и несколько живых примеров:
аголовки таблиц
Очевидный пример — компактные по ширине заголовки таблиц.
First th | Some cell | And another |
---|---|---|
Second th | 12 | 12314 |
Third th | 12 | 12314 |
First th | The Second th | Third th |
---|---|---|
2 | 4 | 42 |
12 | 4 | 234 |
13 | 100 | 0 |
«Книжная полка»
Так как повёрнутые блоки получаются «честными», то, если выстроить их в ряд, высота ряда будет равна высоте самого большего из них:
Как-то так.
Ещё раз: мы должны знать высоту блока, так что, если понадобится поворачивать таким образом многострочные блоки, нужно будет соответствующим образом изменять ширину их врапперов.
Кроме того, возможно, этот метод можно заставить работать и в IE — применив матричный фильтр для поворота и добавив элемент в замену псевдоэлементу. Мне лень всё это делать, но вы можете всегда попробовать это сделать сами :)
Вы можете прокомментировать эту статью в Мастодоне.
Опубликовано с метками: #Practical #CSS