SVG mask not loading initially in Chrome - google-chrome
Working on a project which is using a SVG mask on the homepage hero component but for some reason the text in the mask only shows when I resize the window. It's not showing on the initial page load. This is happening only in Chrome (latest version).
You can view the example on the STAGING environment here: https://staging.erwconstructions.com.au/
HTML Markup is:
<section data-component="mask-hero" class="in-view mask-hero">
<picture>
<img src="https://staging.erwconstructions.com.au/wp-content/uploads/2020/07/home-hero.jpg" alt="Home">
<svg width="100%" height="100%" viewBox="0 0 100% 100%">
<defs>
<linearGradient id="gradient">
<stop offset="100%" stop-color="black" />
</linearGradient>
<mask id="mask">
<rect width="100%" height="100%" fill="#fff" />
<text x="0" y="50%">
<tspan x="5vw" dy="-.1em">Building</tspan>
<tspan x="5vw" dy="1em">Redefined</tspan>
</text>
</mask>
</defs>
<rect width="100%" height="100%" fill="url(#gradient)" fill-opacity="0.9" mask="url(#mask)" />
</svg>
</picture>
</section>
The CSS is:
[data-component="mask-hero"] {
height: 100vh;
padding: 0;
background: none;
& picture {
display: block;
height: 100vh;
& img {
height: 100%;
object-fit: cover;
object-position: center;
position: fixed;
will-change: transform;
width: 100%;
z-index: -1;
}
& svg {
display: block;
height: 100%;
}
& text {
font-family: var(--defaultFont);
font-weight: var(--bold);
font-size: 3em;
#media (--app-breakpoint-2) {
font-size: 6em;
}
#media (--app-breakpoint-4) {
font-size: 8em;
}
#media (--app-breakpoint-5) {
font-size: 14em;
}
}
}
}
For some reason there is also a console error regarding the viewBox, even though the correct attributes are set on the SVG:
Error: <svg> attribute viewBox: Expected number, "0 0 100% 100%".
Any help would be greatly appreciated.
Thanks,
Dayne
By the given error, I'd guess to problem is with the viewBox. It should be given an absolute number in px, not percent. Like <svg viewBox="0 0 100 100">
Have you tried using javascript to make it work ?
This code below adds background color to white on rect inside svg code to show the text when the page has loaded.
var svgRect = document.querySelector('svg rect');document.addEventListener("DOMContentLoaded", function(){ setTimeout(function() { svgRect.style.backgroundColor = 'white'; }, 500); });
Related
How to extend an SVG graphic downwards filling the page?
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>
How to render a foreignObject SVG encoded with Base64 on browser
I have written the SVG code below. I want to encode it with Base64 and display it with data:image/svg+xml;base64,BASE64ENCODINGHERE. The issue is probably with foreignobject but I cannot see the text on the image. How can I solve this problem? For this case the Base64 encoding is: PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaW5ZTWluIG1lZXQiIHZpZXdCb3g9IjAgMCA1MDAgMjUwIj48c3R5bGU+ZGl2IHtmb250OiAxNHB4IHNlcmlmO2hlaWdodDoyMDBweDt3aWR0aDo0ODBweDttYXJnaW4tdG9wOjEwcHg7b3ZlcmZsb3c6IGF1dG87fS5iYXNlIHsgZm9udC1mYW1pbHk6IHNlcmlmOyBmb250LXNpemU6IDE0cHg7IH08L3N0eWxlPjxyZWN0IHg9IjAiIHk9IjAiIHJ4PSIxMCIgcnk9IjEwIiB3aWR0aD0iNTAwIiBoZWlnaHQ9IjI1MCIgc3R5bGU9ImZpbGw6d2hpdGU7c3Ryb2tlOmJsYWNrO3N0cm9rZS13aWR0aDo1O2ZpbGwtb3BhY2l0eTowLjE7c3Ryb2tlLW9wYWNpdHk6MC45IiAvPjxmb3JlaWdub2JqZWN0IHg9IjgiIHk9IjgiIHdpZHRoPSI0OTAiIGhlaWdodD0iMjQwIj48dGV4dCB4PSIxMCIgeT0iMTYwIiBjbGFzcz0iYmFzZSI+Q2F0ZWdvcnk6eGF4YXhhPC90ZXh0PjxkaXYgPmhlYmVsZSBodWJlbGUgYnVtIGJhbSBidW08L2Rpdj48L2ZvcmVpZ25vYmplY3Q+PC9zdmc+ So, the link becomes: data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaW5ZTWluIG1lZXQiIHZpZXdCb3g9IjAgMCA1MDAgMjUwIj48c3R5bGU+ZGl2IHtmb250OiAxNHB4IHNlcmlmO2hlaWdodDoyMDBweDt3aWR0aDo0ODBweDttYXJnaW4tdG9wOjEwcHg7b3ZlcmZsb3c6IGF1dG87fS5iYXNlIHsgZm9udC1mYW1pbHk6IHNlcmlmOyBmb250LXNpemU6IDE0cHg7IH08L3N0eWxlPjxyZWN0IHg9IjAiIHk9IjAiIHJ4PSIxMCIgcnk9IjEwIiB3aWR0aD0iNTAwIiBoZWlnaHQ9IjI1MCIgc3R5bGU9ImZpbGw6d2hpdGU7c3Ryb2tlOmJsYWNrO3N0cm9rZS13aWR0aDo1O2ZpbGwtb3BhY2l0eTowLjE7c3Ryb2tlLW9wYWNpdHk6MC45IiAvPjxmb3JlaWdub2JqZWN0IHg9IjgiIHk9IjgiIHdpZHRoPSI0OTAiIGhlaWdodD0iMjQwIj48dGV4dCB4PSIxMCIgeT0iMTYwIiBjbGFzcz0iYmFzZSI+Q2F0ZWdvcnk6eGF4YXhhPC90ZXh0PjxkaXYgPmhlYmVsZSBodWJlbGUgYnVtIGJhbSBidW08L2Rpdj48L2ZvcmVpZ25vYmplY3Q+PC9zdmc+ <svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet" viewBox="0 0 500 250"> <style> div { font: 14px serif; height: 200px; width: 480px; margin-top: 10px; overflow: auto; } .base { font-family: serif; font-size: 14px; } </style> <rect x="0" y="0" rx="10" ry="10" width="500" height="250" style="fill:white;stroke:black;stroke-width:5;fill-opacity:0.1;stroke-opacity:0.9" /> <foreignobject x="8" y="8" width="490" height="240"> <text x="10" y="160" class="base">Category:xaxaxa</text> <div>hebele hubele bum bam bum</div> </foreignobject> </svg> Expected output: enter image description here Result I got: enter image description here
It's foreignObject with a capital O. SVG is case sensitive except when it's embedded in HTML. You need to specify that the div lives in the XHTML namespace There's no such thing as a text element in HTML so if you want to keep that, move it from the foreignObject contents. I've just removed it. That gives us this... <svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet" viewBox="0 0 500 250"> <style> div { font: 14px serif; height: 200px; width: 480px; margin-top: 10px; overflow: auto; } .base { font-family: serif; font-size: 14px; } </style> <rect x="0" y="0" rx="10" ry="10" width="500" height="250" style="fill:white;stroke:black;stroke-width:5;fill-opacity:0.1;stroke-opacity:0.9" /> <foreignObject x="8" y="8" width="490" height="240"> <div xmlns="http://www.w3.org/1999/xhtml">hebele hubele bum bam bum</div> </foreignObject> </svg> and if you base64 encode that you get data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaW5ZTWluIG1lZXQiIHZpZXdCb3g9IjAgMCA1MDAgMjUwIj4KICA8c3R5bGU+CmRpdiB7CiAgZm9udDogMTRweCBzZXJpZjsKICBoZWlnaHQ6IDIwMHB4OwogIHdpZHRoOiA0ODBweDsKICBtYXJnaW4tdG9wOiAxMHB4OwogIG92ZXJmbG93OiBhdXRvOwp9CgouYmFzZSB7CiAgZm9udC1mYW1pbHk6IHNlcmlmOwogIGZvbnQtc2l6ZTogMTRweDsKfQogIDwvc3R5bGU+CiAgPHJlY3QgeD0iMCIgeT0iMCIgcng9IjEwIiByeT0iMTAiIHdpZHRoPSI1MDAiIGhlaWdodD0iMjUwIiBzdHlsZT0iZmlsbDp3aGl0ZTtzdHJva2U6YmxhY2s7c3Ryb2tlLXdpZHRoOjU7ZmlsbC1vcGFjaXR5OjAuMTtzdHJva2Utb3BhY2l0eTowLjkiIC8+CiAgPGZvcmVpZ25PYmplY3QgeD0iOCIgeT0iOCIgd2lkdGg9IjQ5MCIgaGVpZ2h0PSIyNDAiPgo8ZGl2IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIj5oZWJlbGUgaHViZWxlIGJ1bSBiYW0gYnVtPC9kaXY+CiAgPC9mb3JlaWduT2JqZWN0Pgo8L3N2Zz4=
CSS svg hover animation/transition
im using a svg clip-path as mask for an image. Now i want an inner border inside it on hover. So i made a second clip-path for hover but the transition doesnt affect it. I want the border comming from the sides (reducing zoom/negative scaling). Here you can see what i want without working animation/transition: body { background: #ccc; } .clip-svg { position: relative; display: block; height: 400px; width: 300px; background-position: center center; background-size: auto 100%; clip-path: url(#Emblem); transition: 0.4s all ease; } .clip-svg:hover { clip-path: url(#Emblem2); } <div class="clip-svg" style="background-image: url(https://images.pexels.com/photos/864994/pexels-photo-864994.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260)"></div> <svg width="0" height="0"> <defs> <clipPath id="Emblem"> <path d="M279,240c0,96-139.4,145-139.4,145S22,336,22,240c0-58,0-203,0-203s65-11,129-11c75,0,128,11,128,11S279,136,279,240z"/> </clipPath> <clipPath id="Emblem2"> <path d="M39,51.6V240c0,72.4,80.9,116.6,101.2,126.5c11-4.5,35.7-15.4,59.8-32.3c18.5-13,33.2-26.8,43.6-41.3 c12.2-17,18.4-34.8,18.4-53V51.3C240.8,48,200.9,43,151,43C106.3,43,59.9,48.7,39,51.6z"/> <path d="M151,26C87,26,22,37,22,37s0,145,0,203c0,96,117.6,145,117.6,145S279,336,279,240c0-104,0-203,0-203S226,26,151,26z M270,240c0,19.9-6.7,39.3-19.9,57.7c-10.9,15.1-26.2,29.7-45.5,43.1c-26.2,18.3-52.8,29.8-63.1,33.8l-1.6,0.6l-1.6-0.8 c-10.4-5-37.2-18.9-61.3-41.3c-30.5-28.4-46-59.7-46-93.2V44.7l3.4-0.5C53.5,41.4,103.1,35,151,35c53.2,0,95.3,5.6,115.6,8.9 l3.4,0.5V240z"/> </clipPath> </defs> </svg> <br/> Image: https://www.pexels.com/...d-tablet-864994/ Thanks in advance
I would consider two layers each one using a clip-path and I would control the opacity: body { background: #ccc; } .clip-svg { position: relative; display: inline-block; height: 400px; width: 300px; } .clip-svg::before, .clip-svg::after { content: ""; position: absolute; top: 0; right: 0; left: 0; bottom: 0; background-position: center center; background-size: auto 100%; background-image: var(--i); transition: 0.8s all ease; } .clip-svg::before { clip-path: url(#Emblem2); } .clip-svg::after { clip-path: url(#Emblem); } .clip-svg:hover::after { opacity:0; } <div class="clip-svg" style="--i: url(https://images.pexels.com/photos/864994/pexels-photo-864994.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260)"></div> <svg width="0" height="0"> <defs> <clipPath id="Emblem"> <path d="M279,240c0,96-139.4,145-139.4,145S22,336,22,240c0-58,0-203,0-203s65-11,129-11c75,0,128,11,128,11S279,136,279,240z"/> </clipPath> <clipPath id="Emblem2"> <path d="M39,51.6V240c0,72.4,80.9,116.6,101.2,126.5c11-4.5,35.7-15.4,59.8-32.3c18.5-13,33.2-26.8,43.6-41.3 c12.2-17,18.4-34.8,18.4-53V51.3C240.8,48,200.9,43,151,43C106.3,43,59.9,48.7,39,51.6z"/> <path d="M151,26C87,26,22,37,22,37s0,145,0,203c0,96,117.6,145,117.6,145S279,336,279,240c0-104,0-203,0-203S226,26,151,26z M270,240c0,19.9-6.7,39.3-19.9,57.7c-10.9,15.1-26.2,29.7-45.5,43.1c-26.2,18.3-52.8,29.8-63.1,33.8l-1.6,0.6l-1.6-0.8 c-10.4-5-37.2-18.9-61.3-41.3c-30.5-28.4-46-59.7-46-93.2V44.7l3.4-0.5C53.5,41.4,103.1,35,151,35c53.2,0,95.3,5.6,115.6,8.9 l3.4,0.5V240z"/> </clipPath> </defs> </svg>
I don't see a way to achieve what you want using clip paths on an HTML element. You can only replace one clip path with another in CSS. You can't interpolate between two of them. However it is fairly easy to do, if you are okay with moving the image into an SVG. Then you can do whatever you want with the inner border. Note however, with this solution, the inner border is not a clip path, so it doesn't make the image transparent. I don't know if that is important to you or not. It should be possible to do that if you really need it to. body { background: #ccc; } .clip-svg .emblem2-ref { transform-origin: 150px 200px; transform: scale(1.2, 1.2); transition: 0.4s all ease; } .clip-svg:hover .emblem2-ref { transform: scale(1, 1); } #Emblem2 { fill: #ccc; } <!-- Clip path and inner border definitions. Can be included once and used by multiple SVGs --> <svg width="0" height="0"> <defs> <clipPath id="Emblem"> <path d="M279,240c0,96-139.4,145-139.4,145S22,336,22,240c0-58,0-203,0-203s65-11,129-11c75,0,128,11,128,11S279,136,279,240z"/> </clipPath> <path id="Emblem2" d="M39,51.6V240c0,72.4,80.9,116.6,101.2,126.5c11-4.5,35.7-15.4,59.8-32.3c18.5-13,33.2-26.8,43.6-41.3 c12.2-17,18.4-34.8,18.4-53V51.3C240.8,48,200.9,43,151,43C106.3,43,59.9,48.7,39,51.6z M270,240c0,19.9-6.7,39.3-19.9,57.7c-10.9,15.1-26.2,29.7-45.5,43.1c-26.2,18.3-52.8,29.8-63.1,33.8l-1.6,0.6l-1.6-0.8 c-10.4-5-37.2-18.9-61.3-41.3c-30.5-28.4-46-59.7-46-93.2V44.7l3.4-0.5C53.5,41.4,103.1,35,151,35c53.2,0,95.3,5.6,115.6,8.9 l3.4,0.5V240z"/> </defs> </svg> <!-- Will need one of these SVGs for every image you want to display --> <svg width="300" height="400" class="clip-svg"> <g clip-path="url(#Emblem)"> <image width="300" height="400" preserveAspectRatio="xMidYMid slice" xlink:href="https://images.pexels.com/photos/864994/pexels-photo-864994.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260"/> <use class="emblem2-ref" xlink:href="#Emblem2"/> </g> </svg> <br/> Image: https://www.pexels.com/...d-tablet-864994/
I want to implement SVG clip-path for SVG element
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>
Hover event on hidden part of the div
I have the following sample html with css. My probem is, when I move the mouse over the top coners of the parent html element, the hover role become active. But it should not be, because it is a hidden part of the parent. It is working correctly in firefox, but not in chrome, opera, ie or edge. Any suggestions? It is a browser related bug or it is working as intended? If I remove the position properties from the css, then it is working properly, but is not an option. .perent{ top: 0px; right: 0px; width: 500px; height: 500px; background-color:red; border-radius:50%; overflow:hidden; position:relative; } .child{ width: 1000px; height: 200px; background-color:blue; position:absolute; } .child:HOVER{ background-color:black; } <div class="perent"> <div class="child"> </div> </div>
For a completely round cut, use this: Add this: .perent { -webkit-clip-path: circle(50.0% at 50% 50%); clip-path: circle(50.0% at 50% 50%); }
Although I am not sure if it is a browser bug or not, but I can suggest using svg body { margin: 0; } svg { height: 100vh; } .child:hover { fill: black; } <svg viewbox="0 0 100 100"> <defs> <clipPath id="clipPath"> <circle r="50" cx="50" cy="50"/> </clipPath> </defs> <rect class="child" x="0" y="0" width="100" height="40" fill= "blue" clip-path="url(#clipPath)"/> <rect x="0" y="40" width="100" height="60" fill="red" clip-path="url(#clipPath)"/> </svg>