2 заметки с тегом

СВГ

Выравнивание подписей с длинами сторон прямоугольника

Заметка о вёрстке специфичного блока в вебе. Большинству такое не пригодится. Пишу, потому что надеюсь показать пользу от применения свойств по назначению.

Верстали блочок с габаритами основания. Будь текст статичен, хватило бы СВГ. Но в английской версии мы помним об американцах и дублируем размеры в футах (и отбиваем дробную часть точкой):

В СВГ всё задаётся строго по координатам, хорошо масштабируется, но не умеет «адаптироваться» под содержание. Поэтому c СВГ не обойтись без двух шаблонов и надежды, что они выдержат подписи любой длины. Можно усилить СВГ скриптом, но для меня это выглядело суперлишним. Казалось, что справятся ХТМЛ с ЦССом.

Исходный ХТМЛ простейший:

<div>
    <span>22 м</span>
    <div></div>
    <span>14 м</span>
</div>

Первое, что решал: как выравнивать подписи по центру стороны. Понятно, что для верхней подписи нужен «text-align: center», но как ограничить длину подписи, чтобы она равнялась длине прямоугольника, а не всего родительского дива? Можно дублировать width для прямоугольника и подписи, но это не DRY и неудобно в поддержке. Выручило свойство box-sizing, которое говорит, как считать ширину и высоту элемента. Добавил родительскому диву «box-sizing: content-box» — указанные размеры элементы не будут включать падинги и обводки.

.rectangle {
    position: relative;
    box-sizing: content-box;
    padding-top: отступ, подходящий под высоту подписи; 
}

Теперь можно наследовать длину родителя и позиционировать подписи вне его:

.rectangle-width, .rectangle-height {
    display: inline-block;
    position: absolute;
    white-space: nowrap;
}

.rectangle-width {
    width: inherit;
    top: 0;
    text-align: center;
}

Если текст длиннее отведённой длины, то он начинается от левого края и благодаря «white-space: nowrap» не переносится.

.rectangle-height {
    left: calc(100% + отступ от фигуры);
    top: 60%;
    transform: translateY(-40%);
}

Transform и top и выравнивают подпись и фигуру по горизонтали. Если родитель без падинга, сработает «top: 50%; transform: translateY(-50%)». В моём случае разницу в 20% нашёл на глаз.

В конце разбираюсь с прямоугольником. Ширину и высоту он наследует у родителя, а ровно поместиться в отведённые границы помогает свойство «box-sizing: border-box», которое, наоборот, включает падинги и обводку.

.rectangle-figure {
    display: inline-block;
    box-sizing: border-box;
    width: inherit;
    height: inherit;
    border: 1px solid цвет;
}

Итоговый ХТМЛ английской версии (без оформления футов):

<div class="rectangle" style="width: длина; height: высота">
    <span class="rectangle-width">22 m 72.2 ft</span>
    <div class="rectangle-figure"></div>
    <span class="rectangle-height">14 m<br>45.9 ft</span>
</div>

Кроме редактирования текста, код требует один раз задать размеры прямоугольника инлайн.

 Нет комментариев    179   2018   вёрстка   СВГ   ХТМЛ   ЦСС

СВГ-иконки на практике

Кроме разрешения и веса, СВГ-иконки умеют удобно хранить несколько состояний. Так не в силах ни один растр. Количество состояний — признак, по которому делю иконки на «сплошные» и «слоёные».

Если иконка работает, как ссылка — целиком меняет цвет при наведении (или посещении), то про себя называю её «сплошной». С ней можно работать вслепую, не заглядывая внутрь. Говорим через ЦСС всему СВГ: «будь при наведении красным», и всё.

А если цвет меняют отдельные части, называю иконку «слоёной». Потому что такие игры возможны, только когда внутри СВГ формы лежат в отдельных элементах друг над другом — слоями.

Когда появляется такое поведение, первая идея — применить ЦСС-бордер к сплошной иконке. Но лучше не торопиться. Бордер всегда позиционируется по центру. Если контур однопиксельный, браузер нарисует линию в два полупрозрачных пикселя. И иконка станет мыльной на неретиновом экране.

Даже если контур будет кратным, сглаживание углов бордером или выход за пределы иконки могут мешать. Поэтому лучше положить в СВГ отдельные слои и управлять ими.

При этом слой с формой в виде обводки не сработает. ЦСС покрасит не только внешнюю форму, но и внутреннюю.

Если иконка слоёная, обратиться через ЦСС ко всему СВГ не получится. Нужно манипулировать элементами внутри. Это легко с инлайновым СВГ — добавил классы к нужным элементам и готово. Иконка фулскрина в карточке на сайте лаборатории:

<svg class="full-screen" xmlns="http://www.w3.org/2000/svg">
  <g>
    <path d="M7,7 L7,8 L6.00097656,8 L6.00097656,9 L5,9 L5,8 L0,8
    L0,18 L10,18 L10,13 L9,13 L9,12 L10,12 L10,11 L11,11 L11,10 L12,10
    L12,9 L13,9 L13,10 L18,10 L18,0 L8,0 L8,5 L9,5 L9,6 L8,6 L8,7 L7,7 Z"
    fill="#FFF"/>
			
    <path class="variable" d="M9.538,3.077 L13.935,3.077 L9.538,7.475 L9.538,8.462 
    L10.525,8.462 L14.923,4.065 L14.923,8.462 L16,8.462 L16,2 L9.538,2 L9.538,3.077 
    Z M3.077,13.938 L3.077,9.54 L2,9.54 L2,16 L8.461,16 L8.461,14.924 L4.063,14.924 
    L8.461,10.527 L8.461,9.54 L7.474,9.54 L3.077,13.938 Z" 
    fill="#666"/>
  </g>
</svg>

Без инлайна сложнее — обращение будет к типу элемента или к атрибуту. Плей в той же карточке:

<svg class="play"  xmlns="http://www.w3.org/2000/svg">
  <g>
    <polygon fill="#FFF" points="0 0 0 22 19 11"></polygon>
      
    <path class=“play-fill“ d="M2,3L2 19 15 11z" fill="#666"></path>
      
    <path class="play-void“ d="M3,4.99999999L3 17 13 11z" fill="#666"></path>
  </g>
</svg>

Допустим, он не инлайновый. Тогда при наведении будем менять цвет только элементов «path». Нижний полигон всегда белый. Верхнему треугольнику стоит задать по умолчанию заливку «none», чтобы обращаться к нему отдельно и управлять его видимостью.

Если такая иконка будет сплошной, понадобиться ещё один СВГ с белым фоном под ней. Это замусорит код и может привести к ошибкам при масштабировании.

И ещё момент. Графические редакторы делают такой плей из трёх полигонов, поэтому переводить их в кривые придётся вручную. Я неэлегантно вставляю код в фидл и копирую получившуюся кривую в инспекторе.