I am trying to animate height property of an element using CSS but I want it from the center. Below is my code but it changes height from bottom.
.toggle {
position: absolute;
width: 400px;
height: 200px;
background: #ccc;
}
.left-border {
position: absolute;
top: 50px;
left: 10px;
width: 20px;
height: 60px;
border-radius: 200px;
background-color: #ff0000;
animation: height 2s;
}
#-webkit-keyframes height {
from {
height: 60px;
}
to {
height: 10px;
}
}
<div class="toggle">
<div class="left-border"></div>
</div>
Here is JSFIDDLE
You can use transform
from {
}
to {
transform: scaleY(0.1666);
}
0.1666 comes from 10px / 60px
Here you go. I use animation top instead of height. The red toggle also needs a 'container' now so I just used the one you had there. When changing the dimensions of the red toggle, change the outer wrapper, not the toggle element (it will fit to whatever the container is, both width and height wise)
https://jsfiddle.net/j2refncs/7/
.toggle {
width: 20px;
height: 40px;
background: #ccc;
position: relative;
.left-border {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
border-radius: 200px;
background-color: #ff0000;
animation: height 2s;
}
}
#-webkit-keyframes height {
from {
top: 0;
}
to {
top: 30px;
}
}
Just add top: 75px to the keyframe since the change in height is 50px. You want to reduce the height by 25px or half from both sides, top and bottom, to come to the desired 10px. So 50px / 2 + top: 50px = top: 75px:
.toggle {
position: absolute;
width: 400px;
height: 200px;
background: #ccc;
}
.left-border {
position: absolute;
top: 50px; /* starting position from the top */
left: 10px;
width: 20px;
height: 60px;
border-radius: 200px;
background-color: #f00;
animation: height 2s;
}
#-webkit-keyframes height {
to {height: 10px; top: 75px} /* + ending position from the top */
}
<div class="toggle">
<div class="left-border"></div>
</div>
You can animate the top with the height to make the height change appear from the center:
.toggle {
position: relative;
width: 400px;
height: 200px;
background: #ccc;
}
.left-border {
position: absolute;
top: 25px;
left: 10px;
width: 20px;
height: 60px;
border-radius: 200px;
background-color: #ff0000;
animation: height 2s forwards;
}
#keyframes height {
from {
top: 25px;
height: 60px;
}
to {
top: 50px;
height: 10px;
}
}
<div class="toggle">
<div class="left-border"></div>
</div>
You can also use transform: scaleY() in the animation. The default transform origin is the center.
.toggle {
position: relative;
width: 400px;
height: 200px;
background: #ccc;
}
.left-border {
position: absolute;
top: 25px;
left: 10px;
width: 20px;
height: 60px;
border-radius: 200px;
background-color: #ff0000;
animation: height 2s forwards;
}
#keyframes height {
from {
transform: scaleY(1);
}
to {
transform: scaleY(0.167);
}
}
<div class="toggle">
<div class="left-border"></div>
</div>
Related
This is the code that I have so far, the color changes like it is supposed to. But the animation for moving does not work and stays in the same position. Not sure what I am missing.
div {
height: 50px;
width: 50%;
background: blue;
margin: 50px auto;
border-radius: 5px;
postion: relative;
}
#square {
animation-name: first;
animation-duration: 4s;
}
#keyframes first {
0% {
background-color: blue;
top: 0px;
left: 0px;
}
50% {
background-color: green;
top: 25px;
left: 25px;
}
100% {
background-color: yellow;
top: -25px;
left: -25px;
}
}
You've make a simple mistake in your code.
On the div selector, you write the position selector as postion for this reason the animation can't work.
Here is the working code:
div {
height: 50px;
width: 50%;
background: blue;
margin: 50px auto;
border-radius: 5px;
position: relative;
}
#square {
animation-name: first;
animation-duration: 4s;
animation-timing-function: ease-in-out;
}
#keyframes first {
0% {
background-color: blue;
top: 0px;
left: 0px;
}
50% {
background-color: green;
top: 25px;
left: 25px;
}
100% {
background-color: yellow;
top: -25px;
left: -25px;
}
}
<div id="square">
<h1>Hello World.</h1>
</div>
I have a animated div that flies to the top right corner of the viewport.
However, because of the overflow properties it not visible outside of parent container in Firefox. It is perfectly visible in Chrome.
Element behind the scrollbar in Firefox:
Element correctly above the parent in Chrome:
How can I make it work in Firefox as well? If overflow-y: auto is removed from .container the issue doesn't appear anymore, but that's not a viable solution as I need the scrollable content.
Here is an example. You can check that it produces the desired behaviour in Chrome, but not in Firefox:
.app {
overflow: hidden;
}
.container {
width: 260px;
max-height: 400px;
background: blue;
left: 10px;
right: 10px;
top: 10px;
position: fixed;
z-index: 500;
overflow-y: auto;
}
.wrapper {
height: 250px;
padding: 10px;
margin: 5px;
background: yellow;
top: 5px;
position: sticky;
}
.content {
height: 600px;
margin: 5px;
background: orange;
}
#keyframes fly-to-top {
10% {
top: 150px;
right: 80%;
width: 50px;
}
30% {
top: 120px;
right: 70%;
width: 45px;
}
60% {
top: 75px;
right: 40%;
width: 40px;
}
100% {
top: 10px;
right: 160px;
width: 35px;
}
}
.animated {
position: fixed;
right: unset;
top: 165px;
width: 50px;
background: red;
color: white;
animation: fly-to-top linear 2s forwards;
display: flex;
align-items: flex-start;
}
<div class="app">
<div class="container">
<div class="wrapper">
<div class="animated">
Text
</div>
</div>
<div class="content">
Lorem ipsum
</div>
</div>
</div>
Try this splution:
.wrapper position set to fixed
.content is shifted down with transform: translateY()
In the .wrapper class, i was add pointer-events: none;, because
if cursor is on the .wrapper block without this property, mouse
wheel cann't scroll the content, scroll work only when drag the
scroll bar.
.app {
overflow: hidden;
}
.container {
width: 260px;
max-height: 400px;
background: blue;
left: 10px;
right: 10px;
top: 10px;
position: fixed;
z-index: 500;
overflow-y: auto;
}
.wrapper {
display: flex;
height: 250px;
padding: 10px;
margin: 5px;
background: yellow;
/* top: 5px; */
position: fixed; /* changed */
/* calculate '.container' width - scroll-track-width(12px-17px) - '.wrapper' padding(left, right) - margin(left, right) */
width: calc(260px - 12px - 20px - 10px);
z-index: 5;
pointer-events: none; /* mouse wheel work with this property */
}
.content {
height: 600px;
margin: 5px;
background: orange;
/* calculate '.wrapper' properties to shift '.content' down */
/* height + padding(top, bottom) + margin-bottom */
transform: translateY(calc(250px + 20px + 5px));
}
#keyframes fly-to-top {
10% {
top: 150px;
right: 80%;
width: 50px;
}
30% {
top: 120px;
right: 70%;
width: 45px;
}
60% {
top: 75px;
right: 40%;
width: 40px;
}
100% {
top: 10px;
right: 160px;
width: 35px;
}
}
.animated {
position: fixed;
right: unset;
top: 165px;
width: 50px;
background: red;
color: white;
animation: fly-to-top linear 2s forwards;
display: flex;
align-items: flex-start;
z-index: 100;
}
<div class="app">
<div class="container">
<div class="wrapper">
<div class="animated">
Text
</div>
</div>
<div class="content">
Lorem ipsum
</div>
</div>
</div>
Edited after comment:
You can take the animated element out of its parent (i.e. the element which has overflow: hidden), on a higher level in the HTML code - as a sibling to the container. I did that in the snippet below, and also added a z-index that places the animated element above the container:
.app {
overflow: hidden;
}
.container {
width: 260px;
max-height: 400px;
background: blue;
left: 10px;
right: 10px;
top: 10px;
position: fixed;
z-index: 500;
overflow-y: auto;
}
.wrapper {
height: 250px;
padding: 10px;
margin: 5px;
background: yellow;
top: 5px;
position: sticky;
}
.content {
height: 600px;
margin: 5px;
background: orange;
}
#keyframes fly-to-top {
10% {
top: 150px;
right: 80%;
width: 50px;
}
30% {
top: 120px;
right: 70%;
width: 45px;
}
60% {
top: 75px;
right: 40%;
width: 40px;
}
100% {
top: 10px;
right: 160px;
width: 35px;
}
}
.animated {
position: fixed;
right: unset;
top: 165px;
width: 50px;
background: red;
color: white;
animation: fly-to-top linear 2s forwards;
display: flex;
align-items: flex-start;
z-index: 501;
}
<div class="app">
<div class="container">
<div class="wrapper">
</div>
<div class="content">
Lorem ipsum
</div>
</div>
<div class="animated">
Text
</div>
</div>
I'm trying to replicate the styling of this animation but I don't know how to "fill in" the background color of the intersection of these two shapes. In the animation, the intersection is conveniently stepwise and stops where the edge of the square intersections with the origin of the circle; I can imagine using a clipping-mask to fill in that quadrant of the circle. However, is it possible to do the same more dynamically? Can you fill in the background of two intersecting shapes (while still having a transparent background otherwhere)?
.shape-interconnected {
width: 400px;
height: 300px;
position: relative;
background-color: black;
color: white;
margin: 1rem;
border-radius: 4px;
}
.shape-interconnected > .square, .shape-interconnected > .circle {
width: 50px;
height: 50px;
position: absolute;
border: 5px solid white;
transform: translate(-50%, -50%);
}
.shape-interconnected > .square {
border-radius: 4px;
top: 45%;
left: 55%;
}
.shape-interconnected > .circle {
border-radius: 50%;
top: 55%;
left: 45%;
}
<div class="shape-interconnected">
<div class="square"></div>
<div class="circle"></div>
</div>
You can recreate the dribble using html with a little css pseudo and animation magic.
This example below works at any set css variable set size border defined in the root css vars.
:root {
--size: 250px;
--border: 5px;
}
The trick in my example is by using positioning as percentages, meaning the parent .shape-interconnected controlled by the css var size, dictates all the child and child pseudo element position.
There is a lot of css to explain here, I've added comments in css, see if this inspires you to get you where you need to go...
Here is a fiddle... https://jsfiddle.net/joshmoto/378Lcgp0/
/* our root css vars */
:root {
--size: 250px;
--border: 5px;
}
BODY {
background: black;
min-height: 100%;
}
/* reset our box sizing on psuedo elems */
*, ::after, ::before {
box-sizing: border-box;
}
/* our shape intersect container positioned center of window */
/* this can be positioned where ever you want */
.shape-interconnected {
background: black;
width: var(--size);
height: var(--size);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
animation: shape-interconnected 2s infinite;
}
/* animate height and width equally */
#keyframes shape-interconnected {
0% {
width: var(--size);
height: var(--size);
}
50% {
width: calc(var(--size) * 0.6);
height: calc(var(--size) * 0.6);
}
100% {
width: var(--size);
height: var(--size);
}
}
/* our square calculated at 40% of parent */
/* position and overflow hidden are key, hiding pseudo child elems */
.shape-interconnected > .square {
width: calc(var(--size) * 0.4);
height: calc(var(--size) * 0.4);
background: transparent;
position: absolute;
overflow: hidden;
right: 0;
top: 0;
}
/* our square before pseudo elem emulating inner white filled circle */
/* position absolute with animation keyframes */
.shape-interconnected > .square::before {
content: "";
display: block;
width: 100%;
height: 100%;
background: #fff;
border-radius: 50%;
position: absolute;
animation: circle-interconnected 2s infinite;
}
/* start top/right 150% away, overflowing out of view */
/* 50% keyframe top/right 50% away, in view */
#keyframes circle-interconnected {
0% {
top: 150%;
right: 150%;
}
50% {
top: 50%;
right: 50%;
}
100% {
top: 150%;
right: 150%;
}
}
/* our square after pseudo elem emulating white border */
.shape-interconnected > .square::after {
content: "";
display: block;
width: 100%;
height: 100%;
background: transparent;
border: var(--border) solid white;
position: relative;
}
/* our circle calculated at 40% of parent */
.shape-interconnected > .circle {
width: calc(var(--size) * 0.4);
height: calc(var(--size) * 0.4);
position: absolute;
bottom: 0;
left: 0;
}
/* our circle after pseudo elem emulating white border */
.shape-interconnected > .circle::after {
content: "";
display: block;
width: 100%;
height: 100%;
background: transparent;
border: var(--border) solid white;
border-radius: 50%;
position: relative;
}
<div class="shape-interconnected">
<div class="square"></div>
<div class="circle"></div>
</div>
Here is another example using the same code above but with these css root var settings...
:root {
--size: 500px;
--border: 2px;
}
Live example below...
/* our root css vars */
:root {
--size: 500px;
--border: 2px;
}
BODY {
background: black;
min-height: 100%;
}
/* reset our box sizing on psuedo elems */
*, ::after, ::before {
box-sizing: border-box;
}
/* our shape intersect container positioned center of window */
/* this can be positioned where ever you want */
.shape-interconnected {
background: black;
width: var(--size);
height: var(--size);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
animation: shape-interconnected 2s infinite;
}
/* animate height and width equally */
#keyframes shape-interconnected {
0% {
width: var(--size);
height: var(--size);
}
50% {
width: calc(var(--size) * 0.6);
height: calc(var(--size) * 0.6);
}
100% {
width: var(--size);
height: var(--size);
}
}
/* our square calculated at 40% of parent */
/* position and overflow hidden are key, hiding pseudo child elems */
.shape-interconnected > .square {
width: calc(var(--size) * 0.4);
height: calc(var(--size) * 0.4);
background: transparent;
position: absolute;
overflow: hidden;
right: 0;
top: 0;
}
/* our square before pseudo elem emulating inner white filled circle */
/* position absolute with animation keyframes */
.shape-interconnected > .square::before {
content: "";
display: block;
width: 100%;
height: 100%;
background: #fff;
border-radius: 50%;
position: absolute;
animation: circle-interconnected 2s infinite;
}
/* start top/right 150% away, overflowing out of view */
/* 50% keyframe top/right 50% away, in view */
#keyframes circle-interconnected {
0% {
top: 150%;
right: 150%;
}
50% {
top: 50%;
right: 50%;
}
100% {
top: 150%;
right: 150%;
}
}
/* our square after pseudo elem emulating white border */
.shape-interconnected > .square::after {
content: "";
display: block;
width: 100%;
height: 100%;
background: transparent;
border: var(--border) solid white;
position: relative;
}
/* our circle calculated at 40% of parent */
.shape-interconnected > .circle {
width: calc(var(--size) * 0.4);
height: calc(var(--size) * 0.4);
position: absolute;
bottom: 0;
left: 0;
}
/* our circle after pseudo elem emulating white border */
.shape-interconnected > .circle::after {
content: "";
display: block;
width: 100%;
height: 100%;
background: transparent;
border: var(--border) solid white;
border-radius: 50%;
position: relative;
}
<div class="shape-interconnected">
<div class="square"></div>
<div class="circle"></div>
</div>
You might add a white circle inside the square and position it to the same coords the transparent one has.
Set overflow: hidden to the square to hide the outside part of the white circle:
.shape-interconnected {
width: 400px;
height: 300px;
position: relative;
background-color: black;
color: white;
margin: 1rem;
border-radius: 4px;
--animation-props: 1s alternate linear infinite;
}
.shape-interconnected>.square,
.shape-interconnected>.square:before,
.shape-interconnected>.circle {
width: 50px;
height: 50px;
position: absolute;
border: 5px solid white;
transform: translate(-50%, -50%)
}
.shape-interconnected>.square {
top: 35%;
left: 65%;
border-radius: 4px;
overflow: hidden;
animation: for_square var(--animation-props);
}
.shape-interconnected>.circle {
top: 65%;
left: 35%;
border-radius: 50%;
animation: for_transparent_circle var(--animation-props);
}
.shape-interconnected>.square:before {
content: '';
border-radius: 50%;
background: #fff;
top: 230%;
left: -190%;
animation: for_white_circle var(--animation-props);
}
#keyframes for_square {
to {
top: 50%;
left: 55%;
}
}
#keyframes for_transparent_circle {
to {
top: 55%;
left: 50%;
}
}
#keyframes for_white_circle {
to {
top: 80%;
left: 10%;
}
}
<div class="shape-interconnected">
<div class="square"></div>
<div class="circle"></div>
</div>
I am trying to make a sort of Venn-Diagram that is going to be used for navigation later.
I have three intersecting ellipsoids created with CSS shapes. Each ellipsoid, as well as their two intersections, will be distinct links later on. Also, when you hover over them they should pop out as per transform: scale(1.3).
My issue is that I'm using ellipsoids which are partially transparent with :after to create the intersections, which creates a problem when hovering over them because the :hover condition gets triggered when hovering anywhere on the partially transparent ellipsoid and not just the :after part. This means that the nonintersecting areas are not hoverable because they are obstructed by the other invisible ellipsoid.
I think the example will make this clearer.
Here is the code:
CSS:
.venn-container{position: relative; left: 0;}
.cat_one{
width: 400px;
height: 200px;
background: red;
border-radius: 200px / 100px;
position: absolute;
float: left;
opacity: 0.5;
}
.cat_two{
width: 400px;
height: 200px;
background: green;
border-radius: 200px / 100px;
position: absolute;
float: left;
left: 240px;
opacity: 0.5;
}
.cat_three{
width: 400px;
height: 200px;
background: blue;
border-radius: 200px / 100px;
position: absolute;
float: left;
left: 480px;
opacity: 0.5;
}
.int1{
background: transparent;
width: 400px;
height: 200px;
border-radius: 200px / 100px;
position: relative;
opacity: 0.5;
overflow: hidden;
float: left;
}
.int1:after{
background: black;
position: absolute;
content: '';
border-radius: 200px / 100px;
width: 400px;
height: 200px;
left: 240px;
}
.int1:hover{
transform: scale(1.3);
left: -35px;
}
.int2{
background: transparent;
width: 400px;
height: 200px;
border-radius: 200px / 100px;
position: relative;
opacity: 0.5;
overflow: hidden;
float: left;
left: 80px;
}
.int2:after{
background: black;
position: absolute;
content: '';
border-radius: 200px / 100px;
width: 400px;
height: 200px;
left: -240px;
}
.int2:hover{
transform: scale(1.3);
left: 115px;
}
HTML:
<div class="venn-container">
<div class="cat_one"></div>
<div class="cat_two"></div>
<div class="cat_three"></div>
<div class="int1"></div>
<div class="int2"></div>
</div>
And here is a fiddle: https://jsfiddle.net/y3Lvmuqg/2/
I would like the :hover to only get triggered in the intersections, and later make cat_one and cat_two hoverable outside the intersections.
I don't know if there is a way I'm doing this is the best and I'm open to suggestions.
Thanks for getting back to me #ge0rg I spent about an hour fiddling with CSS and HTML and came up with this code using just divs with background colors, hover events and border radius's (along with a few z-index and positioning techniques).
Hope you enjoy your reworked venn diagram...
You may have to mess around with the size, and definetly will have to mess with the positioning (however they're all inside a div and so it makes it so that you can just position the div and the rest will happen magically) I added a background color to the div just to show that nothing was transparent, and I also added a always on top function for viewing a section, and I hope you enjoy!
.Venn {
background: linear-gradient(to bottom right, blue, lightblue);
}
.d1:hover, .d2:hover, .d3:hover {
color: #565656;
animation: top 2s steps(2, end) forwards;
-webkit-animation: top 2s steps(2, end) forwards;
box-shadow: 0px 0px 20px white;
}
.d1, .d2, .d3 {
overflow-wrap: break-word;
}
.d1 center, .d3 center {
position: absolute;
top: 50%;
left: 50%;
transform: translateY(-50%) translateX(-50%);
}
.d1 {
padding: 10px;
width: 100px;
height: inherit;
z-index: 1;
position: absolute;
border-radius: 100%;
top: 0px;
}
.d3 {
padding: 10px;
width: 100px;
height: inherit;
z-index: 2;
position: absolute;
border-radius: 100%;
top: 0px;
left: 81px;
}
.d1:hover, .d3:hover {
transform: scale(1.05);
}
.d2 {
border-radius: 100% 0;
height: 90px;
width: 87.5px;
transform: rotate(-45deg) scale(.7);
position: absolute;
top: 15px;
left: 55.35px;
z-index: 3;
border: 1px solid black;
}
.d2b {
transform: rotate(45deg);
padding: 0;
margin: 0;
}
.d2b center {
position: relative;
left: 20px;
}
.d2:hover {
transform: rotate(-45deg);
}
.Venn {
height: 100px;
}
-webkit #keyframes top {
99% {
z-index: previous;
background-image: none;
}
100% {
z-index: 7;
}
}
#keyframes top {
99% {
z-index: previous;
background-image: none;
}
100% {
z-index: 7;
}
}
<div class="Venn" style="position: relative; left: 50px; width: 300px; height: 100px;">
<div class="d1" style=" background-color: grey;">
<center> 1 </center>
</div>
<div class="d2" style=" background-color: #AAAAAA;">
<div class="d2b" style="max-width: inherit;">
<center> 2 </center>
</div>
</div>
<div class="d3" style=" background-color: lightgrey;">
<center> 3 </center>
</div>
</div>
For those of you who would prefer a JSfiddle/ CodePen here you go a Codepen.
Below is my effort.
http://liveweave.com/i1qkNw
Below is also my code
.container {
display: inline-block;
position: relative;
border: 1px solid green;
}
.middle {
position: relative;
width: 300px;
height: 250px;
background: black;
}
.door {
position: absolute;
width: 300px;
height: 250px;
background: red;
top: 0;
left: 0;
opacity: 0.5;
transition: .5s;
transform-origin: center center;
}
.container:hover .door {
transition: .5s;
opacity: 0;
width: 0;
height: 0;
}
<div class="container">
<div class="middle"></div>
<div class="door"></div>
</div>
What i want to do is, when user hovers over container, I want the door div's width/height to be zero. As you can see, I am achieving this effect but it disappears to upper left corner. Is there any way I can make it disappear to its center?? Like the width and height are reduced till its center and disappear.
Kindly guide me how to achieve this effect.
You have to set top / bottom / left / right values to 50%.
.container {
display: inline-block;
position: relative;
border: 1px solid green;
}
.middle {
position: relative;
width: 300px;
height: 250px;
background: black;
}
.door {
position: absolute;
width: 300px;
height: 250px;
background: red;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 0.5;
transition: .5s;
transform-origin: center center;
}
.container:hover .door {
transition: .5s;
opacity: 0;
top: 50%;
bottom: 50%;
left: 50%;
right: 50%;
width: 0;
height: 0;
}
<div class="container">
<div class="middle"></div>
<div class="door"></div>
</div>