I'm trying to make arc shape of pseudo-element of the parent div, I'm trying to achieve this look by using clip-path, this is simplified example of the look that I'm after:
I'm kinda limited in what I can change in the current markup, background color is dynamic and that's why I need to inherit it in pseudo element and also there is background image in that whole container. That's why I'm trying to do this with pseudo-elements and clip-path. This is what I tried:
div {
position: relative;
background: rgba(0,0,0,0.5);
height: 100px;
width: 100px;
margin: 100px auto;
}
div:before {
content: '';
position: absolute;
z-index: 2;
height: 50px;
width: 50px;
right: -50px;
bottom: 0;
background: inherit;
clip-path: polygon(0 100%, 0 0, 3% 15%, 6% 27%, 11% 34%, 19% 43%, 26% 53%, 35% 63%, 46% 71%, 54% 77%, 65% 83%, 70% 86%, 81% 91%, 91% 95%, 100% 100%);
}
<div></div>
But as you can see it's far from perfect, you can see the points and it doesn't have that smooth arc look. I'm using SCSS, also I'm open to any JS suggestions.
This is a job for mask:
div {
position: relative;
background: rgba(0,0,0,0.5);
height: 100px;
width: 100px;
margin: 100px auto;
}
div:before {
content: '';
position: absolute;
z-index: 2;
height: 50px;
width: 50px;
left:100%;
bottom: 0;
background: inherit;
-webkit-mask:radial-gradient(farthest-side at top right,transparent 99%,#fff 100%);
mask:radial-gradient(farthest-side at top right,transparent 99%,#fff 100%);
}
<div></div>
Related
I am currently making an animation that will apply a gradient mask on an image. The mask is a transparent mask and it will transform from right to left of the image. Here is my code.
<!DOCTYPE html>
<html>
<head>
<style>
.container {
height: 100vh;
width: 100vw;
background-color: white;
position: relative;
}
.first {
background-image: url('https://i.ibb.co/17zzm7P/flower.jpg');
background-size:cover;
position: absolute;
height: 100%;
width: 100%;
-webkit-mask-image: linear-gradient(to left, transparent 0px, black 20rem, black);
-webkit-animation: rightToLeft 5s forwards;
}
#keyframes rightToLeft {
0% {
-webkit-mask-position: 100vw 0%;
mask-position: 100vw 0%;
}
100% {
-webkit-mask-position: 0vw 0vw;
mask-position: 0vw 0vw;
}
}
</style>
</head>
<body>
<div class="container">
<div id="first" class="first"> </div>
</div>
</body>
</html>
Basically, the animation works well. However, the mask image is only applied to a specific area when it moves from right to left. Because the mask is transparent, I expect when it moves to the new area, the previous area it passed through is also transparent. How can I do to make the previous area transparent too?
Thank you so much for your time.
You are almost good, you only need to disable the repetition by using mask-repeat: no-repeat
.container {
height: 100vh;
background-color: white;
position: relative;
}
.first {
background-image: url('https://i.ibb.co/17zzm7P/flower.jpg');
background-size: cover;
position: absolute;
height: 100%;
width: 100%;
-webkit-mask-image: linear-gradient(to left, transparent, black 20rem);
-webkit-mask-repeat: no-repeat;
-webkit-animation: rightToLeft 5s forwards;
}
#keyframes rightToLeft {
0% {
-webkit-mask-position: 100vw 0%;
mask-position: 100vw 0%;
}
100% {
-webkit-mask-position: 0vw 0vw;
mask-position: 0vw 0vw;
}
}
body {
margin:0;
}
<div class="container">
<div id="first" class="first"> </div>
</div>
as seen in my codepen, there are two greyscaled shapes. Now its only possible to hover one of both, because the original size is a box and overlaps both images.
But is there a way to like recognize the shape when hovering it? Z-index does not lead to a result...
Hope you can help me out a bit!
would be great without JS but its not a k.o.
html:
<div id="one">
<img src="https://cdn.pixabay.com/photo/2019/01/19/15/53/ice-
3941906_1280.jpg">
</div>
<div id="two">
<img src="https://cdn.pixabay.com/photo/2016/04/20/17/02/tuscany-
1341536_1280.jpg">
</div>
css:
img{
width: 700px;
height: 400px;
object-fit: cover;
}
#one img{
-webkit-clip-path: polygon(0 0, 0% 100%, 100% 0);
clip-path: polygon(0 0, 0% 100%, 100% 0);
}
#two img{
-webkit-clip-path: polygon(100% 100%, 0% 100%, 100% 0);
clip-path: polygon(100% 100%, 0% 100%, 100% 0);
}
#one{
position: absolute;
z-index: 0;
top: 0 ;
left: 0;
}
#two{
position:absolute;
top: 0px;
left: 0;
z-index: 0;
}
#one,
#two{
filter:grayscale(100%);
}
#one:hover,
#two:hover{
filter:grayscale(0%);
}
https://codepen.io/robwe30/pen/eXBvzp?editors=1100
Cheers
For that simple shape, You may play with pointer-events to remove it and a pseudo element rotated to switch it back on only on one part of the image.
about pointer-events https://css-tricks.com/almanac/properties/p/pointer-events/
example
/* CSS switch of pointer-events on/off */
#two {
position: relative;
overflow: hidden;/* hide pseudo overflowing */
pointer-events: none;
}
#two:before {
pointer-events: auto;
content: '';
position: absolute;
top: 100%;
left: 0;
z-index: 2;
width: 150%;
height: 100%;
/* set transform according to ratio image */
transform-origin: top left;
transform: rotate(-30deg);
/* if you want to see where it stands , add borders or background */
}
/* end CSS switch */
img {
width: 700px;
height: 400px;
object-fit: cover;
display: block;/* avoids gap underneath */
}
#one img {
-webkit-clip-path: polygon(0 0, 0% 100%, 100% 0);
clip-path: polygon(0 0, 0% 100%, 100% 0);
}
#two img {
-webkit-clip-path: polygon(100% 100%, 0% 100%, 100% 0);
clip-path: polygon(100% 100%, 0% 100%, 100% 0);
}
#one {
position: absolute;
z-index: 0;
top: 0;
left: 0;
}
#two {
position: absolute;
top: 0px;
left: 0;
z-index: 0;
}
#one,
#two {
filter: sepia(100%);/* demo purpose */
}
#one:hover,
#two:hover {
filter: grayscale(0%);
}
<div id="one">
<img src="https://picsum.photos/800/600?image=1060">
</div>
<div id="two">
<img src="https://picsum.photos/800/600?image=1065">
</div>
https://codepen.io/gc-nomade/pen/aMBwYz
Here is another idea to create the same using less of code and without clip-path
.container {
width: 300px;
height: 200px;
position: relative;
overflow: hidden;
}
.container img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.container div {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform: skewX(-56.3deg); /* tan(angle) = Width/height --> angle = arctan(width/height) */
transform-origin: top;
overflow: hidden;
}
.container div img {
transform: skewX(56.3deg);
transform-origin: top;
}
.container img:hover{
filter:grayscale(100%);
}
<div class="container">
<img src="https://picsum.photos/800/600?image=1069">
<div>
<img src="https://picsum.photos/800/600?image=1051">
</div>
</div>
.clients-img::after {
content: '';
position: relative;
background-image: url('https://i.stack.imgur.com/Y2vyB.png');
background-repeat: no-repeat;
float: left;
margin-left: 15px;
transition: all 1.8s ease;
width: 135px;
height: 135px;
}
.clients-slider-inside img {
border-radius: 50%;
position: absolute;
padding: 14px;
left: 0px;
top: 0px;
width: 135px;
height: 135px;
}
.clients-img:hover::after {
transform: rotate(360deg) translate(0px);
}
<div class="clients-slider-inside">
<div class="clients-img"> <img src="https://i.stack.imgur.com/tz2aw.png" alt="clients img"> </div>
</div>
On Mouse hover rotate 360 degree and On Mouse out no any effect.
This type gradient border. So can you please help me for perfect rotation in circle.
You can avoid using an image and recreate the gradient using multiple linear-gradient on the background of the container. Then the idea is to rotate the whole container and rotate the image in the opposite direction so you create the effect of background rotation.
.clients-img {
display: inline-block;
position: relative;
border-radius: 50%;
background: linear-gradient(to right, #fff 50%, transparent 50%), linear-gradient(-15deg,#6fda44 25%, #fff 80%);
transition:1s all;
}
.clients-img img {
border-radius: 50%;
width: 135px;
height: 135px;
padding: 15px;
vertical-align: top;
transition:1s all;
}
.clients-img:hover {
transform: rotate(360deg);
}
.clients-img:hover img{
transform: rotate(-360deg);
}
<div class="clients-img"> <img src="https://i.stack.imgur.com/tz2aw.png" alt="clients img"> </div>
Attached you'll find an image explaining what i'd like to accomplish.
I would like to have my background set, over that I would like to have a border that's a bit offset from the background. In some way I need to find a way to animate every single side of the border by it's own.
I would like the top border to animate in from the right, the bottom one from the left. The left one from the bottom and the right one from the top.
This is giving me a big headache. Anybody have any ideas?
What I've done is:
<div id="#mainsection"></div>
The border is created in CSS:
#mainsection:after {
content: '';
position: absolute;
top: 40px;
right: 40px;
bottom: 40px;
left: 40px;
border: 4px solid #96896C;
}
What I've realised is that this is not going to work as I need every border-part as separate items.
You could perhaps use linear gradients and a couple of ::before and ::after pseudo elements. This wont give you entirely separate animations but the horizontal and vertical borders can be animated separately.
body, html {
height: 100%;
}
#mainsection {
height: 100%;
position: relative;
background: url(https://placehold.it/1000x1000) center center;
}
#mainsection:after {
content: '';
position: absolute;
top: 40px;
right: 40px;
bottom: 40px;
left: 40px;
background-image: linear-gradient(black, black), linear-gradient(transparent, transparent), linear-gradient(black, black);
background-repeat: no-repeat;
background-size: 2px 0%, calc(100% - 4px) 100%, 2px 0%;
background-position: left bottom, 0 0, right top;
transition: background-size 1.5s ease;
}
#mainsection:before {
content: '';
position: absolute;
top: 40px;
right: 40px;
bottom: 40px;
left: 40px;
background-image: linear-gradient(black, black), linear-gradient(transparent, transparent), linear-gradient(black, black);
background-repeat: no-repeat;
background-size: 0% 2px, calc(100% - 4px) 100%, 0% 2px;
background-position: left bottom, 0 0, right top;
transition: background-size 2s ease .5s; /* .5s delay */
}
#mainsection:hover:after {
background-size: 2px 100%, calc(100% - 4px) 100%, 2px 100%;
}
#mainsection:hover:before {
background-size: 100% 2px, calc(100% - 4px) 100%, 100% 2px;
}
<div id="mainsection"></div>
A similar solution to #Turnip but by simply using multiple gradient on the same div. And you can control the animation of each one by playing with initial and final values of background-size and background-position:
body {
margin:0;
}
.container {
height: 100vh;
padding:40px;
background:
linear-gradient(#000,#000) top right content-box,
linear-gradient(#000,#000) top right content-box,
linear-gradient(#000,#000) bottom left content-box,
linear-gradient(#000,#000) bottom left content-box,
url(https://placehold.it/1000x1000) center center;
background-size:0 3px,3px 0,0 3px,3px 0,auto;
background-repeat:no-repeat;
transition:2s;
box-sizing:border-box;
}
.container:hover {
background-size:
100% 3px,
3px 100%,
100% 3px,
3px 100%,
auto; /* This is for image */
}
<div class="container"></div>
Then simply adjust the position to control the animation:
body{
margin:0;
}
.container {
height: 100vh;
padding:40px;
background:
linear-gradient(#000,#000) top left content-box,
linear-gradient(#000,#000) top right content-box,
linear-gradient(#000,#000) bottom right content-box,
linear-gradient(#000,#000) bottom left content-box,
url(https://placehold.it/1000x1000) center center;
background-size:0 3px,3px 0,0 3px,3px 0,auto;
background-repeat:no-repeat;
transition:2s;
box-sizing:border-box;
}
.container:hover {
background-size:
100% 3px,
3px 100%,
100% 3px,
3px 100%,
auto; /* This is for image */
}
<div class="container"></div>
Another one:
body {
margin:0
}
.container {
height: 100vh;
padding:40px;
background:
linear-gradient(#000,#000) top content-box,
linear-gradient(#000,#000) right content-box,
linear-gradient(#000,#000) bottom content-box,
linear-gradient(#000,#000) left content-box,
url(https://placehold.it/1000x1000) center center;
background-size:0 3px,3px 0,0 3px,3px 0,auto;
background-repeat:no-repeat;
transition:2s;
box-sizing:border-box;
}
.container:hover {
background-size:
100% 3px,
3px 100%,
100% 3px,
3px 100%,
auto; /* This is for image */
}
<div class="container"></div>
Overview
I have a #container element which houses a centered element .center.
This web-app will be fullscreen on a number of monitors of various width and height; some portrait and some landscape.
The .center element is significantly smaller than its parent #container, and on larger screens, it sits in the middle with lots of space between the wrapper and the edges, both horizontally and vertically.
Issue
I am trying to figure out a way to expand the .center so that it scales (all its contents scaling equally, including images and font size) until either:
its width is equal to the width of #container, or
its height is equal to the height of #container
I am aware of the CSS3 transform: scale() functions, however as the height and width of the #container is unknown and variable, I don't know how to scale all elements dynamically.
How can this be achieved?
Code
#container {
position: absolute;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background: rgb(37, 66, 141);
background: -moz-radial-gradient(center, ellipse cover, rgba(37, 66, 141, 1) 0%, rgba(0, 0, 0, 1) 54%);
background: -webkit-radial-gradient(center, ellipse cover, rgba(37, 66, 141, 1) 0%, rgba(0, 0, 0, 1) 54%);
background: radial-gradient(ellipse at center, rgba(37, 66, 141, 1) 0%, rgba(0, 0, 0, 1) 54%);
filter: progid: DXImageTransform.Microsoft.gradient( startColorstr='#25428d', endColorstr='#000000', GradientType=1);
}
#wrapper {
padding: 20px;
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
position: relative;
height: 100%;
width: 100%;
text-align: center;
z-index: 2;
}
#wrapper .center {
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
position: absolute;
}
* {
color: white;
font-family: "Lato", Helvetica, Arial, sans-serif;
font-weight: 400;
line-height: 1.62em;
}
#logo {
margin: 40px 0;
}
#pulsor {
-webkit-animation: pulsate 60s linear 0s infinite;
-moz-animation: pulsate 60s linear 0s infinite;
-animation: pulsate 60s linear 0s infinite;
text-shadow: 0 0 8px #ccc;
}
#-webkit-keyframes pulsate {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
}
}
#-moz-keyframes pulsate {
from {
-moz-transform: rotate(0deg);
}
to {
-moz-transform: rotate(360deg);
}
}
#keyframes pulsate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
body,
html {
margin: 0;
padding: 0;
}
<div id="container">
<div id="overlay"></div>
<div id="wrapper">
<div class="center">
<h1>Tonight at</h1>
<div id="logo"><img src="http://design.ubuntu.com/wp-content/uploads/logo-ubuntu_cof-orange-hex.png" id="pulsor" width="280"></div>
<h2>Theatre</h2>
<p>19:30 - Les Miserables</p>
<p>20:30 - A cheeky Indian take-away</p>
<p></p>
<h2>Devant Room</h2>
<p>17:30 - My Favourite Books with JK Rowling</p>
<p>18:00 - Look! I did a sleight of hand! Just kidding with Lennart Green</p>
<p>19:30 - Old people grumbling about the number of steps to the Theatre</p>
</div>
</div>
</div>
If you want to scale everything you can use em or pt to set sizes for everything including image widths and padding. Then you can use vw or vmin on the font size to scale everything according to screen size.
padding:1em;
width:30em;
font-size:2vw;
Here is an example:
https://jsfiddle.net/5ezu2gLu/
Also, you can control the minimum and maximum sizes, on whatever you wish. More info here: http://madebymike.com.au/writing/precise-control-responsive-typography/
Try these changes:
Remove the center DIV from your HTML.
And change the following CSS:
#container {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background: rgb(37, 66, 141);
background: -moz-radial-gradient(center, ellipse cover, rgba(37, 66, 141, 1) 0%, rgba(0, 0, 0, 1) 54%);
background: -webkit-radial-gradient(center, ellipse cover, rgba(37, 66, 141, 1) 0%, rgba(0, 0, 0, 1) 54%);
background: radial-gradient(ellipse at center, rgba(37, 66, 141, 1) 0%, rgba(0, 0, 0, 1) 54%);
filter: progid: DXImageTransform.Microsoft.gradient( startColorstr='#25428d', endColorstr='#000000', GradientType=1);
}
#wrapper {
padding: 20px;
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
position: relative;
height: 100%;
width: 100%;
text-align: center;
}
#logo img {
max-width: 100%;
}
Here's an updated EXAMPLE
This basically scales the elements as the viewport width is reduced, however, I would advise using #media() queries to be more precise when scaling fonts etc.