Is the <clipPath> just a bad alternative to <mask>? - html

SVG Clipping vs. Masking
I recently came across clipping and masking in SVG. I noticed that the <mask> element includes every feature of the <clipPath> element.
In addition, <clipPath> has many disadvantages:
lower browser compatibility
no transparency allowed
no structural, gradient or image elements allowed
Because of this I wonder what the <clipPath> element is for:
The <mask> element is much more powerful!
That is my code:
<svg viewBox="0 0 100 100" width="100" height="100">
<defs>
<clipPath id="clip">
<rect x="0" y="0" width="50" height="50"/>
</clipPath>
</defs>
<circle cx="50" cy="50" r="50" fill="grey" clip-path="url(#clip)"/>
</svg>
Finally, my questions:
Should I use <mask> instead of <clipPath> in my code snippet?
Is there any situation when <clipPath> is more suitable than <mask>?

Related

How to fix blurry svg icons in chrome

Our small (16px), circular icons suddenly degraded in quality on chrome with no change to our code or assets. The svgs look fine on a macbook screen, but blur on a monitor. Current running theory is a chrome update, but am looking for possible solutions/fixes. Any information or advice welcome.
example of blurry edges on an icon
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<path d="M50,0a50,50,0,1,0,50,50A50,50,0,0,0,50,0Zm0,91.6667A41.6667,41.6667,0,1,1,91.6667,50,41.6668,41.6668,0,0,1,50,91.6667Z"/>
<g>
<circle cx="49.2659" cy="75.9917" r="5.7828" fill="#6d6e71"/>
<path d="M53.7632,63.0029H43.85c0-10.0845,5.03-15.1208,9.0712-19.1674,3.326-3.33,5.5236-5.5311,5.5236-10.2049,0-6.4239-6.9209-6.6089-7.71-6.6089-.3743,0-9.1787.0818-9.1787,7.16H31.642c0-11.2085,9.6047-17.0731,19.0922-17.0731,11.57,0,17.6239,8.3117,17.6239,16.5224,0,8.7764-4.6706,13.4524-8.4225,17.21C56.3524,54.4287,53.7632,57.0211,53.7632,63.0029Z" fill="#6d6e71"/>
</g>
</svg>

Illustrator created svg graphic not displaying/scaling properly in html

I have created this Instagram icon in Illustrator. I am trying to get it to display properly on an HTML page but it's not working properly. After exporting the svg image I copy the svg code generated by Illustrator into my HTML and it scales funny; cutting out some edges and making the strokes much thicker. It appears to be independent of parent element.
Scaling the svg using its height and width property or transform doesn't do anything and the viewBox dimensions match that of the image. Check out the screenshots.
Generated svg code:
<svg viewBox="0 0 22 22">
<g id="Shape">
<path class="cls-1" d="M16,22.2H6.41A6.21,6.21,0,0,1,.2,16V6.41A6.22,6.22,0,0,1,6.41.2H16a6.21,6.21,0,0,1,6.2,6.21V16A6.21,6.21,0,0,1,16,22.2ZM6.41,2.2A4.22,4.22,0,0,0,2.2,6.41V16a4.21,4.21,0,0,0,4.21,4.2H16A4.2,4.2,0,0,0,20.2,16V6.41A4.21,4.21,0,0,0,16,2.2Z"/>
<path class="cls-1" d="M11.2,17A5.78,5.78,0,1,1,17,11.2,5.79,5.79,0,0,1,11.2,17Zm0-9.56A3.78,3.78,0,1,0,15,11.2,3.79,3.79,0,0,0,11.2,7.42Z"/>
<circle class="cls-1" cx="17" cy="5.14" r="1.25"/>
</g>
</svg>
How it looks in the browser:

SVG background-image blurriness in Chrome with repeating background

An SVG background is appearing Blurry in Chrome and other Blink/webkit based browsers:
Screenshot of a portion of the SVG in Chrome:
Screenshot of a portion of the SVG in Firefox:
This only happens when displaying the SVG with "background-repeat: true" and "background-size: contain" CSS values. We'd like to repeat the SVG background height as many times as is necessary, since the page height is dynamic and stretching the vector image would look poor.
The SVG is displayed inline in the CSS in the sample page below, but the issue happens in the same way when I link to the external SVG image.
Here's a test page which shows this behavior:
https://august-13-2020-test-canvas.bubbleapps.io/version-test/pagemaker-test-original-2
(log in with "username" and "password", we're required to put this authentication here).
A test page with a properly displayed (crisp/smooth edged) SVG is here: https://august-13-2020-test-canvas.bubbleapps.io/version-test/pagemaker-test-online-1
A version with crisp/smooth edges is displayed in exactly the same way - the only difference is the content of the SVG.
Here's a link to the background SVG for the blurry page: https://dd7tel2830j4w.cloudfront.net/d44/f1588704991659x396570736162959360/background.svg
All the SVGs I tested from this page had crisp edges: https://www.svgbackgrounds.com/#flat-mountains (the bottom-right one is the one used in the above link)
In the process of trying to fix this issue or identify the cause of it within the SVG code, I've edited the SVG quite a bit, attempting the following:
Converting all SVG point values (path's d attributes) to integers
Adding "PreserveAspectRatio" to the SVG's opening tag
Removing the height and width from the opening declaration of the SVG
Removing the "linear gradients" from the SVG and replacing them with static colors
Doubling the size of the SVG shapes to see if the blurriness decreases with a larger initial width and height
Adding the "crispEdges" property to the SVG paths
Optimizing the SVG (using SVGomg)
Additionally, I've attempted to change the CSS a bit, but couldn't get it working.
Some ideas I have for workarounds are the following:
Using multiple background images to repeat the display of the SVG (display it 5-10 times in the background, mimicking the background-repeat: repeat-y effect but by including multiple background images)
Using JS to draw the SVG inline on the page (where this bug doesn't happen), creating an HTML that is exactly the same height as our group's dynamic height (which can change at any time without triggering a JS event) and repeating the SVG somehow within that group.
Asking a designer for a different SVG background, and hoping that the blurriness issue will not repeat.
Any help here would be much appreciated, I'm pulling my hair out on this and wasn't able to fix the issue after consulting several developers on CodeMentor.io.
Blink seems to apply a faulty algorithm, first rendering the SVG at a wrong size and then scaling the resulting raster image. This is tricky to work around, as two scaling mechanisms are involved, SVG viewBox and CSS background-size.
I can only offer a partial solution, working in Chrome and Edge (both engines), but failing in Firefox.
It moves the responsibility for scaling and repetition from the CSS background properties to the SVG itself with a <pattern> element. The complete content of the SVG image is moved inside this element, including setting the viewBox attribute to the same values.
Then, the width and height values for pattern repetition are set to width="100vw" height="504vw". This fills the viewport width and keeps the aspect ratio for the height. (Firefox seems not to be able to interpret vw units in this context).
Finally, a <rect> with width = height = 100% is defined and filled with the pattern, and the root <svg> element, without a viewBox attribute, is similarly set to width = height = 100%.
<svg width="100%" height="100%" fill="none" xmlns="http://www.w3.org/2000/svg">
<pattern id="pt" width="100vw" height="504vw" x="0" y="0" viewBox="0 0 1440 7258" patternUnits="userSpaceOnUse" preserveAspectRatio="xMinYMin meet">
<rect width="1440" height="7258" fill="white"/>
<path d="M-137 1749L1546 1994.95V2870L-137 2624.64V1749Z" fill="#F7F8FF"/>
<path d="M-137 3776L1546 4021.95V4897L-137 4651.64V3776Z" fill="url(#paint0_linear)"/>
<path d="M-137 3969L1546 4214.95V4900L-137 4654.64V3969Z" fill="url(#paint1_linear)"/>
<path d="M1319 2764L1545 2796.96V2870L1319 2837.12V2764Z" fill="#264CE9"/>
<path d="M-53 2645L96 2666.68V2744L-53 2722.37V2645Z" fill="#FBE89F"/>
<path d="M-29 2571L307 2620.13V2699L-29 2649.99V2571Z" fill="#54A5F2"/>
<path d="M1209 2820L1545 2869.13V2948L1209 2898.99V2820Z" fill="#6AD2F6"/>
<path d="M-147 4649L307 4715.42V4891L-147 4824.74V4649Z" fill="#6AD2F6"/>
<path d="M-137 -233L1546 12.9461V688L-137 442.638V-233Z" fill="url(#paint2_linear)"/>
<g style="mix-blend-mode:multiply">
<path d="M987 -144L2119 21.4151V388L987 222.978V-144Z" fill="#6AD2F6"/>
</g>
<path d="M-137 27L1546 272.946V948L-137 702.638V27Z" fill="url(#paint3_linear)"/>
<path d="M-258 455L490 564.509V794L-258 684.751V455Z" fill="url(#paint4_linear)"/>
</pattern>
<linearGradient id="paint0_linear" x1="43.9999" y1="3807" x2="458.5" y2="4665" gradientUnits="userSpaceOnUse">
<stop stop-color="#264CE9" stop-opacity="0.06"/>
<stop offset="1" stop-color="#F7F8FF" stop-opacity="0.26"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="43.9999" y1="4000" x2="1229" y2="5099" gradientUnits="userSpaceOnUse">
<stop stop-color="#264CE9" stop-opacity="0.06"/>
<stop offset="1" stop-color="#F7F8FF" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint2_linear" x1="194" y1="87.4999" x2="1671" y2="300" gradientUnits="userSpaceOnUse">
<stop offset="0.270833" stop-color="#264CE9"/>
<stop offset="1" stop-color="#6AD2F6"/>
</linearGradient>
<linearGradient id="paint3_linear" x1="194" y1="347.5" x2="1671" y2="560" gradientUnits="userSpaceOnUse">
<stop stop-color="#264CE9"/>
<stop offset="1" stop-color="#6AD2F6"/>
</linearGradient>
<linearGradient id="paint4_linear" x1="-108" y1="550.5" x2="490" y2="638" gradientUnits="userSpaceOnUse">
<stop stop-color="#264CE9" stop-opacity="0.43"/>
<stop offset="1" stop-color="#264CE9"/>
</linearGradient>
<rect width="100%" height="100%" fill="url(#pt)" />
</svg>
I have simplified the markup a bit, but these changes are all cosmetic, including the removal of the clipPath - it is applied for pattern elements, anyway.
Never found a solution to this issue (or at least failed to implement the solution presented by ccprog).
We chose to edit the SVG files to be longer. Our SVG files are being used as the background for web pages that have dynamic lengths, and theoretically have no limit in their height.
By repeating an SVG that is ~8000px tall 5 times, it covers up until a web page would reach 40000px height, which should be fine for our use case. I used inkscape to go in and copy the content of each SVG and then replicate that content several times, making the final SVGs 5x taller than the original ones.

Using many external svg clippaths in firefox

The problem
I'm trying to crop two images to some triangle shape via clippath, but when I try to move the inline svg code to an external file, only the fp clippath applies to the image. The image with the sp path disappears completely.
Please note that I'm using Firefox and therefore cannot use pure css and the clip-path: polygon() style.
The SVG code
<svg xmlns="http://www.w3.org/2000/svg" height="0" width="0">
<defs>
<clipPath id="fp">
<polygon points="0 0, 100 0, 0 100"/>
</clipPath>
<clippath id="sp">
<polygon points="100 0, 100 100, 0 100"/>
</clippath>
</defs>
</svg>
The working fiddle
This fiddle works because it's inline SVG. Try to move it to a separate file and refer to it in the css. It won't work.
https://jsfiddle.net/qkqovjmq/4/
I solved it by using the jQuery clip path plugin which renders all clip paths correctly.

Why is my image turned into negative using SVG mask

I've got a normal original image that is square or rectangular. What I want is to place an egg shaped oval over it to function as its mask.
It needs to be as crossbrowser compatible as it can be. Therefore I'm using this method below all other methods are less crossbrowser proof.
The problem
I'm getting a negative image. I tried using a white shape and a black shaped png. mask but with no luck. I tried to find a generator so i can upload an egg shaped svg but again with no succes.
<svg width="150" height="150" baseProfile="full" version="1.2">
<defs>
<mask id="svgmask2" maskUnits="userSpaceOnUse" maskContentUnits="userSpaceOnUse" transform="scale(1)">
<image width="150" height="150" xlink:href="/website_url/FullSizeRender-150x150.jpg" />
</mask>
</defs>
<image id="the-mask" mask="url(#svgmask2)" width="150" height="150" y="0" x="0" xlink:href="/website_url/img/clippath_mask.png" />
</svg>
Working (half working) example:
js Fiddle right here
My Masking Image
You're mixing up the mask and the image, so swap them.
Also the mask needs to be inverted i.e. you want a white oval on a black background.