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 am trying to make .main-div like this image
.main-div {
width: 100px;
height: 100px;
background-color: Red;
border-radius: 30px/20px;
}
<div class="main-div"></div>
My JSFiddle is here.
You can do a trick using a pseudo element and achieve that shape
body {
background: lightgray;
}
.main-div {
position: relative;
display: inline-block;
width: 110px;
height: 100px;
background-color: red;
border-radius: 30%/50%;
background: url(https://i.stack.imgur.com/CWoXa.png) center center no-repeat;
background-size: 110px 110px;
}
.main-div::after {
content: '';
position: absolute;
left: 5px;
top: -5px;
width: 100px;
height: 110px;
background: inherit;
background-size: inherit;
border-radius: 50%/30%;
}
.main-div+.main-div {
background: gray;
}
<div class="main-div"></div>
<div class="main-div"></div>
As Justinas remarked in their answer, the border of your example image does not look like it can be recreated with border-radius alone. This is because the outline is not an ellipse.
It is possible to do this, with good browser support, using SVG as follows.
/* set size of and center SVG */
svg {
display: block;
width: 200px;
height: 200px;
margin: 0 auto;
}
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<clipPath id="outline">
<!-- use Bezier curves to define outline -->
<path d="M 0 100
C 0 0, 40 0, 100 0
C 160 0, 200 0, 200 100
C 200 200, 160 200, 100 200
C 40 200, 0 200, 0 100
Z" />
</clipPath>
</defs>
<image x="0" y="0" width="200" height="200"
xlink:href="https://placehold.it/200"
clip-path="url(#outline)" />
</svg>
This uses clipping in SVG with the clipPath element. You can define any path to use for the clipping. I have used four Bezier curves here. You can tweak where the control points are, or change this to use something entirely different if you wish.
An extra bonus of this approach is that it is now easy to apply other (advanced) filters, for example blurring the image or applying a drop shadow.
/* set size of and center SVG */
svg {
display: block;
width: 204px;
height: 204px;
margin: 0 auto;
}
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<clipPath id="outline">
<!-- use Bezier curves to define outline -->
<path d="M 0 100
C 0 0, 40 0, 100 0
C 160 0, 200 0, 200 100
C 200 200, 160 200, 100 200
C 40 200, 0 200, 0 100
Z" />
</clipPath>
<filter id="dropshadow" x="-30%" y="-30%"
width="160%" height="160%"
color-interpolation-filters="sRGB">
<!-- define color of shadow here -->
<feComponentTransfer in="SourceAlpha">
<feFuncR type="linear" slope="0"
intercept="0.518"></feFuncR>
<feFuncG type="linear" slope="0"
intercept="0.698"></feFuncG>
<feFuncB type="linear" slope="0"
intercept="0.867"></feFuncB>
</feComponentTransfer>
<!-- define blur of shadow here -->
<feGaussianBlur stdDeviation="2" />
<!-- we can offset the shadow -->
<feOffset result="shadow" dx="1" dy="1" />
<!-- put shadow below original content -->
<feBlend in="SourceGraphic"
in2="shadow" mode="normal" />
</filter>
</defs>
<g transform="translate(2, 2)"
filter="url(#dropshadow)">
<image x="0" y="0" width="200" height="200"
xlink:href="https://placehold.it/200"
clip-path="url(#outline)" />
</g>
</svg>
Your image radius does not look like standard CSS border radius. If yes, than you need to use image preprocessing (in back-end side, e.g. GD or stand-alone tool like Photoshop) or use Clipping Mask with limited support. Using border radius you can have similar effect.
.main-div {
width: 100px;
height: 100px;
background-color: red;
border-radius: 40%;
overflow: hidden;
position: relative;
}
.main-div img {
width: 100%;
position: absolute;
left: -50px;
top: -50px;
margin-top: 50%;
margin-left: 50%;
}
<div class="main-div">
<img src="http://lorempixel.com/200/200/"/>
</div>
Add this style. You can change border-radius as per your requirements:
div {
border: 2px solid #a1a1a1;
padding: 10px 15px; `enter code here`
background: #dddddd;
width: 100px;
border-radius: 55px;
}
.element {
border-radius: 50px;
overflow: hidden;
}
<img src="https://image.ibb.co/irvmO5/html5.png" alt="html5" border="0" class="element"><br /><a target='_blank' href='https://imgbb.com/'>Rounded rectangle clip mask</a>