Safari SVG Image Mask Not Resizing using CSS - css

I am trying to resize an svg image with a mask using css. The issue I am running into is with Safari as it doesn't seem to allow the CSS classes to override the default values. Here's the inline svg code:
<svg width="48" height="48" class="icon green">
<defs>
<mask id="svgmask-947">
<image class="svg-image" width="48" height="48" href="/themes/custom/assets/media/images/fa-png/campus.png"></image>
</mask>
</defs>
<rect class="icon-mask" mask="url(#svgmask-947)" width="48" height="48" y="0" x="0"></rect>
The SVG won't resize, if I simple apply any class to it with a new width/height in CSS. Here's sample CSS:
.icon, rect, mask image {
width:24px;
height: 24px;
}
Applying the CSS in all other browsers works, just not Safari.
Thanks for any insight and help.

Found the solution as I was missing the viewbox attribute:
<svg width="48" height="48" class="icon green" viewBox="0 0 48 48">
<defs>
<mask id="svgmask-980">
<image class="svg-image" width="48" height="48" href="/themes/custom/assets/media/images/fa-png/campus.png"></image>
</mask>
</defs>
<rect class="icon-mask" mask="url(#svgmask-980)" width="48" height="48" y="0" x="0"></rect>

Related

SVG background color doesn't work on Firefox

I have svg icon, looking like add to watchlist but background color doesn't work on the firefox browser, any help will be appreciated.
svg {
background-color: #1ebaed;
border: 1px solid #ffffff;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" width="40" height="40">
<defs>
<image width="40" height="40" id="watchlist" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAAAAXNSR0IB2cksfwAAAYBQTFRFAAAAAAAAAAAAAAAADw8PJSUlNDQ0Ojo6Ozs7Nzc3LS0tGRkZFxcXUFBQp6en5OTk+Pj4/////Pz88PDwxsbGdHR0Kysrf39/6+vr+/v7tLS0W1tb6enpyMjIe3t7R0dHPT09X19fq6ur7u7unp6eFhYWCgoK7OzsV1dXIiIiurq63t7eNjY2EBAQvb298/PzNTU1Li4uDg4OBQUFtra2SUlJBwcHvLy8fX19ERERrKys/f393NzcHh4e9PT09vb2AQEBkJCQEhISBAQEra2t8vLyISEhpqamOTk50tLSJCQkhoaGZGRkpaWlTExMzc3NlpaWxMTECAgIwsLC4uLiDAwM1dXVQUFBiYmJODg45+fn/v7+Tk5O4eHhjIyMCQkJdXV119fXYmJic3NzMjIyeHh4iIiI2dnZv7+/AgICbm5ueXl5ExMTqampdnZ2Ly8vGxsbGBgYTU1NRkZGSkpKysrK9/f35eXlQkJCx8fHcXFxn5+fpKSkk5OTQ0NDFRUVnB3CTAAAAIB0Uk5T3O3y//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9MrCj1AAABXUlEQVR4nGNgYCQKMDAwMRMFmBgYiVPIOKqQRgpZWNnYOTi5uPEr5OHl4xcQBAIhYRFRMZwKucUlBJGApBQ7doXSMmB5WTl5BUUlZTBbRRVToZoKWEpdA8LV1AJztXXQFerqgSX0DYBsVkMjZmZjE4iAKapCM3OIuyyYmS2tBKxt5JmZbe3AIvYKyAodHCHq1J2YnV1ADFc3ZmZ3iBi/KpJCD6hHPR2YvazBLG9mZh+ooC+SQj+omD8zsxiEFQAMBahgIJLCoGCIWEgQc2gYmBXOzBwBDc5IZM+4RYEFo2OYmdligZJxzMzxsRCFCajBwwYJ7URgwDglJacARVIh6tLQA5wrHSyeYQvhZmZB7M3GjMKcXLCURF5+QaFXEcTRicVYE0VJKVjW2lW4DMwo9w7FmiiAoMJFWwgaKBKVVU5IMhgJN95QMaK6praqrh5VfFBlrpGhkOjCntjqAwB2bUIilx2T4wAAAABJRU5ErkJggg=="/>
</defs>
<style>
tspan { white-space:pre }
</style>
<g id="Mobile View Expanded">
<use id="Watchlist icon" style="mix-blend-mode: lighten" href="#watchlist" x="0" y="0" />
</g>
</svg>

How to use SVG clipPath with Pattern via CSS clip-path property?

The initial SVG figure with pattern:
<svg width="200" height="200" viewBox="0 0 100 100">
<defs>
<pattern id="img-dotted-dots" x="0" y="0" height=".08" width="7.69%">
<circle cx="2" cy="2" fill="white" r="0.8"></circle>
</pattern>
<mask id="img-dotted-mask">
<rect width="100" height="100" fill="url(#img-dotted-dots)"></rect>
</mask>
</defs>
<path d="M0 0 H 100 V 100 H 0 Z" mask="url(#img-dotted-mask)" fill="#1063B1"></path>
</svg>
Need to achieve:
One instance of the SVG figure with pattern for refferencing with CSS as clip-path.
I have tried to create SVG clipPath element and bind to CSS clip-path by this way
.figure {
width: 300px;
height: 300px;
clip-path: url(#img-dotted-clip-path);
background-color: #1063B1;
}
<div class="figure"></div>
<svg width="0" height="0" viewBox="0 0 100 100">
<defs>
<clipPath
clipPathUnits="objectBoundingBox"
id="img-dotted-clip-path">
<pattern
patternUnits="objectBoundingBox"
patternContentUnits="objectBoundingBox"
x="0" y="0" height="0.1" width="0.1">
<circle cx="0" cy="0" fill="white" r="0.5"></circle>
</pattern>
</clipPath>
</defs>
</svg>
Nothing happens.
Expected result - the same as the previous snippet.
For comparing:
If I use SVG rect - CSS clip-path works.
If pattern - doesn't
.figure {
width: 300px;
height: 300px;
clip-path: url(#img-dotted-clip-path);
background-color: #1063B1;
}
<div class="figure"></div>
<svg width="0" height="0" viewBox="0 0 100 100">
<defs>
<clipPath
clipPathUnits="objectBoundingBox"
id="img-dotted-clip-path">
<rect width="1" height="1"></rect>
</clipPath>
</defs>
</svg>
The only things that are valid inside a clip path are:
Shape elements (‘circle’, ‘ellipse’, ‘line’, ‘path’, ‘polygon’, ‘polyline’, ‘rect’)
‘text’
‘use’
Plus you can use animation elements etc to animate the clip path. However, only the shapes of those elements are used. Effects such as patterns, filters, etc are ignored.
The only way you could get the effect you want to work as a clipping path would be to add numerous <circle> elements to your <clipPath>.
<clipPath>
<circle>
<circle>
<circle>
<circle>
... etc ...
</clipPath>
But you could use a mask instead. Masks allow patterns.
.figure {
width: 300px;
height: 300px;
-webkit-mask: url(#img-dotted-mask);
mask: url(#img-dotted-mask);
background-color: #1063B1;
}
<p>This only works in Firefox</p>
<div class="figure"></div>
<svg width="0" height="0">
<defs>
<pattern id="img-dotted-pattern"
viewBox="0 0 1 1"
patternUnits="userSpaceOnUse" x="0" y="0" width="20" height="20">
<rect width="1" height="1" fill="black"/>
<circle cx="0.5" cy="0.5" fill="white" r="0.15"></circle>
</pattern>
<mask id="img-dotted-mask">
<rect width="2000" height="2000" fill="url(#img-dotted-pattern)"/>
</mask>
</defs>
</svg>
However inline SVG masks applied to HTML elements, like my example above, only work in Firefox. To get an SVG mask to work in Chrome, you would need to use mask or mask-image with an external or Data URL (as Temani has done in their answer).
You can recreate the same thing using mask combined with radial-gradient
.figure {
width: 300px;
height: 300px;
background:linear-gradient(to right,red,#1063B1);
/*radius here size here*/
-webkit-mask:radial-gradient(3px, #fff 97%,transparent 100%) 0 0/20px 20px;
mask:radial-gradient(3px, #fff 97%,transparent 100%) 0 0/20px 20px;
}
body {
background:#f2f2f2;
}
<div class="figure"></div>
Or consider the SVG inside the mask property. Make sure to escape the # and correctly set the viewbox and width/height to have a perfect repeat
.figure {
width: 300px;
height: 300px;
background:linear-gradient(to right,red,#1063B1);
-webkit-mask:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="200" height="192" viewBox="0 0 100 90"><defs><pattern id="img-dotted-dots" x="0" y="0" height=".08" width="7.69%"><circle cx="2" cy="2" fill="white" r="0.8"></circle></pattern><mask id="img-dotted-mask"><rect width="100" height="100" fill="url(%23img-dotted-dots)"></rect></mask></defs><path d="M0 0 H 100 V 100 H 0 Z" mask="url(%23img-dotted-mask)" fill="%231063B1"></path></svg>');
mask:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="200" height="192" viewBox="0 0 100 90"><defs><pattern id="img-dotted-dots" x="0" y="0" height=".08" width="7.69%"><circle cx="2" cy="2" fill="white" r="0.8"></circle></pattern><mask id="img-dotted-mask"><rect width="100" height="100" fill="url(%23img-dotted-dots)"></rect></mask></defs><path d="M0 0 H 100 V 100 H 0 Z" mask="url(%23img-dotted-mask)" fill="%231063B1"></path></svg>');
}
body {
background:#f2f2f2;
}
<div class="figure"></div>

Clip Path with SVG

I have created the below CSS Clip path with SVG. I would like to know that how to make it some unique shapes rather than the normal hexagonal mask? Also i would like to give border radius to the edges. Any help would be appreciated.
Thanks in Advance.
http://ktdev.khaleejtimes.ae/bg/bg-shapenw1.html
.svg_pan {
width: 90%;
height: 600px;
border-radius: 50px;
}
<svg class="svg-graphic svg_pan" width="180" height="200" viewBox="0 0 560 645" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" version="1.1">
<g>
<clipPath id="hexagonal-mask">
<polygon points="130,0 0,160 0,485 270,645 560,485 460,160" />
</clipPath>
</g>
<a xlink:href="#">
<image clip-path="url(#hexagonal-mask)" height="100%" width="100%" xlink:href="al-seef.jpg" />
</a>
</svg>
You will need to calculate the d attribute for a path - your polygon with rounded corners. In this case I'm using quadratic Béziers for the rounded corners. I hope it helps.
.svg_pan {
border:1px solid;
}
<svg class="svg-graphic svg_pan" width="180" height="200" viewBox="0 0 560 645" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" version="1.1">
<defs>
<clipPath id="hexagonal-mask-rounded">
<path d="M147.996,8.725 Q130,0 117.388,15.522L12.612,144.478 Q0,160 0.000,180.000L0.000,465.000 Q0,485 17.206,495.196L252.794,634.804 Q270,645 287.512,635.338L542.488,494.662 Q560,485 554.118,465.884L465.882,179.116 Q460,160 442.004,151.275Z" />
</clipPath>
</defs>
<a xlink:href="#">
<image clip-path="url(#hexagonal-mask-rounded)" height="650" width="650" xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/beagle400.jpg" />
</a>
</svg>
This is a tool you may use to calculate the d attribute for the path using the points attribute of the polygon: https://enxaneta.github.io/SVG_polygon_with_rounded_corners/

Center an element of a SVG mask

I'm a newbie in SVG so it's probably an easy question. I'm trying to make an SVG Mask with a simple triangle shape inside a rectangle. What I want to achieve is to get the rectangle responsive with his width but the triangle should
- get a fixed size
- be always at the center of the viewport
You'll understand better with my snippet:
.header-arrow {
height: 70px;
}
svg {
height: inherit;
}
#arrow-down-alpha {
transform: translateX(calc(50vw - 130px/2));
}
<div class="header-arrow">
<svg width="100%">
<defs>
<mask id="myMask" x="0" y="0" width="100%" height="100%">
<rect fill="white" x="0" y="0" width="100%" height="100%" />
<polygon id="arrow-down-alpha" fill="black" x="00" y="0" width="165px" height="100%" points="55.91 37.8 111.81 0 0 0 55.91 37.8" />
</mask>
</defs>
<rect id="base-mask" mask="url(#myMask)" x="0" y="0" width="100%" height="100%" />
</svg>
</div>
It's workning right now in chrome, but the translateX (or translate) is not working in firefox and edge. I've tried to use the transform SVG attribute but it seems that I can't use percentages values.
I'm not realy familiar with the viewbox but I'm not sure it will help in this case.
Thanks anyway for any kind of help !
Here's one way to achieve what you want without relying on new units or calc(). It should be cross-browser compatible also.
How it works:
We wrap the triangle in a nested SVG. We use an SVG because it has an x attribute which can take percentages.
We position this nested SVG at x="50%". It is now centred in the mask (roughly, see next step).
We move the triangle shape so it is centred at x=0. That's so that it is not offset from the centre of the mask.
We set overflow="visible" on the nested SVG so the part of the triangle that is now off the left of the SVG (ie. x < 0) are not clipped.
.header-arrow {
height: 70px;
}
svg {
height: inherit;
}
<div class="header-arrow">
<svg width="100%">
<defs>
<mask id="myMask" x="0" y="0" width="100%" height="100%">
<rect fill="white" x="0" y="0" width="100%" height="100%" />
<svg x="50%" overflow="visible">
<polygon fill="black" points="0 38 56 0 -56 0" />
</svg>
</mask>
</defs>
<rect id="base-mask" mask="url(#myMask)" x="0" y="0" width="100%" height="100%" />
</svg>
</div>

Using SVG <image> as cover inside proportion less SVG

DEMO
Objective: I am trying to create a triangle shaped proportion less image in HTML.
My Approach: I have decided to use SVG to achieve this by creating a polygon triangle that can stretch & shrink to fit any dimension and used it as a mask on image that is suppose to fit in any dimension without loosing its own proportion.
Issue: Although the shape is working as I want but the background image stretches with the shape, is there any way I can make the image behave to something similar like css background-size: cover property.
Code:
HTML
<div id="svg-container">
<svg width='100%' height='100%' viewBox="0 0 100 100" preserveAspectRatio="none" style='background-color: whitesmoke'>
<defs>
<polygon id="mask" points="0,0 0,100 0,100 100,0" />
<pattern id="image" patternUnits="userSpaceOnUse" width="100" height="100" x="0" y="0">
<image xlink:href="http://lorempixel.com/500/500" x="0" y="0" width="100%" height="100%" preserveAspectRatio="xMinYMin slice"/>
</pattern>
</defs>
<use xlink:href="#mask" fill="url(#image)"></use>
</svg>
</div>
CSS:
#svg-container {
width: 100%;
height: 100px;
}
To check same issue using SVG image tag here.

Resources