I am attempting to build an svg that can be scaled horizontally and fluidly, similar to the old table-sliced images used to scale a header fluidly across the top of a page. Typically this requires the end component(s) not to stretch while the center component does stretch (or repeat). I have included an example image below. I have experimented with nested svg tags combined with viewBox and preserveAspectRatio in a variety of configurations but can't quite get it to work.
Here is a working example of what I need to do, in pure html/css: http://plnkr.co/edit/cSHBV27fL6k2m67FgwlA?p=preview
Is it even possible to do this with a single self-contained svg, or am I wasting my time?
SVG stands for scalable vector graphics, and it is a file format that allows you to display vector images on your website. This means that you can scale an SVG image up and down as needed without losing any quality, making it a great choice for responsive web design.
The viewBox attribute defines the position and dimension, in user space, of an SVG viewport. The value of the viewBox attribute is a list of four numbers: min-x , min-y , width and height .
If you want it to not scale, then you need give either the <svg> , or the <object> , a specific width. For example, if you want it to be rendered at 1:1, you would need to give it the same width and height as the viewBox: <svg width="1191" height="971" ...>
We use viewBox to make the SVG image scalable. viewBox = “0 0 100 100”: defines a coordinate system having x=0, y=0, width=100 units and height=100 units. Thus, the SVG containing a rectangle having width=50px and height=50px will fill up the height and width of the SVG image, and all the dimensions get scaled equally.
I'm answering this because I had to do the something similar.
Yes, you can do it with just SVG. The key attributes are viewBox
and preserveAspectRatio
. preserveAspectRatio="xMaxYMid"
keeps the rectangle to the right and xMinYMid
keeps the rectangle to the left. Set the viewBox
to be the desired size of the rectangles on the end.
This has been tested in Chrome, Firefox, and IE.
Here is a plunker demo.
Note that if the change the height of the svg to 100% instead of 20px you can make the image scale with a containing html div
.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<svg width="100%" height="20px" version="1.0" state='normal'
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<!-- The right head -->
<svg class='head input-source' id='right'
height="100%"
width='100%'
viewBox="0 0 15 30"
preserveAspectRatio="xMaxYMid"
>
<rect width="100%" height="100%"/>
</svg>
<!-- The left head -->
<svg class='head input-source' id='left'
height="100%"
width='100%'
viewBox="0 0 15 30"
preserveAspectRatio="xMinYMid"
>
<rect width="100%" height="100%"/>
</svg>
</defs>
<svg
class='input-source'
stroke='black'
stroke-width='0'
fill="green">
<rect x="2" y="20%" width="100%" height="60%"
stroke='black'
stroke-width='0'
>
</rect>
<use xlink:href='#right'/>
<use xlink:href='#left'/>
</svg>
</svg>
It's actually possible without Javascript by using foreignObject. But it will not work in Internet Explorer, bcs. IE doesn't support foreignObject. See my article at http://w3.eleqtriq.com/2014/03/the-holy-grail-of-image-scaling/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With