将SVG与媒体查询一起使用

使用HTML文档,我们可以根据视口的条件显示,隐藏或重新排列页面的某些部分。例如,如果浏览器窗口宽度为480像素,我们可能会将导航从水平导航切换到垂直可折叠列表。我们可以使用媒体查询和SVG文档执行类似的操作。考虑一个徽标,例如下面虚构的Hexagon Web Design&Development的徽标。

虚构公司的真实标识

没有媒体查询,此SVG徽标将简单地拉伸或缩小以适合视口或其容器。但是通过媒体查询,我们可以做更多聪明的事情。

让我们区分HTML文档视口和SVG文档视口。当SVG内联时,HTML视口和SVG视口是同一个。SVG文档的行为与任何其他HTML元素相同。在另一方面,当一个SVG文档被链接为与objectimg与SVG文档的视口的元件-我们处理。

媒体查询在两种情况下都有效,但是当链接SVG文档时,其视口独立于其HTML文档。在这种情况下,浏览器窗口的大小不会确定SVG视口的大小。取而代之的是,视口尺寸由尺寸确定objectiframeimg元件。以下面的(删节)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,只有我们徽标的符号部分可见,如下所示。

根据SVG视口大小显示/隐藏元素

要从HTML文档触发此视图,请设置SVG容器的宽度:

<object data="hexlogo.svg" type="image/svg+xml" style="width: 20em;"></object>

正如您从上面的图像中看到的那样,我们的SVG图像保留了其内在尺寸,即使其中一部分已被隐藏。不幸的是,这是SVG的限制。要修复它,我们需要更改viewBoxSVG文档的属性,但仅限于视口低于特定大小时。这是一个很好的用例matchMedia

viewBox顾名思义,该属性决定了SVG元素的可视区域。通过调整它,我们可以确定SVG图像的哪个部分填充视口。以下是使用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中获得最佳效果,请使用onloadevent属性。Microsoft Edge也最适用onload,但仅在用作<svg>标记的属性时才有效。换句话说,。<svg onload="updateViewBox">

现在,每当SVG容器为20em或更小时,其值viewBox将为"0 0 200 174"。当它超过时20emviewBox将恢复到其初始值,如下所示。

根据视口的宽度调整viewBox属性

注意:有关创建交互式SVG文档的更全面的入门读物,请阅读 W3C的今日浏览器的SVG Primer 的“ 动态SVG和JavaScript ”一章

由于此技术使用onload事件属性或SVGLoad事件,因此将CSS和JavaScript嵌入SVG文件中是个好主意。当CSS是外部的时,SVGLoad事件可能在其关联的CSS完成加载之前触发。

使用媒体查询 background-size

SVG文档和媒体查询不限于前景图像。我们还可以使用CSS background-size属性调整SVG视口的大小。所有最新的主流浏览器都支持这种技术,但较旧的浏览器版本则不支持。在生产中使用此技术时要小心。

我们将从这个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属性。在这种情况下,我们将使用我们的图像作为身体elementli元素的背景。下图显示了结果:

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;
}

使用CSS background-size属性操作SVG视口

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/261357.html

(0)
上一篇 2022年5月24日
下一篇 2022年5月24日

相关推荐

发表回复

登录后才能评论