Масштабирование фонов SVG
Учитывая гибкость изображений SVG, нужно учитывать много моментов при их использовании в качестве фоновых изображений с помощью свойства background-image, и еще больше при их масштабировании с помощью свойства background-size. Эта статья описывает, как обрабатывается масштабирование изображений SVG при использовании этих свойств.
Алгоритм, кратко
Алгоритм в основном можно свести к этим четырём правилам. Есть некоторые крайние случаи, которые не охватываются этими правилами, но они покрывают большинство ситуаций.
- Если
background-sizeзадаёт фиксированный размер (то есть, проценты и относительные единицы фиксируются своим контекстом), этот размер имеет преимущество. - Если изображение имеет внутреннее соотношение сторон (то есть, его соотношение ширины к высоте является постоянным, например, 16:9, 4:3, 2.39:1, 1:1 и так далее), размер рендеринга сохраняет это соотношение.
- Если изображение задаёт размер, и этот размер не изменяется с помощью constrain или cover, этот заданный размер имеет преимущество.
- Если ни один из вышеперечисленных случаев не подходит, изображение рендерится с тем же размером, что и область фона.
Стоит отметить, что алгоритм масштабирования заботится только о размерах и пропорциях изображения, или их отсутствии. Изображение SVG с фиксированными размерами будет обрабатываться так же, как растровое изображение того же размера.
Примечание: Если вы пытаетесь растянуть ваше SVG до другого соотношения сторон с CSS — например, чтобы растянуть его по всему фону страницы — убедитесь, что ваше SVG содержит preserveAspectRatio="none". Узнайте больше о preserveAspectRatio.
Примеры исходных изображений
Прежде чем углубляться в изучение результатов использования разных типов исходных изображений и просмотра их вида при использовании с background-size, было бы полезно рассмотреть несколько примеров исходных изображений с различными размерами и настройками масштабирования.
В каждом случае мы показываем, как выглядит исходное изображение, рендеренное в прямоугольнике размером 150x150 пикселей, и приводим ссылку на исходный SVG.
Без размеров и пропорций
Это изображение не имеет размеров и пропорций. Ему всё равно, какого оно размера, и оно не сохраняет определённое соотношение сторон. Это может быть подходящий фоновый градиент для рабочего стола, который будет работать независимо от размера и соотношения сторон вашего экрана.
Один заданный размер и без пропорций
Это изображение задаёт ширину 100 пикселей, но не высоту или внутреннее соотношение сторон. Это, по сути, тонкая полоса обоев, которая могла бы растянуться на всю высоту блока.
Один заданный размер с внутренним соотношением сторон
Это изображение задаёт высоту 100 пикселей, но не ширину. Оно также задаёт внутреннее соотношение сторон 3:4. Это гарантирует, что соотношение ширины к высоте всегда равно 3:4, если оно не масштабируется преднамеренно до несоразмерного размера (то есть, явно задавая ширину и высоту, которые не соответствуют этому соотношению).
Это очень похоже на указание конкретной ширины и высоты, так как после того, как вы задали один размер и соотношение, другой размер подразумевается, но это всё равно полезный пример.
Без ширины или высоты с внутренним соотношением сторон
Это изображение не задаёт ни ширины, ни высоты; вместо этого оно задаёт внутреннее соотношение сторон 1:1. Подумайте об этом как об значке программы. Он всегда квадратный и пригоден для любого размера, например, 32x32, 128x128 или 512x512.
Примеры масштабирования
Теперь давайте посмотрим на некоторые примеры того, что происходит при применении различных масштабов к этим изображениям. В каждом из примеров ниже окружающие прямоугольники имеют ширину 300 пикселей и высоту 200 пикселей. Кроме того, фоны имеют background-repeat установленным в no-repeat для большей ясности.
Примечание: Скриншоты ниже показывают ожидаемый рендеринг. Не все браузеры в настоящее время правильно отображают это.
Указание фиксированных длин для обоих измерений
Если вы используете background-size для указания фиксированных длин для обоих измерений, эти длины всегда используются, согласно правилу 1 выше. Другими словами, изображение всегда будет растягиваться до указанных вами размеров, независимо от того, указаны ли размеры и/или соотношение сторон исходного изображения.
Исходное изображение: Без размеров или соотношения сторон
С таким CSS:
background: url(no-dimensions-or-ratio.svg); background-size: 125px 175px;
Результат рендеринга будет выглядеть так:
Исходное изображение: Один указанный размер, без соотношения сторон
С таким CSS:
background: url(100px-wide-no-height-or-ratio.svg); background-size: 250px 150px;
Результат рендеринга будет выглядеть так:
Исходное изображение: Один указанный размер с внутренним соотношением сторон
С таким CSS:
background: url(100px-height-3x4-ratio.svg); background-size: 275px 125px;
Результат рендеринга будет выглядеть так:
Исходное изображение: Без указанной ширины или высоты с внутренним соотношением сторон
С таким CSS:
background: url(no-dimensions-1x1-ratio.svg); background-size: 250px 100px;
Результат рендеринга будет выглядеть так:
Использование contain или cover
Указание cover для background-size делает изображение как можно меньше, но при этом охватывает всю область фона. contain, с другой стороны, делает изображение как можно больше, не выходя за пределы области фона.
Для изображения с внутренним соотношением сторон, ровно один размер соответствует критериям cover/fit. Но если внутреннее соотношение сторон не указано, cover/fit недостаточно, поэтому ограничения по размеру выбирают результирующий размер.
Исходное изображение: Без размеров или соотношения сторон
Если изображение не задаёт размеры или внутреннее соотношение сторон, ни правило 2, ни правило 3 не применяются, поэтому вступает в силу правило 4: фоновое изображение рендерится, занимая всю область фона. Это удовлетворяет ограничению по наибольшему или наименьшему размеру.
background: url(no-dimensions-or-ratio.svg); background-size: contain;
Результат рендеринга выглядит так:
Исходное изображение: Один указанный размер, без соотношения сторон
Аналогично, если изображение имеет один указанный размер, но без внутреннего соотношения сторон, применяется правило 4, и изображение масштабируется для заполнения всей области фона.
background: url(100px-wide-no-height-or-ratio.svg); background-size: contain;
Результат рендеринга выглядит так:
Исходное изображение: Один указанный размер с внутренним соотношением сторон
Вещи меняются, когда вы указываете внутреннее соотношение сторон. В этом случае правило 1 неактуально, поэтому применяется правило 2: мы пытаемся сохранить любое внутреннее соотношение сторон (при соблюдении contain или cover). Например, сохранение внутреннего соотношения сторон 3:4 для прямоугольника 300x200 с contain означает рисование фона размером 150x200.
Случай contain
background: url(100px-height-3x4-ratio.svg); background-size: contain;
Результат рендеринга выглядит так:
Обратите внимание, как всё изображение рендерится, как можно лучше вписываясь в прямоугольник без обрезки.
Случай cover
background: url(100px-height-3x4-ratio.svg); background-size: cover;
Результат рендеринга выглядит так:
Здесь соотношение 3:4 сохраняется, при этом изображение растягивается, чтобы заполнить весь прямоугольник. Это приводит к обрезке нижней части изображения.
Исходное изображение: Без размеров с внутренним соотношением сторон
При использовании изображения без размеров, но с внутренним соотношением сторон, вещи работают аналогично.
Случай contain
background: url(no-dimensions-1x1-ratio.svg); background-size: contain;
Результат рендеринга выглядит так:
Обратите внимание, что изображение масштабируется для соответствия наименьшему размеру, сохраняя при этом соотношение сторон 1:1.
Случай cover
background: url(no-dimensions-1x1-ratio.svg); background-size: cover;
Результат рендеринга выглядит так:
Здесь изображение масштабируется так, чтобы заполнить наибольший размер. Соотношение сторон 1:1 сохранено, хотя с этим исходным изображением это может быть трудно увидеть.
Автоматическое масштабирование с использованием "auto" для обоих размеров
Если background-size установлено в значение auto или auto auto, правило 2 гласит, что рендеринг должен сохранить любое предоставленное внутреннее соотношение сторон.
Источник: Без размеров или внутреннего соотношения
Когда источник изображения не определяет внутреннее соотношение сторон или размеры, вступает в силу правило 4, и изображение рендерится, заполняя область фона.
background: url(no-dimensions-or-ratio.svg); background-size: auto auto;
Результат рендеринга выглядит так:
Источник: Один размер и отсутствие внутреннего соотношения
Если внутреннее соотношение сторон не указано, но указан хотя бы один размер, вступает в силу правило 3, и мы рендерим изображение, подчиняясь этим размерам.
background: url(100px-wide-no-height-or-ratio.svg); background-size: auto auto;
Результат рендеринга выглядит так:
Обратите внимание, что ширина, заданная в исходном SVG в 100 пикселей, соблюдается, а высота заполняет область фона, так как она не указана (ни явно, ни через внутреннее соотношение).
Источник: Один размер и внутреннее соотношение
Если у нас есть внутреннее соотношение с фиксированным размером, это фиксирует оба размера. Знание одного размера и соотношения, как уже упоминалось, равносильно явному указанию обоих размеров.
background: url(100px-height-3x4-ratio.svg); background-size: auto auto;
Результат рендеринга выглядит так:
Поскольку у этого изображения явно указана высота в 100 пикселей, соотношение 3:4 явно устанавливает его ширину в 75 пикселей, поэтому именно так оно рендерится в auto случае.
Источник: Без фиксированных размеров с внутренним соотношением
Если указано внутреннее соотношение, но не указаны размеры, применяется правило 4 — за исключением того, что также применяется правило 2. Таким образом, изображение рендерится так же, как и в contain случае.
background: url(no-dimensions-1x1-ratio.svg); background-size: auto auto;
Результат рендеринга выглядит так:
Использование "auto" и одного конкретного размера
Согласно правилу 1, указанные размеры всегда используются, поэтому нам нужно использовать наши правила только для определения второго размера.
Источник: Без размеров или внутреннего соотношения
Если у изображения нет размеров или внутреннего соотношения, применяется правило 4, и мы используем размер области фона для определения значения для auto размера.
background: url(no-dimensions-or-ratio.svg); background-size: auto 150px;
Здесь ширина определяется с использованием ширины области фона по правилу 4, а высота — 140 пикселей, указанных в CSS.
Источник: Один указанный размер без внутреннего соотношения
Если у изображения указан один размер, но нет внутреннего соотношения, этот указанный размер используется по правилу 3, если этот размер установлен на auto в CSS.
background: url(100px-wide-no-height-or-ratio.svg); background-size: 200px auto;
Здесь 200 пикселей, указанных в CSS, переопределяют 100 пикселей ширины, указанных в SVG, согласно правилу 1. Поскольку не указано внутреннее соотношение или высота, auto выбирает высоту области фона как высоту рендерного изображения.
background: url(100px-wide-no-height-or-ratio.svg); background-size: auto 125px;
В этом случае ширина указана как auto в CSS, поэтому выбирается ширина 100 пикселей, указанная в SVG, согласно правилу 3. Высота установлена в 125 пикселей в CSS, поэтому она выбирается по правилу 1.
Источник: Один указанный размер с внутренним соотношением
Когда размер указан, правило 1 применяет этот размер из SVG к рендерному фону, если он не переопределен в CSS. Когда также указано внутреннее соотношение, оно используется для определения другого размера.
background: url(100px-height-3x4-ratio.svg); background-size: 150px auto;
В этом случае мы используем ширину изображения, указанную в CSS и равную 150 пикселям, поэтому применяется правило 1. Внутреннее соотношение 3:4 затем определяет высоту в auto случае.
Источник: Без указанных размеров с внутренним соотношением
Если размеры не указаны в SVG, указанный размер в CSS применяется, а затем внутреннее соотношение используется для выбора другого размера, согласно правилу 2.
background: url(no-dimensions-1x1-ratio.svg); background-size: 150px auto;
Ширина установлена в CSS как 150 пикселей. Значение auto для высоты вычисляется с использованием этой ширины и соотношения 1:1, что составляет также 150 пикселей, что приводит к изображению выше.
См. также
© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/Scaling_of_SVG_backgrounds