How to change font-size to a SVG? - html

I'm using a svg icon on my website.
here's the code I got from Adobe Illustrator:
<svg id="Livello_1" data-name="Livello 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448.05 436.7"><path d="M190.5,66.9l22.2-22.2a23.9,23.9,0,0,1,33.9,0L441,239a23.9,23.9,0,0,1,0,33.9L246.6,467.3a23.9,23.9,0,0,1-33.9,0l-22.2-22.2a24,24,0,0,1,.4-34.3L311.4,296H24A23.94,23.94,0,0,1,0,272V240a23.94,23.94,0,0,1,24-24H311.4L190.9,101.2A23.85,23.85,0,0,1,190.5,66.9Z" transform="translate(0 -37.65)"/></svg>
I've been able to change its color (in my css fill:#33453a;) but not its size (I tried with both font-size and width, but none of them worked).
The reason why I'm trying to do so is that I need an icon which color and size can be changed in :hover status.

This might be a tricky question. What you are intending to do is not possible as other people pointed out, but not being possible with font-size doesn't mean it is not possible to get it working as you are expecting.
If you look into a big project like react-icons you can get a glimpse of how they do it.
const computedSize = size || conf.size || "1em";
let className;
if (conf.className) className = conf.className;
if (props.className) className = (className ? className + ' ' : '') + props.className;
return (
<svg
stroke="currentColor"
fill="currentColor"
strokeWidth="0"
{...conf.attr}
{...attr}
{...svgProps}
className={className}
style={{ color: props.color || conf.color, ...conf.style, ...props.style}}
height={computedSize}
width={computedSize}
xmlns="http://www.w3.org/2000/svg"
>
{title && <title>{title}</title>}
{props.children}
</svg>
)
};
So you might have something similar like: <span style="font-size: 14px">hi <svg ...></svg></span>.
The trick is to assign with and height the em unit, which stands for ephemeral unit don't be confused with rem, you can read more about his in this post
What the em unit will do in your browser is to look at the closest definition of font-size and attach that one to the SVG context, that is how you get the same dimension.
Solution: add width:1em and height:1em
<svg height="1em" width="1em" id="Livello_1" data-name="Livello 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448.05 436.7"><path d="M190.5,66.9l22.2-22.2a23.9,23.9,0,0,1,33.9,0L441,239a23.9,23.9,0,0,1,0,33.9L246.6,467.3a23.9,23.9,0,0,1-33.9,0l-22.2-22.2a24,24,0,0,1,.4-34.3L311.4,296H24A23.94,23.94,0,0,1,0,272V240a23.94,23.94,0,0,1,24-24H311.4L190.9,101.2A23.85,23.85,0,0,1,190.5,66.9Z" transform="translate(0 -37.65)"/></svg>

You can not change the font size or font width because SVG is not a font. It is Scalable Vector Graphics. If you would have some text in your SVG then you could do something with the font from the text element.
In your case you have to add attribute width and height for SVG. And in hover of SVG you can change it like follows:
#Livello_1:hover
{
fill:#33453a;
width:48px;
height:48px
}
<svg id="Livello_1" width="36" height="36" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448.05 436.7"><path d="M190.5,66.9l22.2-22.2a23.9,23.9,0,0,1,33.9,0L441,239a23.9,23.9,0,0,1,0,33.9L246.6,467.3a23.9,23.9,0,0,1-33.9,0l-22.2-22.2a24,24,0,0,1,.4-34.3L311.4,296H24A23.94,23.94,0,0,1,0,272V240a23.94,23.94,0,0,1,24-24H311.4L190.9,101.2A23.85,23.85,0,0,1,190.5,66.9Z" transform="translate(0 -37.65)"/></svg>
To see the effect you have to move your mouse cursor over this SVG (in snippet, wich must be runned).

Since it does not contain a text with font, the better way is to use scale to increase the size. :
<style>
svg
{
transform: scale(1.3);
}
</style>

I guess you need to align and scale your svg icon relative to your font size.
It is kind of a 'team play' between svg and css:
In css we make sure our svg has a inline-block context, a height relative to the inherited font-sizes.
In svg we use seperate viewBox attributes for each icon.
If you need to adjust the baseline alignment or dimensions on :hover you need to avoid layout shifts e.g vertical-align would also some kind of leading to the next line – therefore we use a relative position and bottom offset.
/* just an example code to illustrate the scalability */
const fontSize= document.querySelector('.fontSize');
const layout = document.querySelector('.layout');
fontSize.addEventListener('change', function(e) {
let currentSize = +e.target.value;
layout.setAttribute('style', 'font-size:'+(1+currentSize)+'em');
});
/* svg will behave similarly to a character/glyph */
.svg-inline {
display: inline-block;
/* without a custom viewbox we have a square aspect ratio as default */
height: 1em;
width: 1em;
}
/**
* optional adjustment:
* font-size: if icons are too big
* vertical baseline offset
**/
.svg-adjust {
font-size: 0.75em;
position: relative;
bottom: -0.1em;
transition: 0.3s;
}
/* set size by viewbox if present */
.svg-inline[viewBox] {
width: auto;
}
.svg-inline-assets{
display:none
}
a:hover .svg-inline {
fill: green;
transform: scale(1.5);
margin-left: 0.5em;
margin-right: 0.5em;
}
/* example layout */
html {
font-family: "Segoe UI";
font-size: calc(1vw + 1vh /2);
line-height: 1.4em;
}
.layout {
width: 50%;
margin: 0 auto;
font-size: 1.5em;
line-height: 1.4em;
}
p {
margin: 0;
}
a {
text-decoration: none;
color: inherit;
border-bottom: 2px solid #aaa;
}
a .svg-inline {
fill: #aaa;
}
.button {
font-size: 1.333em;
line-height: 1em;
background-color: #aaa;
border: 2px solid #aaa;
color: #fff;
cursor: pointer;
margin-top: 1rem;
padding: 0.3em;
}
.button .svg-inline {
fill: #fff;
}
.input-range {
width: 100%;
}
<main class="layout">
<h3>Change font Size</h3>
<p>
<input class="input-range fontSize" type="range" value="0" min="-0.5" max="0.5" step="0.1">
</p>
<svg class="svg-inline-assets" viewBox="0 0 100 100">
<!-- every asset has it's own viewbox: this way we can place icons with different widths -->
<symbol id="fa-arrow-right-asset" viewBox="0 0 100 100">
<path d="M42.5,7.8l5-5c2.1-2.1,5.5-2.1,7.5,0c0,0,0,0,0,0l43.4,43.4c2.1,2.1,2.1,5.5,0,7.5c0,0,0,0,0,0L55,97.2c-2.1,2.1-5.5,2.1-7.5,0c0,0,0,0,0,0l-5-5c-2.1-2.1-2.1-5.5,0-7.6c0,0,0.1-0.1,0.1-0.1l26.9-25.6H5.4c-3,0-5.3-2.4-5.4-5.3c0,0,0,0,0,0v-7.1c0-3,2.4-5.3,5.3-5.4c0,0,0,0,0,0h64.1L42.6,15.5c-2.1-2-2.2-5.4-0.2-7.5C42.4,7.9,42.5,7.8,42.5,7.8z" />
</symbol>
<symbol id="fa-arrow-right-long-asset" viewBox="0 0 200 100">
<path d="M141.1,7.8l5-5c2.1-2.1,5.5-2.1,7.5,0c0,0,0,0,0,0L197,46.2c2.1,2.1,2.1,5.5,0,7.5c0,0,0,0,0,0l-43.4,43.4c-2.1,2.1-5.5,2.1-7.5,0c0,0,0,0,0,0l-5-5c-2.1-2.1-2.1-5.5,0-7.6c0,0,0.1-0.1,0.1-0.1l26.9-25.6H5.4c-3,0-5.3-2.4-5.4-5.3c0,0,0,0,0,0v-7.1c0-3,2.4-5.3,5.3-5.4c0,0,0,0,0,0h162.7l-26.9-25.6c-2.1-2-2.2-5.4-0.2-7.5C141,7.9,141,7.8,141.1,7.8z" />
</symbol>
<!-- this arrow has a x offset of 200: without it's own viewbox it would be cropped -->
<symbol id="fa-arrow-right-long-offset-asset" viewBox="200 0 200 100">
<path d="M341.1,7.8l5,-5c2.1,-2.1,5.5,-2.1,7.5,0c0,0,0,0,0,0l43.4,43.4c2.1,2.1,2.1,5.5,0,7.5c0,0,0,0,0,0l-43.4,43.4c-2.1,2.1,-5.5,2.1,-7.5,0c0,0,0,0,0,0l-5,-5c-2.1,-2.1,-2.1,-5.5,0,-7.6c0,0,0.1,-0.1,0.1,-0.1l26.9,-25.6h-162.7c-3,0,-5.3,-2.4,-5.4,-5.3c0,0,0,0,0,0v-7.1c0,-3,2.4,-5.3,5.3,-5.4c0,0,0,0,0,0h162.7l-26.9,-25.6c-2.1,-2,-2.2,-5.4,-0.2,-7.5c0.1,0,0.1,-0.1,0.2,-0.1z" />
</symbol>
<symbol id="fa-arrow-right-narrow-asset" viewBox="0 0 60 100">
<path d="M57.5,46.2L14.1,2.8c0,0,0,0,0,0c-2.1-2.1-5.5-2.1-7.5,0l-5,5c0,0-0.1,0.1-0.1,0.1c-2,2.1-1.9,5.5,0.2,7.5l37,34.5l-37,34.5c0,0-0.1,0.1-0.1,0.1c-2.1,2.1-2.1,5.5,0,7.6l5,5c0,0,0,0,0,0c2.1,2.1,5.5,2.1,7.5,0l43.4-43.4c0,0,0,0,0,0C59.6,51.7,59.6,48.3,57.5,46.2z" />
</symbol>
</svg>
<h2>Svg inlined icon</h2>
<p><svg class="svg-inline">
<use href="#fa-arrow-right-asset" />
</svg>No vertical adjustment. One morning, when
<svg class="svg-inline svg-adjust">
<use href="#fa-arrow-right-asset" />
</svg>
Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin. He lay on his armour-like back, and if he lifted his head a
<a href="#"><svg class="svg-inline svg-adjust" viewBox="0 0 200 100">
<use href="#fa-arrow-right-long-asset" />
</svg>
little he could see his brown belly</a>, slightly domed and divided by arches into stiff sections.
<svg class="svg-inline svg-adjust" viewBox="0 0 200 100">
<use href="#fa-arrow-right-long-offset-asset" />
</svg> Long arrow with offset.
</p>
<p>The bedding was hardly able to cover it and seemed ready to slide off any moment. His many legs, pitifully thin compared with
<svg class="svg-inline svg-adjust" viewBox="0 0 60 100">
<use href="#fa-arrow-right-narrow-asset" />
</svg> the size of the rest of him, waved about helplessly as he looked. "What's happened to me? " he thought. It wasn't a dream.
</p>
<p>
<button class="button" type="button">
<svg class="svg-inline svg-adjust" viewBox="0 0 60 100">
<use href="#fa-arrow-right-narrow-asset" />
</svg> Button
</button>
<button class="button" type="button">
<svg class="svg-inline svg-adjust">
<use href="#fa-arrow-right-asset" />
</svg>
</button>
<button class="button" type="button">
<svg class="svg-inline svg-adjust" viewBox="0 0 200 100">
<use href="#fa-arrow-right-long-asset" />
</svg>
</button>
</p>
</main>

You can try setting width and height for svg tag. Working link is here

add to svg transform="scale(1.7)" for zoon in
<svg transform="scale(1.7)" width="16px" height="24px" version="1" viewBox="0 0 700 700" xmlns="http://www.w3.org/2000/svg" >

Related

CSS - inline SVG interferes with line-height?

I'm struggling to understand the the following css behavior. Maybe I'm missing something important because this actually seems like a simple scenario to me. Consider the following example:
.container {
background-color: lime;
font-size: 20px;
line-height: 20px;
}
<div class="container">
<svg width="1em" height="1em" viewBox="0 0 24 24" >
<circle cx="12" cy="12" r="10"/>
</svg>
Text
</div>
Because container has line-height: 20px set, I'd expect it to be 20px high. At least this is the case if it only contains text. With the svg however it is suddenly 24px high, even though the svg is 20px high, as expected because of height=1em. Also the "Text" has a height of 23px, even though I'd expect it to be 20px.
Interestingly, if I set container's line-height to something like 30px, it behaves as expected: container is now 30px high.
Can you help me understand why container is not 20px high? Or is line-height simply not easily predictable once the container contains other elements than just plain text? Thank you!
There are two things going on in your demo that are affecting the height of div.container. First, line-height isn't an explicit, fixed height: it specifies the minimum height of line boxes within div.container in your case. Since line-height is a minimum, it can grow if something inside it causes it to grow.
That leads to the SVG: it has a default vertical-align of baseline, which aligns it to the baseline of div.container, and, due to its height, causes the height of div.container to grow to accommodate it. By changing vertical-align of the SVG to something else so it fits within your 20px line-height, you can make it fit.
I've added a few different vertical-align props to your demo so you can see how alignment affects height. In general, bottom and top align the svg to the bottom and top of the line, respectively, which, given the SVG's 20px height, keep it within the line-height. However, if you really, really need div.container to be 20px height, height or max-height are probably better bets.
.container {
background-color: lime;
font-size: 20px;
line-height: 20px;
margin-bottom: 1em;
}
<div class="container">
<svg width="1em" height="1em" viewBox="0 0 24 24" >
<circle cx="12" cy="12" r="10"/>
</svg>
Default: vertical-align: baseline (24px)
</div>
<div class="container">
<svg width="1em" height="1em" viewBox="0 0 24 24" style="vertical-align:middle">
<circle cx="12" cy="12" r="10"/>
</svg>
Default: vertical-align: middle (~22px)
</div>
<div class="container">
<svg width="1em" height="1em" viewBox="0 0 24 24" style="vertical-align:bottom">
<circle cx="12" cy="12" r="10"/>
</svg>
Default: vertical-align: bottom (20px)
</div>
<div class="container">
<svg width="1em" height="1em" viewBox="0 0 24 24" style="vertical-align:top">
<circle cx="12" cy="12" r="10"/>
</svg>
Default: vertical-align: top (20px)
</div>
This gets all heights to 20px using flex, align-items: center; and line-height: 1rem;:
.container {
background-color: lime;
font-size: 20px;
line-height: 1rem;
display: flex;
align-items: center;
}
<div class="container">
<svg width="1em" height="1em" viewBox="0 0 24 24" >
<circle cx="12" cy="12" r="10"/>
</svg>
Text
</div>

Extra pixels when element is inline

I am struggling to understand how the calculation of width/height in inline elements works. My question is very similar to this Extra pixels are being added to the span element yet slightly different.
There is a div element of size 50x50. Within the div, there is a span with padding 15px. The span contains SVG circle of size 20x20.
So there are three use cases:
Only div is a block
div - size 50x50 ✔️
span - size: 50x47 ❌ where are those three pixels?
svg - size: 20x20 ✔️
div and span is a block
div - size 50x50 ✔️
span - size: 50x54 ❌ where do these 4 pixels come from?
svg - size: 20x20 ✔️
eveything is a block
div - size 50x50 ✔️
span - size: 50x50 ✔️
svg - size: 20x20 ✔️
span {
/* display: block; */
padding: 15px;
}
div {
height: 50px;
width: 50px;
}
svg {
/* display: block; */
height: 20px;
width: 20px;
}
<div>
<span>
<svg
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<circle
strokeLinecap="butt"
strokeDasharray="64"
cx="12"
cy="12"
r="9"
/>
</svg>
</span>
</div>
CodePen is available here.
Note: I tried it in the latest Chrome but I think it will be the same everywhere. It's probably just some fundamental thing I am missing. :)
Your second case is covered here: Image inside div has extra space below the image. Due to the default alignment you will have extra space under your SVG. This can be fixed by adding display:block like you discovered or by adding vertical-align:top which is more logical as solution:
span {
display: block;
padding: 15px;
outline:1px solid green;
}
div {
height: 50px;
width: 50px;
margin:30px;
outline:1px solid blue;
}
svg {
height: 20px;
width: 20px;
outline:1px solid red;
}
<div>
<span>
<svg
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<circle
strokeLinecap="butt"
strokeDasharray="64"
cx="12"
cy="12"
r="9"
/>
</svg>
</span>
</div>
<div>
<span>
<svg
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg" style="vertical-align:top;"
>
<circle
strokeLinecap="butt"
strokeDasharray="64"
cx="12"
cy="12"
r="9"
/>
</svg>
</span>
</div>
Your first case is a bit tricky because it has nothing to do with the SVG or the width/height you are setting. It's all about font metrics.
To simplify let's remove the div around and consider different SVG inside the same span and without padding:
span {
border: 1px solid green;
margin:0 10px;
}
svg {
outline: 1px solid red;
}
<span>
<svg
viewBox="0 0 24 24" height="20"
xmlns="http://www.w3.org/2000/svg"
>
<circle
strokeLinecap="butt"
strokeDasharray="64"
cx="12"
cy="12"
r="9"
/>
</svg>
</span>
<span>
<svg
viewBox="0 0 24 24" height="30"
xmlns="http://www.w3.org/2000/svg"
>
<circle
strokeLinecap="butt"
strokeDasharray="64"
cx="12"
cy="12"
r="9"
/>
</svg>
</span>
<span>
<svg
viewBox="0 0 24 24" height="50"
xmlns="http://www.w3.org/2000/svg"
>
<circle
strokeLinecap="butt"
strokeDasharray="64"
cx="12"
cy="12"
r="9"
/>
</svg>
</span>
<span>
<svg
viewBox="0 0 24 24" height="200"
xmlns="http://www.w3.org/2000/svg"
>
<circle
strokeLinecap="butt"
strokeDasharray="64"
cx="12"
cy="12"
r="9"
/>
</svg>
</span>
Notice how the span has always the same height whataver the SVG inside due to the nature of inline element. Let's increase the font-size
span {
border: 1px solid green;
margin:0 10px;
}
svg {
outline: 1px solid red;
}
body {
font-size:40px;
}
<span>
<svg
viewBox="0 0 24 24" height="20"
xmlns="http://www.w3.org/2000/svg"
>
<circle
strokeLinecap="butt"
strokeDasharray="64"
cx="12"
cy="12"
r="9"
/>
</svg>
</span>
<span>
<svg
viewBox="0 0 24 24" height="30"
xmlns="http://www.w3.org/2000/svg"
>
<circle
strokeLinecap="butt"
strokeDasharray="64"
cx="12"
cy="12"
r="9"
/>
</svg>
</span>
<span>
<svg
viewBox="0 0 24 24" height="50"
xmlns="http://www.w3.org/2000/svg"
>
<circle
strokeLinecap="butt"
strokeDasharray="64"
cx="12"
cy="12"
r="9"
/>
</svg>
</span>
<span>
<svg
viewBox="0 0 24 24" height="200"
xmlns="http://www.w3.org/2000/svg"
>
<circle
strokeLinecap="butt"
strokeDasharray="64"
cx="12"
cy="12"
r="9"
/>
</svg>
</span>
The span are now bigger in height and the SVG are kept the same. You will also note the small gap at the bottom of the SVG due to the alignment I explained previously. Try to add font-size:0 and see the result.
As you can see the height of your span has nothing to do with the SVG. To that height, you add the vertical padding to get the final height. In your case, the height was 17px and adding the padding you will have 47px which is close to 50px but there is no relation with.
Note that you may get a different result than 47px if you test in different browsers/OS since the font will not for sure be the same and the initial height can vary.
If you check the speficiation you can read:
The 'height' property does not apply. The height of the content area should be based on the font ...
The vertical padding, border and margin of an inline, non-replaced box start at the top and bottom of the content area,
Making the span block element will change this behavior and you will have a more intuitive result as you noticed in your last example: 2*15px of padding + 20px of SVG height.
Related question with more detail in order to understand how the height of element are calculated: How to determine height of content-box of a block and inline element
Another related question: Can specific text character change the line height?

Alternatively clicking on two overlapping svgs

I'm trying to create a buttons panel for a web page. I made the buttons with .svg files. Using margins an other css attributes i got them to the position shown in the code.
My problem:
I can't make both buttons fully clickable, specifically, I can use the orange part just fine, but the bottom half of the white circle, which is overlapping the orange's bounding-box, I cannot click on ,the top area is good.
Of course i wanna be able to successfully click anywhere in the white or the orange, without the overlapping interfering.
I've been reading on pointer events and figure they are the solution, but i can't figure out where (html or css) to use them or how. Also i'm not sure which property would be correct.
How the buttons are working
<!--my html code-->
<div id="brand">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 106 106">
<defs>
<style>.cls-1{fill:#ffffff;}</style>
</defs>
<a xlink:href="index.html">
<path class="cls-1" d="M67.78,52.28a5.58,5.58,0,0,0-6,0,6,6,0,0,0-2.11,2.45,9.11,9.11,0,0,0,0,7.42,6,6,0,0,0,2.11,2.45,5.58,5.58,0,0,0,6,0,6.05,6.05,0,0,0,2.11-2.45,9.11,9.11,0,0,0,0-7.42A6.05,6.05,0,0,0,67.78,52.28Z"/><path class="cls-1" d="M53,0a53,53,0,1,0,53,53A53.06,53.06,0,0,0,53,0ZM77.67,78.67a10,10,0,0,1-4.3.91A13.53,13.53,0,0,1,69.14,79a12.7,12.7,0,0,1-3.74-2.09,34.09,34.09,0,0,1-4.26-4.15A13.74,13.74,0,0,1,55.34,70a14.09,14.09,0,0,1-3.91-5A15,15,0,0,1,50,58.44L50,45.66,43.86,55.92H39.69L33.61,46.1V58.44H25v-28h7.77L41.9,45.34,50.79,30.4h7.77L58.6,45a15.72,15.72,0,0,1,6.2-1.21,15.38,15.38,0,0,1,7.6,1.88,13.68,13.68,0,0,1,5.27,5.24,15,15,0,0,1,1.91,7.56A14.78,14.78,0,0,1,77.3,66.6a13.64,13.64,0,0,1-6.17,5.24,3.52,3.52,0,0,0,1.14.9,3.13,3.13,0,0,0,1.29.26,4.94,4.94,0,0,0,3.63-1.81L81,76A9,9,0,0,1,77.67,78.67Z"/>
</a>
</svg>
</div>
<div id="reserve">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 944.38 115.07">
<defs>
<style>.cls-2{fill:#ff7800;}</style>
</defs>
<a xlink:href="reserve.html">
<path class="cls-2" d="M494.41,80.8h-3.78v7h3.78a4.7,4.7,0,0,0,3.15-.91,3.23,3.23,0,0,0,1.07-2.59,3.27,3.27,0,0,0-1.07-2.61A4.65,4.65,0,0,0,494.41,80.8Z"/><path class="cls-2" d="M400.62,80.8h-3.77v7h3.77a4.73,4.73,0,0,0,3.16-.91,3.23,3.23,0,0,0,1.07-2.59,3.27,3.27,0,0,0-1.07-2.61A4.68,4.68,0,0,0,400.62,80.8Z"/><path class="cls-2" d="M940.67,10a55.59,55.59,0,0,0,3.71-10H535.66A63.67,63.67,0,0,1,474,59.85h-3.54A63.67,63.67,0,0,1,408.72,0H0A55.59,55.59,0,0,0,3.71,10H364.28V20H9.42a68.63,68.63,0,0,0,8.32,10H364.28V40H30.75C40.78,45.88,53.9,50,71,50H364.29V98.82a16.24,16.24,0,0,0,16.25,16.25h183.3A16.25,16.25,0,0,0,580.1,98.82V50H873.4c17.08,0,30.2-4.12,40.23-10H580.1V30H926.64A68.52,68.52,0,0,0,935,20H580.1V10ZM404.92,99.48l-4.36-6.39h-3.71v6.39h-6.8v-24h11a13.71,13.71,0,0,1,5.66,1.08,8.75,8.75,0,0,1,3.8,12.37,8.38,8.38,0,0,1-3.49,3l5.19,7.55Zm29.84,0h-19.3v-24h18.85V80.7H422.19v4h10.68v5.08H422.19v4.4h12.57Zm21.67-3.36a8.25,8.25,0,0,1-3.61,2.79,14.55,14.55,0,0,1-5.84,1,22.23,22.23,0,0,1-5.66-.72,14,14,0,0,1-4.47-1.92l2.23-5A14.38,14.38,0,0,0,442.83,94a14.06,14.06,0,0,0,4.19.65c2.61,0,3.91-.65,3.91-2a1.62,1.62,0,0,0-1.11-1.53,21.14,21.14,0,0,0-3.59-1,35.84,35.84,0,0,1-4.54-1.25,7.63,7.63,0,0,1-3.12-2.15,5.79,5.79,0,0,1-1.31-4,6.84,6.84,0,0,1,1.21-4,8,8,0,0,1,3.59-2.8,14.69,14.69,0,0,1,5.85-1,20.9,20.9,0,0,1,4.67.53,14.31,14.31,0,0,1,4.05,1.57l-2.09,5a14.06,14.06,0,0,0-6.66-1.85,5.63,5.63,0,0,0-3,.6,1.79,1.79,0,0,0-.92,1.56,1.55,1.55,0,0,0,1.09,1.45,20.1,20.1,0,0,0,3.54,1,34.24,34.24,0,0,1,4.55,1.25,8,8,0,0,1,3.13,2.13,5.72,5.72,0,0,1,1.32,4A6.8,6.8,0,0,1,456.43,96.12Zm23.62,3.36h-19.3v-24h18.86V80.7H467.48v4h10.68v5.08H467.48v4.4h12.57Zm18.65,0-4.36-6.39h-3.71v6.39h-6.8v-24h11a13.71,13.71,0,0,1,5.66,1.08,8.42,8.42,0,0,1,3.71,3.09,8.5,8.5,0,0,1,1.31,4.73,8.41,8.41,0,0,1-1.22,4.55,8.32,8.32,0,0,1-3.49,3L506,99.48Zm24.62,0h-6.7l-10.26-24h7.34l6.53,15.66,6.66-15.66h6.73Zm31,0H535v-24h18.85V80.7H541.76v4h10.68v5.08H541.76v4.4h12.57Z"/>
</a>
</svg>
</div>
<!--my css (wide interface being a mayor div that encases all the buttons)-->
#brand { margin: auto; }
#reserve { margin: auto; }
#media screen and (min-width: 751px) {
#brand { width: 11%; overflow: hidden; }
#reserve { width: 95%; margin-top: -5.4%; overflow: hidden; }
#wide-interface { overflow: hidden; white-space: nowrap; letter-spacing: 5px; text-align: center; }
}
You need to apply a clipPath to the white circle to restrict that shape.
By default, pointer-events must not be dispatched on the clipped
(non-visible) regions of a shape.
You will need to adjust the radius and coordinates but something like;
<clipPath id="myClip">
<circle cx="53" cy="25" r="25" />
</clipPath>

How to force SVG icon to scale?

Below is a simple example of an SVG icon being displayed in a blue DIV. First, the CSS:
div.box {
width: 72px;
height: 72px;
background-color: blue;
}
svg.icon {
width: 72px;
height: 72px;
color: white;
fill: currentColor;
}
... and now the HTML:
<body>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<g id="box-icon"><path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"></path></g>
</defs>
</svg>
<div class="box">
<svg class="icon" viewBox="0 0 72 72"><use xlink:href="#box-icon"></use></svg>
</div>
</body>
See https://jsfiddle.net/b9fxvu7k/
Note that the DIV, the icon, and icon's viewbox are all sized to 72 pixels. But the browser insists on rendering the icon as 24 pixels no matter what size I specify for the DIV, icon, and viewbox. I need the SVG icon to scale up to the size of its container. Does anyone see what is missing? Or, is the SVG path I specified hardcoded to 24x24?
You can add a scale factor to your g using the transform attribute, like this:
<g transform="scale(3)" ...
You can also achieve the same result in CSS:
#button-icon {
transform: scale(3);
}
But the CSS method apparently doesn't work in IE.

Draw a crescent moon using SVG in HTML

Is it possible to draw a crescent moon using SVG in HTML?
I've been trying things out at W3 Schools but I don't see an example of this. I don't need any of the shading that you see in typical google images of 'crescent moon', just a solid border crescent moon.
Rather than drawing three circles you can draw a path with two arcs:
<path d="M50 20A40 40 0 1 0 50 70 30 30 0 1 1 50 20z" stroke="black" stroke-width="2" fill="red"/>
This reads as
M 50 20
Move to position (50, 20)
A 40 40 0 1 0 50 70
Draw an arc from that point to position (50, 70). The arc should have a radius of 40 in the x-axis and 40 in the y axis.
30 30 0 1 1 50 20
Draw another arc in the opposite direction from the current point to (50, 20) with a radius of 30 in both axes.
z Join the ends nicely
For more information see SVG specification
Please note that my solution might not be the best. I am not an expert when it comes to vector graphics and you should definitely look for other solution
The approach I took is to draw another image with the same background. It will look like:
To Eliminate the extra border I draw another circle above it
Now Set the 3rd image border to white it will look like:
If you are not using borders you only need to use 2 circles
You might also wanna take a look at clipping and masking. It might be a better approach.
<!DOCTYPE html>
<html>
<body>
<h1>My first SVG</h1>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" />
<circle cx="115" cy="50" r="30" stroke="black" stroke-width="2" fill="white" />
<circle cx="130" cy="50" r="23" stroke="white" stroke-width="2" fill="white" />
</svg>
</body>
</html>
Side note : W3Schools isn't really the reference you should be relying on. It's full of wrong information and outdated stuff. Better resources include:
Mozilla developers network
Web Platform
I found the existing answers lacked the poetry of an Easter Egg, were not based on science and were not that user friendly.
Here is an icon I built for 'dark mode':
<svg id="moon" viewBox="-6 -6 12 12">
<title>Dark mode</title>
<defs>
<mask id="earth">
<rect fill="white" x="-5" y="-5" width="10" height="10"></rect>
<circle fill="black" cx="3.141592654" r="5"/>
</mask>
</defs>
<circle r="5" fill="currentColor" mask="url(#earth)" transform="rotate(-23.5)"/>
</svg>
Things to know:
The viewbox is centered
Width and height is not provided as this is a vector graphic that scales
Scale can be specified in CSS
The standard svg namespace definition is not needed in evergreen browsers
the mask is an offset circle, offset by pi just for to pay homage to the circle
the icon is tilted by 23.5 degrees as that is the tilt of the earth
the id tags are sensibly named, 'earth' for the mask and 'moon' for the icon
the fill is currentColor so that the icon is black on a white page and white on a black page
for brevity the origin of the circles is not given as this defaults to the centre of the viewbox, with the viewbox having a negative origin
if a fixed size is needed then width and height can be added
if used inline in a document as a clickable icon then the CSS needs to have pointer-events: bounding-box specified so that there is a click area
for usability you can change the <title> to be what you want
the viewbox includes padding, to increase it change the viewbox accordingly
the icon should weigh in at a lot less than 256 bytes
If Easter Eggs are morally wrong in your workplace and you can't inline your SVGs then you can save this oneliner as an image and use it that way:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="-6 -6 12 12"><defs><mask id="a"><rect width="10" height="10" x="-5" y="-5" fill="#fff"/><circle cx="3" r="5"/></mask></defs><circle r="5" fill="currentColor" mask="url(#a)" transform="rotate(-23)"/></svg>
This looks the same at icon size even though there are no floating point numbers.
If you want to use the icon inline in your CSS rather than your document (keeping presentation out of markup) then you can specify a CSS variable with the SVG content and then use that in a pseudo selector.
In your script for changing to 'dark mode' you can update the CSS variable or if you want some informative text as well then you can do the usual add a class to hide it method, e.g.::
[].map.call(document.querySelectorAll('button'), function (event) {
event.addEventListener("click", function (event) { [].map.call(document.querySelectorAll('button'), function (el) {
el.classList.toggle('hide');
});
});
});
:root {
--icon-moon-dark: url('data:image/svg+xml,\
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-6 -6 12 12"> \
<defs> \
<mask id="earth"> \
<rect fill="white" x="-5" y="-5" width="10" height="10"></rect> \
<circle fill="black" cx="3.141592654" r="5"/> \
</mask> \
</defs> \
<circle r="5" fill="white" mask="url(%23earth)" transform="rotate(-23.5)"/> \
</svg>');
--icon-moon-light: url('data:image/svg+xml,\
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-6 -6 12 12"> \
<defs> \
<mask id="earth"> \
<rect fill="white" x="-5" y="-5" width="10" height="10"></rect> \
<circle fill="black" cx="3.141592654" r="5"/> \
</mask> \
</defs> \
<circle r="5" fill="black" mask="url(%23earth)" transform="rotate(-23.5)"/> \
</svg>');
}
.hide {
display: none;
}
nav > button {
padding:0;
font-size: x-large;
}
#dark-mode span {
display: grid;
grid-template-columns: auto 1fr;
align-items: center;
grid-auto-flow: column;
text-transform: uppercase;
font-family: fantasy;
padding: .5em 1em;
}
#dark-mode span::before {
content: var(--icon-moon-light);
width: 1.5em;
height: 1.5em;
}
#light-mode span {
background: black;
color: white;
display: grid;
grid-template-columns: auto 1fr;
align-items: center;
grid-auto-flow: column;
text-transform: uppercase;
font-family: cursive;
padding: .5em 1em;
}
#light-mode span::before {
content: var(--icon-moon-dark);
width: 1.5em;
height: 1.5em;
}
<nav><button id="dark-mode" class="hide"><span>Light mode</span></button>
<button id="light-mode"><span>Dark mode</span></button><nav>
Here's a JS/CSS solution that doesn't require SVG, in case it's useful to anyone:
http://codebox.org.uk/pages/html-moon-planet-phases
(disclaimer - I wrote it)
For the records: CSS only version (no need for SVG) (updated with solid border)
http://jsfiddle.net/KA3yp/1/
HTML:
<div class="crescent"></div>
CSS:
.crescent {
width: 300px;
height: 300px;
background-color: #f00;
border-radius:150px;
position: relative;
}
.crescent:before {
content: "";
width:220px;
height: 220px;
display: block;
position: absolute;
border-radius: 110px;
right: -5px;
top: 40px;
background: #fff;
border: 2px solid #000;
}
.crescent:after {
background: none repeat scroll 0 0 #FFFFFF;
border-radius: 100px;
content: "";
display: block;
height: 140px;
position: absolute;
right: -18px;
top: 83px;
width: 140px;
}
I use Raphael.js to draw this moon here: http://jsfiddle.net/franky85/SX3g8/
Or use the code like this:
var paper = Raphael(0, 0, "100%", "100%");
var backgroundColor = 'white';
var moonColor = 'darkorange';
var c = paper.circle(50, 50, 40).attr({
fill: moonColor,
'stroke-width': 0
});
var e = paper.ellipse(50, 50, 20, 40).attr({
fill: backgroundColor,
'stroke-width': 0
});
var r = paper.rect(50, 10, 40, 80).attr({
fill: backgroundColor,
'stroke-width': 0
});
var set = paper.set();
set.push(c);
set.push(e);
set.push(r);
For more complex SVG draw, you'd better use Raphael.js lib.
The document of Raphael.js is here: http://raphaeljs.com/reference.html