Ниже следует несколько соответствующих выдержек из спецификации SVG2 :
8.3.Начальное окно просмотра
Ширина начального окна просмотра должна быть значением атрибута представления width
для самого внешнего элемента svg , если не выполняются следующие условиявстречаются:
- содержимое SVG представляет собой отдельно хранимый ресурс, который встроен по ссылке (например, элемент
object
в HTML), или содержимое SVG встроено в составе содержимогодокумент ; - и ссылочный элемент или содержащий документ оформлены с использованием CSS ;
- и имеются CSS-совместимые свойства позиционирования , указанный в ссылочном элементе (например, элемент
object
) или в внешнем элементе svg содержащего документа, которые достаточны для определения ширины области просмотра .
В этих условиях ширина области просмотра должна быть установлена с помощью свойств позиционирования.
[То же самое относится к высоте]
8,12.Внутренние размерные свойства содержимого SVG
Внутренние пропорции должны быть рассчитаны с использованием следующего алгоритма.Если алгоритм возвращает значение NULL, то внутреннее соотношение сторон отсутствует.
- Если размерные свойства
width
и height
для элемента svg
являются абсолютными значениями: - ширина / высота
- Если активен SVG View :
- пусть viewbox будет окном просмотра, определяемымактивный SVG View
- return viewbox .width / viewbox .height
- Если
viewBox
на svg
элемент указан правильно: - let viewbox будет viewbox, определенный атрибутом
viewBox
элемента svg
- return viewbox .width / viewbox .height
- return null
Код
Я сделал кнопку для гамбургера в svg, и я пытаюсь точно выяснить, что происходит с точки зрения размеров его области просмотра, так как мы указываем это как с атрибутами представления svg,и с CSS.
svg#ham-btn {
margin: 2rem;
border: 1px solid black;
fill: #383838;
width: 10vw;
height: auto;
}
<svg id="ham-btn" width="107.5px" height="80px" viewBox="0 0 80 80" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg">
<style>
#ham-btn {
cursor: pointer;
}
#ham-btn rect {
transform-box: fill-box;
transform-origin: 50% 50%;
outline: 1px solid transparent;
transition: transform 0.2s;
}
#ham-btn:hover #r2 {
transform: translate(118%, 0);
}
#ham-btn:hover #r1 {
transform: translate(0%, 191.66%) rotate(36deg) scaleX(1.1);
}
#ham-btn:hover #r3 {
transform: translate(0%, -191.66%) rotate(-36deg) scaleX(1.1);
}
</style>
<rect id="r3" x="0" y="71.25%" width="100%" height="15%" rx="5%" />
<rect id="r2" x="0" y="42.5%" width="100%" height="15%" rx="5%"/>
<rect id="r1" x="0" y="13.75%" width="100%" height="15%" rx="5%" />
</svg>
Вопрос
Мое решение зависит от того, что соотношение viewport (107,5 / 80) отличается от отношения viewBox
(80/80).Это то, что вызывает центрирование (через preserveAspectRatio
).Если вы измените соотношение сторон окна просмотра, вы нарушите решение.
Следовательно, мой вопрос таков: почему настройка размеров в CSS не идентична настройке непосредственно в svg?Почему высота и ширина CSS, кажется, не перезаписывают высоту и ширину, указанные в SVG (поскольку первый приведенный выше отрывок спецификации указывает, что он должен).
My Best Guess
- Атрибуты представления svg
width
/ height
определяют внутреннее соотношение сторон элемента svg (как видно из второго отрывка спецификации выше) - Затем CSS перезаписывает эту ширину и высотуполностью (как видно из первого отрывка спецификации выше)
- Это объясняет, почему необходимо явно установить высоту
auto
в CSS.Если бы мы этого не сделали, высота svg снизилась бы до указанного 80px, что исказило бы форму
Есть мысли о том, верна ли эта догадка?