Ниже приведен небольшой отрывок из новой книги Тиффани « Мастер CSS», 2-е издание .
В HTML-документах мы можем отображать, скрывать или переупорядочивать части страницы в зависимости от условий области просмотра. Например, если окно браузера имеет ширину 480 пикселей, мы можем переместить нашу навигацию с горизонтального на вертикальный складной список. Мы можем сделать что-то подобное с медиа-запросами и SVG-документами. Рассмотрим логотип, такой как вымышленный Hexagon Web Design & Development ниже.
Без медиазапросов этот логотип SVG будет просто растягиваться или уменьшаться, чтобы соответствовать области просмотра или ее контейнеру. Но с помощью медиа-запросов мы можем делать более умные вещи.
Давайте различать область просмотра документа HTML и область просмотра документа SVG. Когда SVG встроен, область просмотра HTML и область просмотра SVG — это одно и то же. Документ SVG ведет себя как любой другой элемент HTML. С другой стороны, когда документ SVG связан — как с object
или элементами img
— мы имеем дело с окном просмотра документа SVG.
Медиа-запросы работают в обоих случаях, но когда SVG-документ связан, его область просмотра не зависит от HTML-документа. В этом случае размер окна браузера не определяет размер области просмотра SVG. Вместо этого размер области просмотра определяется размерами object
, элемента iframe
или элемента img
. Возьмите (сокращенный) документ SVG, который следует в качестве примера: [^ 4]
<svg version="1.1" id="HexagonLogo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 555 174" xml:space="preserve"> <defs> <style type="text/css"> /* CSS goes here */ </style> </defs> <g id="hex"> <polygon id="hexagonbg" points="55.2,162 10,86.5 55.2,11 145.5,11 190.7,86.5 145.5,162 "/> <path id="letterH" fill="#FFFFFF" d="M58,35.5h33v35.2h18.4V35.5 h33.2v103.4h-33.2v-38.3H91v38.3H58V35.5z M77.5,126.5V87.3h45.6v39.2h4V47.9h-4v35.6H77.5V47.9h-4v78.6H77.5z"/> </g> <g id="word-mark"> <g id="hexagon-word"> ... </g> <g id="web-design-and-dev"> ... </g> </g> </svg>
В маленьких окнах просмотра, давайте покажем только H в шестиугольнике:
@media (max-width: 20em) { [id=word-mark] { display: none; } }
В маленьких окнах просмотра, давайте покажем только H в шестиугольнике:
Теперь, когда контейнер SVG меньше или равен 20em
, будет видна только символическая часть нашего логотипа, как указано ниже.
Чтобы запустить это представление из документа HTML, установите ширину контейнера SVG:
<object data="hexlogo.svg" type="image/svg+xml" style="width: 20em;"></object>
Как вы могли заметить, глядя на изображение выше, наше изображение SVG сохраняет свои внутренние размеры, даже если часть его была скрыта. Это, к сожалению, является ограничением SVG. Чтобы это исправить, нам нужно изменить атрибут viewBox
документа SVG, но только когда область просмотра меньше определенного размера. Это отличный пример использования matchMedia
.
viewBox
, как следует из его названия, определяет видимую область элемента SVG. Регулируя его, мы можем определить, какая часть изображения SVG заполняет область просмотра. Ниже приведен пример использования matchMedia
и matchMedia
для обновления атрибута viewBox
:
<script type="text/javascript"> var svg, originalViewBox, max20em, mq, updateViewBox; svg = document.querySelector('svg'); /* Store the original value in a variable */ originalViewBox = svg.getAttribute('viewBox'); /* Define our media query and media query object */ mq = matchMedia("(max-width: 20em)"); /* Define the handler */ updateViewBox = function(){ if (mq.matches) { /* Change the viewBox dimensions to show the hexagon */ svg.setAttribute('viewBox', "0 0 200 174"); } else { svg.setAttribute('viewBox', originalViewBox); } } /* Fire on document load */ // WebKit/Blink browsers svg.onload = updateViewBox; // Firefox & IE svg.addEventListener('SVGLoad', updateViewBox, true); /* Fire if the media condition changes */ mq.addListener(updateViewBox); </script>
Примечание. Браузеры немного беспорядок, когда дело доходит до обработки события SVGLoad
. В моих тестах addEventListener
работал наиболее согласованно с Firefox. Для достижения наилучших результатов в Chrome и Safari используйте атрибут события onload
. Microsoft Edge также лучше всего работает с onload
, но только при использовании в качестве атрибута <svg>
. Другими словами, <svg onload="updateViewBox">
.
Теперь, когда контейнер SVG равен 20em
или меньше, значение viewBox
будет равно "0 0 200 174"
. Когда он превышает 20em
, viewBox
вернется к своему начальному значению, как показано ниже.
Примечание. Чтобы получить более полное представление о создании интерактивных документов SVG, прочитайте главу « Динамический SVG и JavaScript » в «Учебнике SVG для современных браузеров W3C».
Поскольку этот метод использует либо атрибут события onload
либо событие SVGLoad
, хорошей идеей будет встроить наши CSS и JavaScript в файл SVG. Когда CSS является внешним, событие SVGLoad
может SVGLoad
прежде чем связанный с ним CSS завершит загрузку.
Использование медиазапросов с background-size
Документы SVG и медиа-запросы не ограничиваются изображениями переднего плана. Мы также можем изменить размер окна просмотра SVG, используя свойство background-size
CSS. Все последние основные браузеры поддерживают эту технику, но старые версии браузеров не поддерживают. Будьте осторожны при использовании этой техники в производстве.
Мы начнем с этого документа SVG:
<?xml version="1.0" encoding="utf-8"?> <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-20 -20 250 250" xml:space="preserve"> <style type="text/css"> circle { stroke: #000; stroke-width: 30; fill: #009688; } @media (width: 100px) { circle { fill: #673ab7; } } @media (width: 300px) { circle { fill: #ffc107; } } </style> </defs> <circle cx="100" cy="100" r="100" /> <circle cx="100" cy="100" r="50" /> </svg>
Это простой случай. Наши элементы circle
получат новый цвет fill
при определенной ширине области просмотра. Когда область просмотра имеет ширину 20 пикселей, заливка будет бирюзовой. Когда он шириной 300 пикселей, он будет желтым.
Чтобы сделать это, мы должны использовать наше изображение SVG в качестве фонового изображения и установить свойство background-size
селектора. В этом случае мы будем использовать наше изображение в качестве фона для element
body и для элементов li
. Изображение ниже показывает результаты:
body, li { background: url(../images/circles.svg); } body { background-color: #9c27b0; background-size: 300px auto; } li { background-size: 20px auto; background-repeat: no-repeat; background-position: left 3px; padding-left: 25px; }