SVG inline - default or inherited height - css

please help me understand from where element get 150px of height?
In my project, I want element the same size as content
but root svg element and visible svg get 150px of height (from out of space likely)
I make demo with similar conditions.
http://plnkr.co/edit/2EJiwZFSwjD2f4wrETiX?p=preview
<body>
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<symbol id="icon-smile" viewBox="0 0 1024 1024">
<rect fill="yellowgreen" width="100%" height="100%"/>
<path class="path1" d="M512 1024c282.77 0 512-229.23 512-512s-229.23-512-512-512-512 229.23-512 512 229.23 512 512 512zM512 96c229.75 0 416 186.25 416 416s-186.25 416-416 416-416-186.25-416-416 186.25-416 416-416zM256 320c0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64s-64-28.654-64-64zM640 320c0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64s-64-28.654-64-64zM704.098 627.26l82.328 49.396c-55.962 93.070-157.916 155.344-274.426 155.344s-218.464-62.274-274.426-155.344l82.328-49.396c39.174 65.148 110.542 108.74 192.098 108.74s152.924-43.592 192.098-108.74z"></path>
</symbol>
</svg>
<div class=kx-rule>
<div class="cell col-md-3 col-sm-3">
<svg class="u-icon" >
<use xlink:href='#icon-smile'/>
</svg>
</div>
</div>
</body>
I know I can size svg but I want understand it's behavior. I red that svg canvas infinite, but why it(viewport?) render with such height?

The svg element
<svg class="u-icon" >
Does not have either height/width attributes/styles or a viewBox so it gets the fallback height/width of 300 x 150 px per the rules on replaced elements.

Related

SVG is not talking FULL 'width' of container

I am trying to make my svg full with width of the screen (container) but its not working. Could someone help me - please?
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320" preserveAspectRatio="none" class="first-svg">
<path fill="#27187F" fill-opacity="1" d="M0,192L60,170.7C120,149,240,107,360,106.7C480,107,600,149,720,170.7C840,192,960,192,1080,170.7C1200,149,1320,107,1380,85.3L1440,64L1440,320L1380,320C1320,320,1200,320,1080,320C960,320,840,320,720,320C600,320,480,320,360,320C240,320,120,320,60,320L0,320Z"></path>
</svg>
css
.first-svg {
width: 100%;
height: 200px;
}
I am suing bootstrap for this project I am working (only for practice)
I have done the following and it seemed to work - I added the SVG inside a row.
<div class="row">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320" preserveAspectRatio="none" class="first-svg">
<path fill="#27187F" fill-opacity="1" d="M0,192L60,170.7C120,149,240,107,360,106.7C480,107,600,149,720,170.7C840,192,960,192,1080,170.7C1200,149,1320,107,1380,85.3L1440,64L1440,320L1380,320C1320,320,1200,320,1080,320C960,320,840,320,720,320C600,320,480,320,360,320C240,320,120,320,60,320L0,320Z"></path>
</svg>
</div>

SVG viewBox="0 0 100 100" wont scale my path to 100%?

I currently have an svg path that only shows about 50%. How can I get it to show 100%?
Here is my code:
<div className="svgPathContainer">
<svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="none">
<path d="M82 88L0 0H123V170H0L82 88Z" fill="#F9B300" />
</svg>
</div>
I have className="svgPath" set as:
.svgPathContainer{
width: 100%;
height: 100%;
}
Here is also an example of the svg only showing at 50%:
https://codesandbox.io/s/svg-scaling-fff1q?file=/src/App.js:93-357
The problem: Why wont the svg path scale to 100% of the .svgPathContainer?
The viewBox is like a canvas size. So drawings outside of this view box will be clipped. Like css overflow: hidden. And your drawing has a size of width 123px and height 170px. So you have to change the view box to this value. Check our some docs.
If you want to keep the viewbox of 100 x 100 px, you need to change your drawing element size (path).
The view box has nothing to do with the scale. It's just the canvas size. A rect clip with width, height and offset (x y w h) for the SVG elements inside. And the SVG tag's width and height attributes are for scale the rendered image.
<div className="svgPathContainer">
<svg width="100%" height="100%" viewbox="0 0 123 170" preserveAspectRatio="none">
<path d="M82 88L0 0H123V170H0L82 88Z" fill="#F9B300" />
</svg>
</div>

Cannot Change SVG <use> icon size when linked to <symbol>

I'm trying to use an SVG symbol in my mark-up, but I can't get the CSS to increase the size of the symbol being rendered inside a element?
I have a twitter logo defined in a set of tags, and then I'm referencing this with an xlink:href inside use tags. The icon is showing, but when I add CSS to the #box1 div holding the element the symbol isn't increasing or decreasing in size and seems to only rendering at the viewBox size.
Also, the SVG element itself when I hover it with the dev tools is rendering at 300 x 150px - but there is nothing on in the code with these measurements.
I'm really confused — any help would be awesome.
#box1 {
height: 10rem;
width: 10rem;
}
<defs style="display: none;">
<svg id="twitter" viewBox="0 0 19.19 15.95">
<symbol id="twitter-symbol"><title>twitter</title>
<path id="twitter-path" d="M19.19,1.92a8.76,8.76,0,0,1-2.28.64A3.9,3.9,0,0,0,18.63.32a6.87,6.87,0,0,1-2.52,1A3.87,3.87,0,0,0,13.23,0,4,4,0,0,0,9.32,4,3.41,3.41,0,0,0,9.44,5,11,11,0,0,1,1.32.72a4.29,4.29,0,0,0-.52,2A4,4,0,0,0,2.56,6.12,3.61,3.61,0,0,1,.76,5.6v0a4,4,0,0,0,3.16,4,4.35,4.35,0,0,1-1,.16,4.9,4.9,0,0,1-.76-.08,4,4,0,0,0,3.68,2.8A7.79,7.79,0,0,1,.92,14.19a6.78,6.78,0,0,1-.92,0A10.83,10.83,0,0,0,6,16c7.24,0,11.19-6.16,11.19-11.47V4a6.83,6.83,0,0,0,2-2" fill="#000">
</path>
</symbol>
</svg>
</defs>
<div id="box1">
<svg>
<use xlink:href="#twitter-symbol"/>
</svg>
</div>
The <defs>is an svg element. It always goes inside the svg. I've made a few changes and now it works. Please run the code and take a look at what I've done.
#box1 {
height: 10rem;
width: 10rem;
}
#twitter{display:none;}
<svg id="twitter">
<defs>
<symbol id="twitter-symbol"><title>twitter</title>
<path id="twitter-path" d="M19.19,1.92a8.76,8.76,0,0,1-2.28.64A3.9,3.9,0,0,0,18.63.32a6.87,6.87,0,0,1-2.52,1A3.87,3.87,0,0,0,13.23,0,4,4,0,0,0,9.32,4,3.41,3.41,0,0,0,9.44,5,11,11,0,0,1,1.32.72a4.29,4.29,0,0,0-.52,2A4,4,0,0,0,2.56,6.12,3.61,3.61,0,0,1,.76,5.6v0a4,4,0,0,0,3.16,4,4.35,4.35,0,0,1-1,.16,4.9,4.9,0,0,1-.76-.08,4,4,0,0,0,3.68,2.8A7.79,7.79,0,0,1,.92,14.19a6.78,6.78,0,0,1-.92,0A10.83,10.83,0,0,0,6,16c7.24,0,11.19-6.16,11.19-11.47V4a6.83,6.83,0,0,0,2-2" fill="#000">
</path>
</symbol>
</defs>
</svg>
<div id="box1">
<svg viewBox="0 0 19.19 15.95" width="24">
<use xlink:href="#twitter-symbol"/>
</svg>
</div>
I hope it helps.
You're using inline SVG code within your HTML, so I believe that SVG path needs a viewbox defined within it. For example, if you add viewBox="0 0 60 55" within your HTML SVG tag, you'll notice that the size will start to adjust. So edit this part of your HTML
<svg viewBox="0 0 60 55">
<use xlink:href="#twitter-symbol"/>
</svg>
To expand on your note where you found the size listed as 300x150, this is the default standard size that applies to HTML inline SVG code (per HTML5 specs). This differs sometimes depending on the browser.
Keep in mind, there a are a few different methods you can use when handling SVGs. Check out the guide below where they give a nice run down on SVG and how to manipulate it's size. You might find an alternative way that you would prefer to use.
https://css-tricks.com/scale-svg/

Scale inline SVG symbol referenced with <use>

I have an SVG logo defined as a symbol like so:
<svg class="SpriteSheet">
<symbol id="icon-logo" viewBox="-12 -79.61 407.19 108.36">
<path id="logo-upperLeft" d="M0-67.61l83.66 0 0-10 -93.66 0 0 30.92 10 0Z" transform="translate(-2 -2)"></path>
<path id="logo-upperRight" d="M383.19-67.61l-83.66 0 0-10 93.66 0 0 30.92 -10 0Z" transform="translate(2 -2)"></path>
<path id="logo-lowerLeft" d="M0 16.75l83.66 0 0 10 -93.66 0 0-30.92 10 0Z" transform="translate(-2 2)"></path>
<path id="logo-lowerRight" d="M383.19 16.75l-83.66 0 0 10 93.66 0 0-30.92 -10 0Z" transform="translate(2 2)"></path>
</symbol>
</svg>
This definition is included at the top of the body and styled with display:none.
Later in the document, I use the logo in this way:
<header class="Header">
<h1 class="Header-headline">
<a href="/">
<svg class="Header-logo">
<use xlink:href="#icon-logo"></use>
</svg>
</a>
</h1>
</header>
I want to make the logo a certain height, with an automatic width:
.Header-logo {
height: 5rem;
}
This results in this:
Although the height is correct (here, 1rem is 24px), the width remains the default 300px. Adding width:auto causes no changes. In researching this problem, I came across several possible solutions here and here. However, none have worked with my application: reapplying the viewBox at the point of usage cuts off a large part of the image and using an <img> tag is not possible because I need to retain access to the SVG's DOM for styling purposes.
I could add a hard-coded width based on the known aspect ratio of the image, but this seems to be a non-optimal solution: what if the aspect ratio of the logo changes in the future? Another option is to define width:100%, which does work, however, this makes the 'clickable' area of the <a> extend across the entire width of the header, which I would like to avoid.
Is it possible to have an automatically-sized width with a defined height when the viewBox is described in the <symbol> definition? Must I be relegated to using an <img> tag or an absolute width for the SVG element?
Unfortunately it is the dimensions of the <svg> element that appears in your <header> that is important. There is no way to inherit a viewBox from a child symbol reference.
You would need to copy the viewBox (width and height) from the symbol.
.Header-logo {
height: 5rem;
}
.Header-logo2 {
height: 8rem;
}
<svg class="SpriteSheet" width="0" height="0">
<symbol id="icon-logo" viewBox="-12 -79.61 407.19 108.36">
<path id="logo-upperLeft" d="M0-67.61l83.66 0 0-10 -93.66 0 0 30.92 10 0Z" transform="translate(-2 -2)"></path>
<path id="logo-upperRight" d="M383.19-67.61l-83.66 0 0-10 93.66 0 0 30.92 -10 0Z" transform="translate(2 -2)"></path>
<path id="logo-lowerLeft" d="M0 16.75l83.66 0 0 10 -93.66 0 0-30.92 10 0Z" transform="translate(-2 2)"></path>
<path id="logo-lowerRight" d="M383.19 16.75l-83.66 0 0 10 93.66 0 0-30.92 -10 0Z" transform="translate(2 2)"></path>
</symbol>
</svg>
<header class="Header">
<h1 class="Header-headline">
<a href="/">
<svg class="Header-logo" viewBox="0 0 407.19 108.36">
<use xlink:href="#icon-logo"></use>
</svg>
</a>
</h1>
</header>
<header class="Header">
<h1 class="Header-headline">
<a href="/">
<svg class="Header-logo2" viewBox="0 0 407.19 108.36">
<use xlink:href="#icon-logo"></use>
</svg>
</a>
</h1>
</header>

Understanding svg's viewbox attribute

I am trying to use Turkey's map which was created before here.
I have changed the dimensions of svg element
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve"
width="800"
height="600"
style="shape-rendering:geometricPrecision;
text-rendering:geometricPrecision;
image-rendering:optimizeQuality;
fill-rule:evenodd;
clip-rule:evenodd"
viewBox="0 0 180 180">
When I change viewBox values to
viewBox="0 0 200 200"
the map is rendered in smaller size.
If I set the values to "0 0 10 10" image is not displayed.
If I set the values to "0 0 50 50" a huge image comes overflowing the page
If I set the values to "0 0 100 100" image is fine.
But I don't understand how it is working.
An SVG canvas is basically an endless plain, where you can put all your objects in.
The width and height you define the size of the image as shown in the browser. This works pretty much like with any other image you can include in HTML.
With the viewBox attribute on the other hand you select the part of that plain, you currently want to view.
So with a value of "0 0 10 10" you set the upper left point of the shown image to the point 0/0 and from there select 10 units to the right and bottom for your image. In your example in those upper 10 times 10 units area there is nothing, hence you see just a transparent area, which you perceive as "not being displayed".
With a value of "0 0 50 50" the shown area gets bigger and you'll start to see the upper left corner of the picture. The first parts of the map become visible.
Finally with "0 0 100 100" you can see pretty much half of the upper map.
The area you select using viewBox is the scaled to the height and width of the SVG element. With both combined you can enabled stuff like zooming into an SVG.
You can control the scaling with the attribute preserveAspectRatio.
You can add the following code at the bottom of the SVG file and see the displayed boxes (make sure to set the viewBox="0 0 180 180" before):
<rect x="0" y="0" width="100" height="100" style="stroke: blue; stroke-width: 1; fill: white; opacity: 0.8" />
<rect x="0" y="0" width="50" height="50" style="stroke: green; stroke-width: 1; fill: none;" />
<rect x="0" y="0" width="10" height="10" style="stroke: red; stroke-width: 1; fill: none;" />
<text x="5" y="97" style="fill: blue; font-size: 5px;">100x100</text>
<text x="5" y="47" style="fill: green; font-size: 5px;">50x50</text>
<text x="5" y="15" style="fill: red; font-size: 5px;">10x10</text>
So to conclude the purpose of viewBox is to select that part of the endless SVG plane, that should actually be rendered. If you choose the wrong values here, you might just see an empty space.
Links:
preserveAspectRatio #MDN
viewBox #MDN
Viewbox with the width and height values are how you can do zooming, and panning with SVG.
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve"
width="800"
height="600"
viewBox="0 0 800 600">
no scaling 800 pixels width in the viewbox equals 800 pixel width on the screen
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve"
width="800"
height="600"
viewBox="0 0 1600 1200">
Everything is scaled down so that a line 1600 pixels wide only shows up as 800 pixels wide.
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve"
width="800"
height="600"
viewBox="400 300 400 300">
Zoom into the bottom right hand 1/4 of the 800 by 600 screen making that portion fill the entire svg, don't show anything above the 300 pixel line or to the left of the 400 pixel line.

Resources