Размеры в SVG • Про CSS

Управление размерами — тема важная, и чтобы максимально использовать возможности SVG, нужно хорошо понимать как всё работает.

Спецификация.

Вьюпорт

Содержимое SVG-элемента отрисовывается на бесконечном холсте и может быть сколь угодно большого размера, но видимая часть холста соответствует размерам SVG-элемента. Эта область отрисовки называется viewport (вьюпорт).

SVG позволяет управлять как размерами вьюпорта, так и поведением содержимого относительно него: оно может обрезаться или показываться полностью, может растягиваться с потерей пропорций или стараться уместиться целиком, даже если при этом появляются пустые поля. Этим поведением можно управлять с помощью атрибутов.

Если просто вставить SVG на страницу и не задавать ему никакие размеры, он отобразится размером 300px на 150px, что не поместилось — обрежется:

Ширина и высота

Шириной и высотой элемента можно управлять стандартными свойствами width и height:

<svg>
  . ..
</svg>

Их можно задавать как атрибутами, так и в CSS:

.mysvg {
  width: 350px;
  height: 200px;
}

Для размеров в пикселях, задаваемых в атрибутах, единицы измерения можно не указывать.

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

viewBox

Похожим образом не изменяя размеры содержимого ресайзится iframe, но в случае с SVG это поведение можно изменить, если определить размеры области с помощью свойства viewBox:

<svg
    viewBox="0 0 180 180">
  ...
</svg>

Первые два значения — координаты X и Y верхнего левого угла отображаемой области, последние два — ширина и высота.

viewBox задаётся только атрибутом.

Попробуйте теперь изменить размеры, и вы увидите, что содержимое отресайзится, чтобы поместиться целиком.

viewBox можно использовать, например, для кадрирования изображения, чтобы показывать не всю картинку, а только какую-то её часть:

Это очень простое демо, вот пример посложнее от Sarah Drasner.

Интересно, что если у SVG нет размеров, но задан viewBox, изображение займёт собой всё доступное пространство:

<svg viewBox="0 0 180 180">
  ...
</svg>

Это поведение может стать проблемой: если размеры у иконок задаются в стилях, а они не загрузились — страница может превратиться в парад гигантских SVG-иконок. Чтобы этого не произошло, всегда явно задавайте в атрибутах SVG ширину и высоту, их потом легко переопределить в CSS.

preserveAspectRatio

Как мы видели в примере выше, если у SVG заданы размеры и viewBox, содержимое будет сжиматься и растягиваться с сохранением пропорций, чтобы поместиться целиком, но этим поведением тоже можно управлять — с помощью свойства preserveAspectRatio (оно задаётся только атрибутом).

Например, с помощью значения none можно указать, что сохранять пропорции не нужно:

<svg
    viewBox="0 0 180 180"
    preserveAspectRatio="none"
    >
  ...
</svg>

SVG с viewBox и preserveAspectRatio='none' ведёт себя очень похоже на img: при изменении размеров содержимое масштабируется под размеры вьюпорта не сохраняя пропорции.

none будет полезно для резиновых фонов:

Остальные значения preserveAspectRatio состоят из двух частей: первая задаёт выравнивание, вторая — поведение элемента относительно вьюпорта.

Выравнивание задаётся одним значением, определяющим положение по вертикали и по горизонтали, например: xMaxYMin

. Для обеих осей можно задать положение в начале, в середине и в конце:

xMin, YMin — в начале оси xMid, YMid — в середине xMax, YMax — в конце

Эти значения можно комбинировать в любых сочетаниях, но порядок должен сохраняться: первым всегда идет значение для X, вторым для Y. Значение для Y всегда пишется с большой буквы.

Поведение элемента определяется второй частью preserveAspectRatio. Возможные значения:

meet — содержимое стремится уместиться целиком (как фон с

background-size: contain) slice — содержимое заполняет собой всю область видимости (как background-size: cover: что не поместилось, обрежется)

Важно помнить, что preserveAspectRatio не работает без viewBox. viewBox задает область, которая должна масштабироваться, preserveAspectRatio определяет как именно она должна это делать.

Также нужно понимать, что preserveAspectRatio срабатывает, если вьюпорт и вьюбокс имеют разные соотношения сторон. Если соотношения сторон совпадают, и содержимое умещается без полей, preserveAspectRatio работать не будет (в этом случае в нём просто нет необходимости).

Для использования SVG в качестве иконок достаточно viewBox и размеров, но если предполагается делать что-то более сложное, имеет смысл разобраться с единицами измерения и системой координат.

Единицы измерения

Внутри SVG можно использовать em, ex, px, pt, pc, cm, mm, in, проценты, а также единицы системы координат (user space units). Единицы системы координат соответствуют пикселям, поэтому для значений в пикселях единицы измерения указывать не нужно.

Системы координат

В SVG-документе есть две системы координат:

  1. Система координат области отрисовки — viewport space.
  2. Система координат содержимого — user space.

Отсчет системы координат вьюпорта начинается от левого верхнего угла вьюпорта, системы координат содержимого — от левого верхнего края вьюбокса.

По умолчанию система координат содержимого соответствует системе координат вьюпорта, а единицы измерения содержимого — единицам измерения вьюпорта, но при использовании трансформаций или viewBox масштабируется вся система координат с единицами измерения, то есть пиксели из user space больше не равны пикселям из viewport space.

Поизменяйте размеры элемента и посмотрите что происходит с системой координат содержимого (она показана бирюзовым):

Система координат содержимого начинается из точки 0,0, и если вьюпорт и вьюбокс не совпадают, точка отсчета, как и вся система координат содержимого, будет ездить и масштабироватся вместе с вьюбоксом.

Масштабирование единиц измерения хорошо видно на примере обводки: изначально её толщина равна единице, но при изменении размеров видимая толщина обводки будет изменяться вместе с фигурой:

Если такое поведение нежелательно, это можно исправить с помощью свойства vector-effect со значением non-scaling-stroke, оно добавляется к содержимому SVG:

<circle r="60" cx="75" cy="75"
  stroke="black" stroke-width="1"
  vector-effect="non-scaling-stroke"/>

vector-effect можно задавать как атрибутом, так и в CSS.

Также новая система координат создается при добавлении трансформаций:

Внутри трансформируемого элемента будет своя своя система координат, отличная от систем координат вьюпорта и вьюбокса.

Тема может выглядеть сложной, но на самом деле, достаточно немного поиграться с кодом, и всё станет понятно. Для лучшего понимания систем координат, размеров и трансформаций в SVG рекомендую демо Сары Суайдан, а также её статьи:

  • Understanding SVG Coordinate Systems and Transformations (Part 1) — The viewport, viewBox, and preserveAspectRatio
  • Understanding SVG Coordinate Systems and Transformations (Part 2) — The transform Attribute
  • Understanding SVG Coordinate Systems and Transformations (Part 3) — Establishing New Viewports

Адаптивное видео для фона блока

Подключаем библиотеку jQuery и плагин jquery.vide.js и просто добавляем атрибут data-vide-bg=»path/video» к нужному блоку.

Где: path — папка с файлами video.jpg, video.mp4, video.ogv и video.webm

Пример:

<div data-vide-bg=»/demo/vide/video»> <div> Адаптивное видео для фона </div> </div>

<div data-vide-bg=»/demo/vide/video»>

<div>

Адаптивное видео для фона

</div>

</div>

Также можно использовать атрибут data-vide-options для настроек видео. По умолчанию они выглядят так:

volume: 1 громкость (от 0 до 1)
playbackRate: 1 скорость видео (медленнее быстрее)
muted: true отключение звука (true, false)
loop: true повтор (true, false)
autoplay: true автопроизведение (true, false)
position: ‘50% 50%’ позиционирование видео, также как background-position для CSS
posterType: ‘detect’ Тип постера («detect» — автоматически; «none» — без постера; «jpg», «png», «gif»,… — точное расширение.
resizing: true масштабирование видео под размеры блока (true, false)
bgColor: ‘transparent’ цвет для фона блока с видео
className: ‘ ‘ класс для блока с видео

Пример:

<div data-vide-bg=»/demo/vide/video» data-vide-options=»playbackRate: 0.

1, position: ‘0 100%'»> <div> Адаптивное видео для фона </div> </div>

<div data-vide-bg=»/demo/vide/video» data-vide-options=»playbackRate: 0.1, position: ‘0 100%'»>

<div>

Адаптивное видео для фона

</div>

</div>

Для того чтобы сделать видеофон на весь экран, нужно прописать атрибут data-vide-bg к тегу body и задать ему 100% высоту и ширину:

Пример:

<!doctype html> <html> <title>Адаптивный видеофон во весь экран / Atuin</title> <meta http-equiv=»Content-Type» content=»text/html; charset=utf-8″ /> <script src=»http://code.jquery.com/jquery-1.12.4.min.js» type=»text/javascript»></script> <script src=»http://atuin.ru/demo/vide/jquery.vide.js»></script> <style> html, body{ height:100%; width:100%; margin:0; display:table; } div { font-size:42px; text-align:center; vertical-align:middle; font-family:verdana; color:#BFE2FF; display:table-cell; } </style> <body data-vide-bg=»/demo/vide/video»> <div>Адаптивный видеофон во весь экран</div> </body> </html>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

<!doctype html>

<html>

<title>Адаптивный видеофон во весь экран / Atuin</title>

<meta http-equiv=»Content-Type» content=»text/html; charset=utf-8″ />

<script src=»http://code. jquery.com/jquery-1.12.4.min.js» type=»text/javascript»></script>

<script src=»http://atuin.ru/demo/vide/jquery.vide.js»></script>

<style>

html, body{

height:100%;

width:100%;

margin:0;

display:table;

}

div {

font-size:42px;

text-align:center;

vertical-align:middle;

font-family:verdana;

color:#BFE2FF;

display:table-cell;

}

</style>

<body data-vide-bg=»/demo/vide/video»>

<div>Адаптивный видеофон во весь экран</div>

</body>

</html>

Выглядеть будет так

Автор скрипта: VodkaBears
Файлы и подробное описание тут

Как создать фоновое изображение с помощью элемента Image и блока Div — General — Forum

Toryn 1

Привет всем,

Поскольку в настоящее время Webflow не оптимизирует фоновые изображения для мобильных устройств, я экспериментирую с созданием фоновых изображений, используя вместо этого элемент Image внутри блока Div. Тем не менее, я застрял с отзывчивостью и был бы очень признателен за любую помощь, которую кто-либо может предоставить.

Я вставляю блок Div, устанавливаю его Display на «Flex», а для Horizontal Align и Justify — на «Center». Я установил для параметра Position значение «Fixed->Full» с z-индексом -1, чтобы располагаться позади всего остального на странице. Затем я вставляю элемент изображения, выбираю ресурс изображения и устанавливаю высоту размера элемента изображения на 100VH.

Это приводит к тому поведению, которое я хочу на рабочем столе, но как только ширина области просмотра сокращается за пределы исходного соотношения моего изображения 16: 9 (например, на планшете), изображение начинает сжиматься внутрь по горизонтали.

Функциональность, которую я бы хотел, заключается в том, что на меньших экранах просмотра исходные размеры изображения сохраняются, и изображение просто начинает оставаться в центре и обрезать внутрь со всех сторон (так же, как ведут себя фоновые изображения Webflow). Я ломал голову над тем, какие параметры размера мне нужно установить, чтобы включить это.

Заранее большое спасибо, и если что-то из того, что я написал, непонятно, дайте мне знать!

Лучший,
Торин


Вот мой сайт только для чтения: https://preview.webflow.com/preview/toryn?utm_medium=preview_link&utm_source=designer&utm_content=toryn&preview=907d354ea78565c7e60b5c6ae9940c7d&pageId=5d24985460878d501f584e33&mod e=превью

Винсент (Венсан Бидо) 2

Не могли бы вы тоже поэкспериментировать с CSS object-fit?

Добавьте этот код в компонент Ambed на странице:

 <стиль>
. fit { объект-подгонка: обложка; ширина:100%; высота:100%;}

 

Теперь добавьте класс .fit к любому изображению как отдельный класс или комбинированный класс. Затем он будет вести себя как изображение bg, установленное для обложки, но будет изображением, поэтому оно будет оптимизировано Webflow, и вы можете установить для него alt=»».

Видно внизу этой страницы:

2 лайка

Торин 3

Спасибо, Винсент, буду экспериментировать!

Марио1000 (Марио) 4

вы можете сделать это в стиле, и вы можете использовать прозрачный PNG для фонового изображения.

Шимон (Шимон) 5

Спасибо за это!
Если вам интересно, вы также можете добиться этого без кода CSS.

Просто установите изображение на 100% по ширине и высоте, по размеру покрытия, установите абсолютное положение (0% с каждой стороны) и индекс -1.

3 Likes

Базовая страница с div, фон не отображается? — Общие — Форум

DragonDon 1

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

Установка:

Корпус

  • ОТДЕЛ

У меня есть другая страница, которая работает, но она настроена с разделом и работает

Тело

  • Раздел (фон установлен здесь)
    — Контейнер
    — DIV

http://puu.sh/kZqmZ/85e0602cf6.png
(Обратите внимание на пробел слева)

Итак, я подумал… «Могу ли я добавить фоновые изображения только в разделы?». Затем я добавил раздел на страницу и собирался поместить DIV в раздел, но как только раздел был добавлен (внизу списка элементов, обратите внимание!), появился фон DIV!!

http://puu. sh/kZqli/b0faf38730.jpg
(обратите внимание на цвет фона изображения слева)

Кажется, что WebFlow навязывает использование контейнеров, несмотря на то, что базовое body/div является вполне допустимым использованием html.

Ахмадз839 (Ахмад Зафар) 2

Кажется, у меня работает нормально, возможна ли ссылка только для чтения?

ДраконДон 3

Это был скорее комментарий, чем реальная проблема. Это повторялось на моем сайте.

Если хотите, вы можете взглянуть на тестовую страницу, чтобы увидеть ее в действии. Как только вы увидите пустую страницу, просто добавьте «раздел» ПОСЛЕ DIV, а затем вы увидите, что он внезапно говорит «о, я сейчас покажу вам этот фон DIV».

https://preview.webflow.com/preview/bjt-daily-ui?preview=629a035a0be5307ac17ef7c518b5a8a5

Ahmadz839 (Ахмад Зафар) 4

Я следовал вашим инструкциям, я разместил раздел после div вот что получилось: http://nimb. ws/snpjx1.

Ахмадз839 (Ахмад Зафар) 5

@DragonDon

Как вы можете видеть на картинке ниже, я не разместил ни одного раздела на странице, но у div все еще есть фоновое изображение, все, что я сделал, это дал div 100vh

1366×643 446 КБ

Лучший
Ахмад

DragonDon 6

На видео показано только добавление раздела на пустую страницу.

ДраконДон 7

Собственно, чего не хватало, так это 100% высоты по кузову.

Автор записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *