Related
In HTML, I am trying to use SVG graphics to create a background section to a part of my site. It uses a curve that sections off a part of the website to another. I have managed to create a basic outline for the general shape of the SVG: Picture of the animated banner and SVG page section.
However, I am expecting the SVG element to be stretched downwards so it fills out the rest of the page. This is not the case however as when scrolling down the SVG ends and the background takes up the rest of the site: The SVG is too small.
I need help extending the SVG to fill the rest of the page underneath it.
Current HTML Code:
div class="wave">
<svg width="100%" height="200px" fill="none" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<path
fill="white"
d="
M0 67
C 273,183
822,-90
2525.01,98
V 359
H 0
V 67
Z">
</path>
</svg>
</div>
I have tried to change the SVG values but they normally just turn the graphic out of shape. I would like help understanding how to understand and fix this problem.
Futhermore, how to use the SVG viewBox to preserve the aspect ratio of the graphic?
[Update] Here is the website so far. I need to move the SVG graphic downwards as indicated in the arrow so the black particle background is above it: Picture Update
The problem here is you can (see thereafter) "fill" till the end of page, now that means playing with viewport and aspect ratio as said Robert. That means also your "curve" won't be constant regarding different sizes of screen.
Check and play with the snippet thereafter:
.wave {
width: 100vw;
height: 100vh;
}
<div class="wave">
<svg width="auto" height="100%" fill="none" viewbox="0 0 512 128" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin slice">
<path
fill="red"
d="M 0,75 C 158.44341,97.135847 296.6677,25.650819 512,25 V 128 H 0 Z">
</path>
</svg>
</div>
perhaps this can work for you
you have your wave, plus a rect under
body {
margin: 0;
padding: 0;
width: 100vw;
height: 100vh;
}
.wave {
width: 100%;
height: 100%;
}
<div class="wave">
<svg width="auto" height="100%" fill="#ff0000" viewbox="0 0 512 128" xmlns="http://www.w3.org/2000/svg">
<path d="M 0,75 C 158.44341,97.135847 296.6677,25.650819 512,25 V 128 H 0 Z"></path>
<rect width="512" height="129" x="0" y="127" />
</svg>
</div>
I thought about your problem.
If the idea is to have an image fullscreen on home with a wave svg down with a color and continuity same color in other part. An idea would be the following:
body {
margin: 0;
padding: 0;
overflow-x: hidden;
}
section {
min-height: 100vh;
background-color: #999999;
margin: 0;
}
section h2 {
margin: 0;
}
#home {
margin: 0;
padding: 0;
width: 100vw;
background-image: url("https://picsum.photos/1920/1080");
background-size: cover;
background-position: center;
position: relative;
}
#home .title {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: #7b98bc;
}
.wave {
width: 100%;
height: 100vh;
}
.wave svg {
display: inline-block;
}
<section id="home">
<div class="wave">
<svg width="100%" height="auto" fill="#999999" viewbox="0 0 512 128" preserveAspectRatio="xMinYMax meet" xmlns="http://www.w3.org/2000/svg">
<path d="M 0,75 C 158.44341,97.135847 296.6677,25.650819 512,25 V 128 H 0 Z"/>
</svg>
</div>
<div class="title">
<h2>Title of my website</h2>
</div>
</section>
<section id="part1">
<h2>here we are section part1</h2>
</section>
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" >
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>
I want to implement SVG clip-path for SVG element. I have a DIV element in which I want to put SVG element which will act as a clipping mask, and also I have the separate SVG element that has an image to which the clipping mask will be applied.
The first problem I faced with is that clipping mask moves to the left top corner of the viewport but not located inside of the parent DIV element.
The second problem is that I want to make an image on the full screen not depending on the screen size.
Incorrect Mask Circle
Correct Mask Circle (what I want to have)
Do you have suggestions how to make it?
Thanks in advance!
html, body { margin:0; padding:0; overflow:hidden }
svg { position:absolute; top:0; left:0;}
.image-clip-src {
width: 100%;
height: 100%;
}
.svg-wrapper {
width: 72px;
height: 72px;
padding: 2.5em;
border: 1px solid #4D4F51;
margin: 0 auto;
border-radius: 50%;
overflow: hidden;
position: fixed;
top: 55%;
z-index: 9;
left: 64%;
transform: translateY(-50%);
cursor: pointer;
}
.clipped-image image {
clip-path: url(#clipping);
}
<svg class="clipped-image" width="100%" height="100%" viewBox="0 0 1440 960" preserveAspectRatio="xMinYMin meet">
<image class="image-clip-src" xlink:href="https://images.unsplash.com/photo-1526327227970-4bda49fa3489?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=3c4bce33d96df6b18af53fb2dae3363e&auto=format&fit=crop&w=1650&q=80" width="100%" height="100%" overflow="visible"/>
</svg>
<div class="svg-wrapper">
<svg class="svg-defs">
<defs>
<clipPath id="clipping">
<circle r="72" stroke="black" stroke-width="3"/>
</clipPath>
</defs>
</svg>
</div>
That's not the way SVG works.
When you tell something to use a clip path, all it sees is the clip path definition itself. It doesn't know or care about where on the page you have positioned it's parent <svg>.
If you want the clip circle to be at a certain position on the water image, you need to specify its position using cx and cy.
html, body { margin:0; padding:0; overflow:hidden }
svg { position:absolute; top:0; left:0;}
.image-clip-src {
width: 100%;
height: 100%;
}
.clipped-image image {
clip-path: url(#clipping);
}
<svg class="clipped-image" width="100%" height="100%" viewBox="0 0 1440 960" preserveAspectRatio="xMinYMin meet">
<defs>
<clipPath id="clipping">
<circle cx="64%" cy="55%" r="72" stroke="black" stroke-width="3"/>
</clipPath>
</defs>
<image class="image-clip-src" xlink:href="https://images.unsplash.com/photo-1526327227970-4bda49fa3489?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=3c4bce33d96df6b18af53fb2dae3363e&auto=format&fit=crop&w=1650&q=80" width="100%" height="100%" overflow="visible"/>
<circle cx="64%" cy="55%" r="72" fill="none" stroke="#4D4F51" stroke-width="1"/>
</svg>
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