<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>~iany/ SVG</title><link>https://blog.iany.me/tags/svg/</link><description>Recent content in SVG «~iany/»</description><language>en-US</language><managingEditor>me@iany.me (Ian Yang)</managingEditor><webMaster>me@iany.me (Ian Yang)</webMaster><copyright>CC-BY-SA 4.0</copyright><lastBuildDate>Sun, 16 Jun 2013 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.iany.me/tags/svg/index.xml" rel="self" type="application/rss+xml"/><item><title>Responsive SVG</title><link>https://blog.iany.me/2013/06/responsive-svg/</link><pubDate>Sun, 16 Jun 2013 00:00:00 +0000</pubDate><author>me@iany.me (Ian Yang)</author><guid>https://blog.iany.me/2013/06/responsive-svg/</guid><description>&lt;p&gt;SVG can use percentage as unit, but it is often more convenient to use px as unit. Framework such as d3 also uses px internally. However, it is still easy to scale an SVG using attributes &lt;code&gt;viewBox&lt;/code&gt; and &lt;code&gt;preserveAspectRatio&lt;/code&gt; even px is used as unit internally.&lt;/p&gt;
&lt;h2 id="viewbox-and-preserveaspectratio"&gt;viewBox and preserveAspectRatio&lt;/h2&gt;
&lt;p&gt;The attribute &lt;a href="http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute"&gt;viewBox&lt;/a&gt; specifies viewpoint dimension. SVG can be scaled along with the parent container without changing the internal coordinates.&lt;/p&gt;
&lt;p&gt;For example, the SVG below defines a viewpoint with width 100 and
height 100.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;svg viewBox=&amp;quot;0 0 100 100&amp;quot;&amp;gt;
&amp;lt;circle cx=&amp;quot;50&amp;quot; cy=&amp;quot;50&amp;quot; r=&amp;quot;50&amp;quot; fill=&amp;quot;blue&amp;quot;&amp;gt;
&amp;lt;/svg&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The figure below shows the same SVG in different container sizes: 50x50, 100x50, 100x100, 100x200, 200x200 from left to right.&lt;/p&gt;
&lt;figure class="kg-image-card"&gt;
&lt;img alt="Same SVG in Different Size Containers" class="kg-image" loading="lazy" src="https://blog.iany.me/2013/06/responsive-svg/same-svg-in-different-containers_hu_d41762ac2492bccc.png" srcset="https://blog.iany.me/2013/06/responsive-svg/same-svg-in-different-containers_hu_2bebec1cfcce62d.png 400w, https://blog.iany.me/2013/06/responsive-svg/same-svg-in-different-containers_hu_56a84172c5222a.png 800w, https://blog.iany.me/2013/06/responsive-svg/same-svg-in-different-containers_hu_d41762ac2492bccc.png 1192w" sizes="(max-width: 800px) 100vw, 1192px" /&gt;
&lt;figcaption &gt;Same SVG in Different Size Containers&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Attribute &lt;a href="http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute"&gt;preserveAspectRatio&lt;/a&gt; controls how SVG is scaled according to parent container. There are many combinations, but the most frequently used are default (when the attribute is not specified, or set to &lt;code&gt;xMidYMid meet&lt;/code&gt; explicitly) and &lt;strong&gt;none&lt;/strong&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;default, preserve ratio, align center of SVG to the center of the container, scaled up as much as possible but ensure the entire &lt;code&gt;viewBox&lt;/code&gt; is visible within the container.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;none&lt;/code&gt;, do not preserve ratio, scale SVG to fill the whole container.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See the figure similar to the previous one but setting &lt;code&gt;preserveAspectRatio&lt;/code&gt; to &lt;code&gt;none&lt;/code&gt;.&lt;/p&gt;
&lt;figure class="kg-image-card"&gt;
&lt;img alt="`preserveAspectRatio=&amp;#34;none&amp;#34;`" class="kg-image" loading="lazy" src="https://blog.iany.me/2013/06/responsive-svg/preserveaspectratio-none_hu_6c121c8a0a82763a.png" srcset="https://blog.iany.me/2013/06/responsive-svg/preserveaspectratio-none_hu_8fd08d7c8cb873dd.png 400w, https://blog.iany.me/2013/06/responsive-svg/preserveaspectratio-none_hu_669370b9ac619e91.png 800w, https://blog.iany.me/2013/06/responsive-svg/preserveaspectratio-none_hu_6c121c8a0a82763a.png 1186w" sizes="(max-width: 800px) 100vw, 1186px" /&gt;
&lt;figcaption &gt;&lt;code&gt;preserveAspectRatio=&amp;quot;none&amp;quot;&lt;/code&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="responsive-svg"&gt;Responsive SVG&lt;/h2&gt;
&lt;p&gt;First add following CSS:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-css"&gt;svg {
width: 100%;
height: 100%;
}
svg * {
vector-effect: non-scaling-stroke;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first rule ensures SVG always fills parent container. And the second one sets a default &lt;code&gt;vector-effect&lt;/code&gt; that when SVG is scaled, leave stroke width untouched.&lt;/p&gt;
&lt;p&gt;If the SVG does not need to preserve ratio, set &lt;code&gt;preserveAspectRatio&lt;/code&gt; to &lt;code&gt;none&lt;/code&gt;, and set the height of the container. For example, the SVG below has a fixed height &lt;code&gt;50px&lt;/code&gt;, and is half width of the whole page.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;div style=&amp;quot;width:50%;height:50px;&amp;quot;&amp;gt;
&amp;lt;svg viewBox=&amp;quot;0 0 100 100&amp;quot; preserveAspectRatio=&amp;quot;none&amp;quot;&amp;gt;
&amp;lt;circle cx=&amp;quot;50&amp;quot; cy=&amp;quot;50&amp;quot; r=&amp;quot;50&amp;quot; fill=&amp;quot;blue&amp;quot;&amp;gt;
&amp;lt;/svg&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;figure&gt;
&lt;div style="width:50%;height:50px;"&gt;
&lt;svg viewBox="0 0 100 100" style="width:100%;height:100%" preserveAspectRatio="none"&gt;
&lt;circle cx="50" cy="50" r="50" fill="blue" /&gt;
&lt;/svg&gt;
&lt;/div&gt;
&lt;figcaption&gt;Fixed With, Horizontal scalable&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;If the SVG must preserve ratio, then we need a bit of JavaScript to change container height when window is resized.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;$.fn.preserveAspectRatio = function() {
this.each(function() {
var $this = $(this);
var ratioSpec = $this.attr('data-preserveAspectRatio').split(':');
var ratio = parseInt(ratioSpec[1], 10) / parseInt(ratioSpec[0], 10);
$this.height($this.width() * ratio);
});
};
var preserveAspectRatio = function() {
$('[data-preserveAspectRatio]').preserveAspectRatio();
};
$(function() {
preserveAspectRatio();
$(window).on('resize', preserveAspectRatio);
// Better to wrap preserveAspectRatio in underscore debounce or jquery-throttle-debounce.
// $(window).on('resize', _.debounce(preserveAspectRatio, 200));
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then set &lt;code&gt;data-preserveAspectRatio&lt;/code&gt; on any container that needs preserve aspect ratio. Following example sets the width height ratio to &lt;code&gt;1:1&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;div style=&amp;quot;width:50%;&amp;quot; data-preserveAspectRatio=&amp;quot;1:1&amp;quot;&amp;gt;
&amp;lt;svg viewBox=&amp;quot;0 0 100 100&amp;quot; preserveAspectRatio=&amp;quot;none&amp;quot;&amp;gt;
&amp;lt;circle cx=&amp;quot;50&amp;quot; cy=&amp;quot;50&amp;quot; r=&amp;quot;50&amp;quot; fill=&amp;quot;blue&amp;quot;&amp;gt;
&amp;lt;/svg&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;See the demo in this &lt;a href="https://codepen.io/doitian/pen/njmzrR"&gt;pen&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="references"&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://web.archive.org/web/20171114160758/http://meloncholy.com/blog/making-responsive-svg-graphs/"&gt;Making responsive SVG graphs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.w3.org/TR/SVG/coords.html"&gt;SVG Coordinate Systems, Transformations and Units&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><category domain="https://blog.iany.me/post/">Posts</category><category domain="https://blog.iany.me/tags/css/">CSS</category><category domain="https://blog.iany.me/tags/frontend/">Frontend</category><category domain="https://blog.iany.me/tags/svg/">SVG</category></item></channel></rss>