Is it possible to have multiple masks with clip-path? - css

Hi,
I wonder whether it's possible to use more than one mask on the same element, just like this:
clip-path:polygon(8% 0%, 8% 7%, 14% 12%), polygon(96.4%, 92% 96.4%, 97% 92.3%), polygon(97% 15%, 99% 13%, 99% 0%);
With this I would be able to show only certain areas of the element that are separated from each other.
Thank you.

This is possible if you use clip-path with an SVG-defined <clipPath>
.clip-svg {
clip-path: url(#myClip);
}
<img class="clip-svg" src="https://picsum.photos/id/1015/600/400">
<svg width="0" height="0">
<defs>
<clipPath id="myClip">
<polygon points="400,50 400,320, 140,300"/>
<polygon points="450,10 500,200 600,100" />
<polygon points="150,10 100,200 300,100" />
</clipPath>
</defs>
</svg>
Confirmed working in Chrome 60, Firefox 55, Edge 85. Unfortunately doesn't work in IE.
Full browser support information here.

You can also use CSS to make one polygon which goes in and out of element bounds . See:
https://24ways.org/2018/clip-paths-know-no-bounds/
https://codepen.io/danwilson/pen/zMgrgb
div {
width: 80vmin;
height: 80vmin;
background: hsl(181, 90%, 52%);
clip-path: polygon(30px 20px, 40px 200px, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
}
<div></div>

You can use multiple mask. But you can't use multiple clip-path. You can use multiple masks with clip-path.
you can use mask property with clip-path to make multiple masks.
like this example.
#parent {
display: flex;
justify-content: center;
align-items :center;
height: 100vh;
width: 100vh;
background: linear-gradient(90deg, black 50%, yellow 50%);
}
.multiple_mask{
height: 200px;
width: 200px;
background: red;
clip-path: polygon(0% 0%, 50% 0%, 100% 50%, 50% 100%, 0% 100%, 50% 50%);
-webkit-mask-image: linear-gradient(45deg, black 50%, transparent 50%), linear-gradient(180deg, black, transparent);
mask-image: linear-gradient(45deg, black 50%, transparent 70%);
}
<div id="parent">
<div class="multiple_mask"></div>
</div>
Hope you understand

To use clip path for multiple clips you need to think of it like an etch-a-sketch. You have to complete the object and follow that line to the next object. Then come back to the previous object before moving to the next one.
img {
clip-path: polygon(14% 12%, 8% 0%, 8% 7%, 14% 12%, 87% 96.4%, 92% 96.4%, 97% 92.3%, 87% 96.4%, 14% 12%, 97% 15%, 99% 13%, 99% 0, 97% 15%, 14% 12% );
}
<img class="clip-svg" src="https://picsum.photos/id/1015/600/400"/>

Related

How to emulate styled HTML meter with two linear-gradient backgrounds, while avoiding the gradients horizontally compressing?

It seems to be damn-near impossible to style a <meter> HTML element to any interesting degree, so I am emulating a meter using CSS.
I have a step-wise gray linear gradient I want to use for the "unfilled" right-hand portion of the meter
background-image: linear-gradient(
to right,
#ddd 20%,
#ccc 20%,
#ccc 40%,
#bbb 40%,
#bbb 60%,
#aaa 60%,
#aaa 80%,
#999 80%,
#999 100%
);
and a step-wise green-ish gradient I want to use for the "filled" left-hand portion of the meter.
background-image: linear-gradient(
to right,
#70f600 20%,
#0e0 20%,
#0e0 40%,
#0d0 40%,
#0d0 60%,
#0c0 60%,
#0c0 80%,
#0b0 80%,
#0b0 100%
);
The effect I want is that
at 0% full meter, the styled meter will be the gray step gradient alone;
at 100% full meter, the styled meter will be the green step gradient alone;
at some intermediate percent (0% < X < 100%) full meter, the leftmost X% of the styled meter will be the leftmost X% of the green step gradient, and the remaining rightmost space of the styled meter will be the corresponding rightmost space of the gray step gradient. For example:
at ~36% fill
at ~82% fill
crucially, neither step gradient should be horizontally compressed to fit into the available space.
This last bulletpoint is what I am struggling to achieve.
My current best effort is the following HTML and CSS (to produce, in this case, a 36% filled meter):
HTML
<div class="meter-gauge">
<div class="negative-space" style="width: calc(100% - 36%)"/>
</div>
CSS
.meter-gauge {
position: relative;
display: inline-block;
height: 1em;
min-width: 10em;
background-image: linear-gradient(
to right,
#70f600 20%,
#0e0 20%,
#0e0 40%,
#0d0 40%,
#0d0 60%,
#0c0 60%,
#0c0 80%,
#0b0 80%,
#0b0 100%
);
}
.negative-space {
position: absolute;
top: 0;
right: 0;
height: inherit;
width: 0; /* Overridden by style attribute */
background-image: linear-gradient(
to right,
#ddd 20%,
#ccc 20%,
#ccc 40%,
#bbb 40%,
#bbb 60%,
#aaa 60%,
#aaa 80%,
#999 80%,
#999 100%
);
z-index: 1;
}
Here, unlike the desired meter styling, displayed earlier, we get a version where the gray step gradient is horizontally compressed to fit 100% of the gradient into 64% of the space.
For comparison, an 82% filled meter with the above CSS looks like this, where the issue is even more obvious:
How can I achieve the look I want, and avoid one of the two gradients being included in its entirety but horizontally squashed into the available space?
I have noted that the effect I want would have been possible to achieve if the two gradients were instead two image files, as demonstrated by this image comparison slider demo. This seems to be because the image files are defined with absolute widths, and are then scaled as necessary. The gradients on the other hand are defined only using percentages, which relate only to the width of the containing block, not that block's parent block width.
Note: I don't want to use absolute CSS size units, as I want to be able to plug this styled meter in anywhere, at any size.
How about using clip-path?
Example code
.gauge {
width: 30em;
height: 2em;
position: relative;
background-color: #ccc;
}
.gauge > * {
width: 100%;
height: 100%;
position: absolute;
}
.meter-gauge {
background-image: linear-gradient(to right,
#70f600 20%,
#0e0 20%,
#0e0 40%,
#0d0 40%,
#0d0 60%,
#0c0 60%,
#0c0 80%,
#0b0 80%,
#0b0 100%);
}
.negative-space {
background-image: linear-gradient(to right,
#ddd 20%,
#ccc 20%,
#ccc 40%,
#bbb 40%,
#bbb 60%,
#aaa 60%,
#aaa 80%,
#999 80%,
#999 100%);
clip-path: inset(0 0 0 30%);
}
<div class="gauge">
<div class="meter-gauge"></div>
<div class="negative-space"></div>
</div>
How it works
clip-path: inset(top right bottom left)
Just have a couple of elements, or pseudo elements, with the green on top of the gray.
Green one has clip-path:
clip-path: polygon(0 0, var(—pc) 0, var(—pc) 100%, 0 100%);
Where —pc is percentage required e.g 36%
Sorry I can’t give a proper snippet as am stuck on an iOS device.

How to create a flag using linear-gradient?

div{
height: 500px;
width: 900px;
background-image: linear-gradient(to bottom right,green 33% 66%,yellow 66% 100%,black 111% 222%,yellow 0% 5%,blue 0% 10%);
}
<div></div>
here's how its supposed to be:
Do it with multiple background and it will be easier to handle:
.box {
width:300px;
height:200px;
background:
linear-gradient(to bottom right,#21b539 calc(50% - 40px),#f5cf22 0 calc(50% - 30px),#0000 0),
linear-gradient(to top left ,#00a6e0 calc(50% - 40px),#f5cf22 0 calc(50% - 30px),#0000 0)
#000
}
<div class="box">
</div>
try this background: linear-gradient( to bottom right, green 33% 40%, yellow 40% 45%, black 45% 55%, yellow 55% 60%, blue 60% 100% );
Also add a height and width to your div
You have to do something like this:
background-image: linear-gradient(to bottom right,green 35%,yellow 35% 40%, black 40% 60%, yellow 60% 65%, dodgerblue 65%);
Remember the gradient is in the direction top left to bottom right. And a percentage more than 100 don't make any sense.
div {
width: 900px;
height: 500px;
background-image: linear-gradient(to bottom right,green 35%,yellow 35% 40%, black 40% 60%, yellow 60% 65%, dodgerblue 65%);
}
<div>
</div>

Rounded image shape using clip-path

I want to have css clip-path like the below image
can someone help me
img {
clip-path: polygon(53% 0%, 100% 1%, 100% 50%, 100% 100%, 55% 100%, 42% 65%, 0% 52%, 44% 36%);
border-radius:0 100% 100% 0
}
<img src="http://lorempixel.com/400/400/">
mask can easily do this. It would be tricky to have curve with clip-path
img {
width:50%;
border-radius:50%;
-webkit-mask:
radial-gradient(circle at top left,transparent 45%,#fff 45.5%) top,
radial-gradient(circle at bottom left,transparent 45%,#fff 45.5%) bottom;
-webkit-mask-size:100% 50%;
-webkit-mask-repeat:no-repeat;
}
<img src="https://picsum.photos/id/1012/800/800">
Another syntax:
img {
width:50%;
border-radius:50%;
-webkit-mask:
radial-gradient(51% 51% at 0 0 ,transparent 99%,#fff),
radial-gradient(51% 51% at 0 100%,transparent 99%,#fff);
-webkit-mask-composite: destination-in;
mask-composite:intersect;
}
<img src="https://picsum.photos/id/1012/800/800">

How to create an irregular square shape in css?

Looking for the code to make this particular shape with CSS..
Any help much appreciated!
You can do it with some rotation and perspective:
.box {
width: 150px;
height: 120px;
background: #f540a8;
margin: 20px;
transform: perspective(180px) rotateX(15deg) rotateY(20deg) rotateZ(-3deg);
}
<div class="box">
</div>
Or using SVG:
<svg viewBox="0 0 200 200" width=200>
<polygon points="20,0 150,20 170,130 0,150" fill="#f540a8" />
</svg>
And also using gradient (but without transparency):
.box {
width: 150px;
height: 120px;
background:
linear-gradient(to top right, transparent 46%,#fff 50%) right/10px 100%,
linear-gradient(to top right, transparent 46%,#fff 50%) top/100% 10px,
linear-gradient(to bottom right, transparent 46%,#fff 50%) bottom/100% 10px,
linear-gradient(to top left, transparent 46%,#fff 50%) left/10px 100%,
#f540a8;
background-repeat:no-repeat;
margin: 20px;
}
<div class="box">
</div>
You can use clip-path.
The clip-path CSS property creates a clipping region that defines
what part of an element should be displayed. More specifically, those
portions that are inside the region are shown, while those outside are
hidden.
Try this code snippet.
div{
width: 150px;
height: 150px;
-webkit-clip-path: polygon(5% 7%, 91% 14%, 98% 91%, 0% 100%);
clip-path: polygon(5% 7%, 91% 14%, 98% 91%, 0% 100%);
background: pink;
}
<div></div>
you can use:
clip-path: polygon(30px 0 , 250px 0, 200px 300px, 0 0);
Please see the example here: https://codepen.io/shakogele/pen/ZMZGGK

css clip path Shape is not working on ie or how can i create this with css

I want to clip an image according to a shape, like the image below.
But my code is not working in IE.
How can I get it to work in IE?
.svg-image {
background: url(http://r-ce.com/wp-content/uploads/2016/01/Driving-Classes-Deal1-1.jpg);
width: 320px;
height: 320px;
}
.svg-image {
-webkit-clip-path: polygon(50% 0%, 100% 0, 100% 35%, 100% 85%, 70% 92%, 51% 81%, 31% 90%, 0 87%, 0% 35%, 0 0);
clip-path: polygon(50% 0%, 100% 0, 100% 35%, 100% 85%, 70% 92%, 51% 81%, 31% 90%, 0 87%, 0% 35%, 0 0);
}
<div class="svg-image"><div>
View on CodePen
This is not supported in IE. See this link to CanIUse http://caniuse.com/#feat=css-clip-path .
Also, this thread while a few years old does provide a possible solution using SVG. clip-path svg polygon Internet explorer
One more thing, if you're into photo shop or gimp you can just cut that part of the image and make it a png with a transparent background. Then you won't have to worry about doing it in the browser. It is a pretty sweet effect though.

Resources