I was wondering what is the best way to mask images in HTML 5 ?
In fact I would like to display circle thumbnails in a gallery without bothering my client with the preparation of the circular pictures...
So I have, in my opinion, two options : Canvas masking or old fashioned way
Do you have others ideas ? Best practices ?
Thanks
you could use
the old fashioned way - by using a transparent png on top of the desired element
the css3 border-radius of the image set to half of it's dimensions (so that the border defines a circle)
the css3 mask and mask-clip properties (here's a nice demo : http://www.webkit.org/blog/181/css-masks/)
canvas to do the masking
svg circles with the image as background-pattern
The choice depends on the targeted browsers and the time you want to invest.
For a fully cross-browser result, I recommend the old fashioned way, but if you want more shapes (maybe dynamic ones) or more than just image masking, you could try svg or canvas.
-circle {
-webkit-border-radius: 61px;
-moz-border-radius: 61px;
border-radius: 61px;
border:1px solid #aaaaaa;
width:122px;
height:122px;
}
see this
check this http://jsfiddle.net/WQSLa/1/
EDIT
u can also try this http://jsfiddle.net/jalbertbowdenii/WQSLa/3 as suggested by albert
Here's the method that works best for me:
create an SVG of the shape of mask you want.
edit the css of the appropriate element and specify the URL of the SVG for the mask
For a 200px circle, your SVG could look like this:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="image-mask" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="200px" height="200px" viewBox="0 0 200 200" enable-background="new 0 0 200 200" xml:space="preserve">
<circle cx="100" cy="100" r="100" stroke="black" stroke-width="0" fill="black" />
</svg>
And your CSS could look like this:
#image-mask {
width: 200px;
height: 200px;
mask: url('/static/images/avatarmask.svg');
-webkit-mask-image: url('/static/images/avatarmask.svg');
}
And if you want something more in-depth, I found this guide to be very helpful: http://collidercreative.com/how-to-create-css-image-masks-for-the-web-with-svgs/.
To update the answer, try clip-path (see this css-tricks post).
caniuse shows over 80% support now, if you use the -webkit- prefix as well. So this is working for me (IE/Edge, though, may be limiting factors):
clip-path: circle(125px at center);
-webkit-clip-path: circle(125px at center);
Related
I have an SVG icon I want to reuse, and would like to transform it first before doing so. Here is a simplified version of the issue I'm facing:
svg {
width: 100px;
height: 100px;
background: blue;
}
.circle {
fill: green;
transform: scale(3)
}
<svg viewBox="0 0 200 200">
<symbol id="circle" transform="scale(2)" class="circle">
<circle cx="50" cy="50" r="50" />
</symbol>
<use href="#circle"/>
</svg>
The green circle is properly sized in Firefox, whether I use inline styling or a class, but in Chrome, the fill attribute is applied, but not transform, class or inline, it remains small. A comparison screenshot:
Of course, I could work around it by applying transformations to each <use> element, but I'd like to understand why it doesn't work, because in the MDN docs, the <symbol> page lists transform as a legal attribute.
Perhaps the issue is that transform is not inherited, but it still works in Firefox, so maybe the problem lies elsewhere.
As Robert Longson pointed out in the comments, <symbol> elements supporting the transform property is a new SVG 2 feature that hasn't made its way to Chrome yet.
I have a <div> that has a background-color sitting in front of an image. I'm trying to apply a multiply effect using an SVG so that the background image behind the div comes through:
<svg>
<filter id="multiply">
<feBlend mode="multiply"/>
</filter>
</svg>
Unfortunately, only the solid background color is being changed, and I get no transparency through to the background.
Here's the fiddle: https://jsfiddle.net/0p58bxsp/1/
The effect I'm expecting is something like this:
I know the visual effect could be fudged using an rgba value as the background color, but I'm very specifically looking for the combination of a solid color having a multiply filter applied to it.
Is this a limitation of the current SVG implementation?
Here's the definition of a multiply blend:
Multiply blend mode multiplies the numbers for each pixel of the top layer with the corresponding pixel for the bottom layer. The result is a darker picture. , where a is the base layer value and b is the top layer value.
As such, using opacity or alpha doesn't give me the exact result that I'm looking for.
This was supposed to be possible if you stayed completely within SVG 1.1 by using the BackgroundImage pseudo input - but only IE10 ever supported it for inline SVG (Opera supported it for .svg files). Firefox, Chrome & Safari never supported it, and it's now formally declared "not to be implemented" by folks who work on those browsers.
You can import a copy of the background image using feImage and position it just right to match the actual background exactly. But depending on your design - that could take extensive javascript. And url() filters can behave strangely. https://jsfiddle.net/0p58bxsp/3/ shows how to do this - but it also surfaces a regression bug in Chrome with positioned primitives which will be fixed in next Chrome.
<div id="background">
<div id="effect">
Effect goes here
</div>
</div>
<svg width="100%" height="100%" viewBox="0 0 200 200">
<defs>
<filter id="multiply" x="0%"
y="0%" height="300%" width="300%">
<feImage x="0" width="400" height="400" y="0" preserveAspectRatio="xMaxYMax meet" xlink:href="http://lorempixel.com/400/400/" />
<feOffset dx="-100" dy="-100"/>
<feBlend mode="multiply" in="SourceGraphic"/>
</filter>
</defs>
</svg>
Safari 9(and only Safari 9) has a "backdrop-filter" that will do this, and you can also specify a mix-blend-mode which has broader support, but this is still pretty edge.
If you need a multiply blend, it might be best to just keep everything in SVG.
You should add opacity: 0.4; into effect class. It will work fine.
#effect {
color: #fff;
height: 200px;
margin: 100px 0 0 100px;
width: 200px;
opacity: 0.4;
background-color: #3d3934;
filter: url(#multiply);
-webkit-filter: url(#multiply);
-moz-filter: url(#multiply);
}
As far as I know, svg effects are limited to the elements itself. You can't use it to mix with another element.
You can however get this effect with standard CSS mix-blend-mode
#background {
background-image: url(http://lorempixel.com/400/400/);
height: 400px;
padding: 1px;
width: 400px;
}
#effect {
color: #fff;
height: 200px;
margin: 100px 0 0 100px;
width: 200px;
background-color: gray;
mix-blend-mode: multiply;
}
<div id="background">
<div id="effect">
Effect goes here
</div>
</div>
I'm having trouble with a svg pattern background that is not repeating on the x-axis in IE11 (and probably other IEs) and the Android native browser.
Apparently I should add preserveAspectRatio: "none slice" to the svg element, but what if the svg is used as background-image?
CSS
header.logoheader:after {
background-image: url('patroon5.svg');
background-size: auto 100%;
background-repeat: repeat-x;
content: "";
display: block;
height: 100px;
left: 0;
position: absolute;
top: 40px;
width: 100%;
}
(I'm using the :after selector so the transparent pattern covers the div)
In my HTML there is no svg element to add the preserveAspectRatio to. I'm thinking this is because of the :after selector.
Anyone got an solution?
You can either edit the background image svg file to include it or alternatively use an SVG fragment identifier i.e.
background-image: url('patroon5.svg#svgView(preserveAspectRatio(none))');
Had this kind of problem before on IE. To fix it you have to edit your svg file then remove the set width and height assuming you have viewBox set in there. Then add preserveAspectRatio="xMinYMid" as an attribute.
e.g.
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
preserveAspectRatio="xMinYMid" viewBox="0 0 1024 1024" enable-background="new 0 0 1024 1024" xml:space="preserve">
This code does not work in IE, I need to use it because I have to make an arrow that follows a point on the map.
div {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
right: 0px;
background: red;
clip-path: url(#cliparrow);
-webkit-clip-path: polygon(777px 285px, 0px 303px, 777px 315px);
}
svg {
width: 0;
height: 0;
float: left;
position: absolute;
}
<div></div>
<svg height="0" width="0">
<defs>
<clipPath id="cliparrow">
<polygon points="777,285 0,303 777,315" ></polygon>
</clipPath>
</defs>
</svg>
Any suggestions? Thanks.
Internet Explorer is not (currently) compatible with using clip-path via CSS on HTML elements (see can-i-use). clip-path is currently only a candidate recommendation for HTML and not yet in the spec (http://www.w3.org/TR/css-masking-1/).
You may, however, use clip-path as an SVG attribute on another SVG element (for example, if you load the MDN page on clipping and masking in SVG, it will work in IE).
If all you need to do is embed a colored shape, and not transform HTML content per se (e.g. apply clipping against HTML text, multiple elements, etc), you could even more simply just use an appropriately shaped SVG element (directly embedded in an otherwise transparent div if needed) instead of trying to clip an HTML element. This also removes the need for the browser specific webkit prefix.
<div>
<svg width="700px" height="700px" xmlns="http://www.w3.org/2000/svg">
<polygon id="arrow" points="777,285 0,303 777,315" ></polygon>
</svg>
</div>
example fiddle (with some extra helpers): http://jsfiddle.net/taswyn/cv6m76m7/
(You'll obviously need to set height and width appropriately, this was just a quick example using your shape. Note the use of SVG CSS to apply the color on the arrow, which this method allows)
Tested in IE 10 using IE 9 and 10 browser modes (and tested in Chrome). Probably won't work in 8 and below.
If you do need to clip against text, you'll need to use SVG text instead of HTML text elements.
Aside: If all you need to do is clip in a rectangle, you could temporarily use clip CSS, which is cross-browser compatible but deprecated, until the masking module hits recommendation status and clip-path becomes available for use on HTML as a W3C standard. (obviously this doesn't apply to your situation, but it may help someone else)
Say I have the following code:
<span>Hello world!</span>
And the following CSS:
span{
color:red;
}
Is there any way I can change the red to an image? Like url(images/text-bg.png);? I want to put a texture on my text and decided that I would just make the text "color" an image, but I'm not sure if this can be done with CSS.
it is possible, take a look at this pen here
https://codepen.io/feferonka/pen/eoWLZp
Use this on parent of text:
background-image: url(url);
background-clip: text;
-webkit-background-clip: text;
color: transparent;
Yes it's possible using svg , you can embed <svg> over one <div> and background image over another <div>, later apply z-index to <div>. You can use Vector applications like illustrator to create the svg the way you want.
<html>
<head>
<title>Untitled Document</title>
<style>
html
{
background-image:url('lauch.jpg');
background-repeat:no-repeat;
background-position:center;
padding-top:200px;
}
</style>
</head>
<body>
<div align="center">
<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="140px" height="80px" viewBox="0 0 76.25 39.167" enable-background="new 0 0 76.25 39.167" xml:space="preserve">
<text transform="matrix(1 0 0 1 5.9336 30.417)" fill="none" stroke="red" stroke-width="0.25" stroke-miterlimit="10" font-family="'Tahoma'" font-size="36">Text</text>
</div>
</body>
</html>
This works perfectly fine for me
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-image: url(your-image.jpg);
This is not possible, not even with CSS3. Here's an interesting article on text effects you can use with CSS3.
http://www.catswhocode.com/blog/8-examples-of-stunning-css3-text-effects
Another option is to use a custom font which suites your needs.
This site has an amazing amount of free open-source fonts in every format needed to support all browsers, it even gives you a nice demo file to demonstrate how to implement it in CSS. This is compatible with CSS2.1 as well, making it IE7+ compatible.
http://www.fontsquirrel.com/
The technique of swapping out text for images is common for headers and page navigation, but there really aren't any pure CSS techniques that are cross-browser compatible (this is a nice technique, but isn't something you should rely on).
If you have a finite amount of text that you want to apply the texture to, your best bet is to just replace the text with images manually, as such:
HTML:
<h1 class="title">Title</h1>
CSS:
h1.title {
background: url(images/title.gif) 0 0 no-repeat;
width: 80px;
height: 23px;
text-indent: -10000px; }