I have three elements and once I clicked one of it I want to move it to the center but from its position with a transition of, for example, 1 second. Also, I want to increase fade the text and show another text during the time when the box increases from 150px to 200px but for now I just don't know how to center it on a click. I did it but it goes from bottom right to the center but I want it to go from its position.
Also, I tried using $(this) to get certain div but it just didn't work
$(document).ready(function(e) {
$('.second').click(e => {
$('.second').addClass('red')
})
});
.main {
display: flex;
gap: 15px;
height: 90vh;
justify-content: center;
align-items: center;
position: relative;
}
.block {
width: 150px;
height: 100px;
box-shadow: 0px 0px 3px #000;
}
.red {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 150px;
height: 150px;
transition: 1s ease;
color: red;
#keyframes rise;
#keyframes rise {
0% { width: 200px; height: 200px }
100% { width: 150px; height: 150px }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='main'>
<div class="first block">Hello</div>
<div class="second block">Hi</div>
<div class="third block">hello</div>
</div>
Just change offset values of that element on click.
This is happening because everything is transitioning,
the sequence of centering the div in your code is like this:
First, its position becomes absolute
then it goes to the bottom right direction because you have top 50%; left 50%;
then it comes back to the center because of transform: translate( -50%, -50%)
You can fix it to ways:
Change the centering method to margins
$(document).ready(function(e) {
$('.second').click(e => {
$('.second').addClass('red')
})
});
.main {
display: flex;
gap: 15px;
height: 90vh;
justify-content: center;
align-items: center;
position: relative;
}
.block {
width: 150px;
height: 100px;
box-shadow: 0px 0px 3px #000;
}
.red {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
width: 150px;
height: 150px;
transition: 1s ease;
color: red;
#keyframes rise;
#keyframes rise {
0% { width: 200px; height: 200px }
100% { width: 150px; height: 150px }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='main'>
<div class="first block">Hello</div>
<div class="second block">Hi</div>
<div class="third block">hello</div>
</div>
In this way, the div goes nowhere, just to the center.
Second way is to not transition position and transform
$(document).ready(function(e) {
$('.second').click(e => {
$('.second').addClass('red')
})
});
.main {
display: flex;
gap: 15px;
height: 90vh;
justify-content: center;
align-items: center;
position: relative;
}
.block {
width: 150px;
height: 100px;
box-shadow: 0px 0px 3px #000;
}
.red {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 150px;
height: 150px;
transition: 1s ease;
transition-property: width, height, color;
color: red;
#keyframes rise;
#keyframes rise {
0% { width: 200px; height: 200px }
100% { width: 150px; height: 150px }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='main'>
<div class="first block">Hello</div>
<div class="second block">Hi</div>
<div class="third block">hello</div>
</div>
The transition-property Property defines which properties to transition so, I put: width, height and color. You can change what you wanna transition
Related
I have tried achieving this effect using border-radius (code below) but I want the circle to be smaller, as shown in this example https://imgur.com/a/gKHtVXr and I don't think I can acheive this with border-radius.
<img class = "zyra-thumb" src = "thumbnail champion/thumb2.png" alt="zyra">
CSS:
.zyra-thumb{
width: 200px;
height: 200px;
object-fit: cover;
border-radius: 150px;
transition: border-radius 0.3s;
}
.zyra-thumb:hover{
border-radius: 10px;
}
you can use clip-path to display only center of the thumb image and
transition: clip-path 1s;to give needed animation on hover
.thumb {
background: purple;
width: 200px;
height: 200px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 10px;
}
.zyra-thumb {
width: 100%;
object-fit: cover;
clip-path: circle(25% at 50% 50%);
transition: clip-path 1s;
border-radius: 10px;
}
.zyra-thumb:hover {
clip-path: circle(100% at 50% 50%);;
}
<div class="thumb">
<img class="zyra-thumb" src="https://www.gravatar.com/avatar/0cf65651ae9a3ba2858ef0d0a7dbf900?s=256&d=identicon&r=PG&f=1" alt="zyra">
</div>
Based on your attached image I assume this is the effect you are trying to achieve.
.zyra-thumb {
background: url(https://i.stack.imgur.com/OR7ho.jpg) no-repeat center;
background-size: cover;
position: relative;
width: 400px;
height: 400px;
overflow: hidden;
display: inline-block;
border-radius: 20px;
}
.zyra-thumb::before {
content: "";
display: block;
width: 50%;
padding-bottom: 50%;
position: absolute;
top: 50%;
left: 50%;
z-index: 2;
transform: translate(-50%, -50%);
border: solid 400px #41373f;
border-radius: 50%;
transition: all ease-in-out 0.3s;
}
.zyra-thumb:hover::before {
width: 150%;
padding-bottom: 150%;
}
<div class="zyra-thumb">
</div>
Simply use border-radius:0px; in hover.
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>
This question already has answers here:
Center div horizontally and vertically inside another div
(2 answers)
How can I horizontally center an element?
(133 answers)
Closed 2 years ago.
I am trying to make a div sit in the direct center of another div. I tried to use margin: auto; to accomplish this, but the div only aligned in the center horizontally. How can I apply this for a center vertical align?
.topbar {
overflow: hidden;
width: 100%;
height: 50px;
background-color: #131218;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
display: flex;
align-items: center;
justify-content: space-between;
}
.body {
display: block;
width: 100%;
height: 330px;
background-color: blue;
border-bottom-left-radius: 20px;
border-bottom-right-radius: 20px;
}
img {
height: 50px;
padding: 5px;
border-radius: 200px;
float: left;
will-change: transform;
animation: logofloat 1s ease-in-out infinite alternate;
}
#keyframes logofloat {
from {
transform: translateY(5px);
}
to {
transform: translateY(15px);
}
}
.authdiv {
background-color: red;
height: 200px;
width: 200px;
margin: auto;
}
<div class="topbar">
<img class="logo" src="https://dummyimage.com/50x50/fff/000.png&text=Logo">
</div>
<div class="body">
<div class="authdiv"></div>
</div>
You could use flexbox on your containing element:
.topbar {
overflow: hidden;
width: 100%;
height: 50px;
background-color: #131218;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
display: flex;
align-items: center;
justify-content: space-between;
}
.body {
display: flex;
flex-flow: column nowrap;
width: 100%;
height: 330px;
background-color: blue;
border-bottom-left-radius: 20px;
border-bottom-right-radius: 20px;
}
img {
height: 50px;
padding: 5px;
border-radius: 200px;
float: left;
will-change: transform;
animation: logofloat 1s ease-in-out infinite alternate;
}
#keyframes logofloat {
from {
transform: translateY(5px);
}
to {
transform: translateY(15px);
}
}
.authdiv {
background-color: red;
height: 200px;
width: 200px;
margin: auto;
}
<div class="topbar">
<img class="logo" src="https://dummyimage.com/50x50/fff/000.png&text=Logo">
</div>
<div class="body">
<div class="authdiv"></div>
</div>
I usually put the element i want to center at 50% from top and 50% from left. Then use translate to pull the element back half it's size. So just add the 4 lines below.
.authdiv {
background-color: red;
height: 200px;
width: 200px;
margin: auto;
position:absolute;
left:50%;
top:50%;
transform:translate(-50% , -50%);
}
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>
I'd like to get this effect:
But I cant move only the content, leaving fixed the container. If you see my fiddle, I'm moving all together, the content and the container.
And even I'd like to put the hover on the circle div, not in the content like it is right now, because now when the animation ends it losing the hover.
A little detail to keep in mind:
I need to update at runtime the text to display due it should be
translated depending on the language selected by the user.
Here is my fiddle
.frame {
display: flex;
background-color: green;
height: 200px;
width: 200px;
flex-direction: center;
justify-content: center;
align-items: center;
}
.oval {
display: flex;
background-color: white;
border-radius: 50px;
width: 100px;
height: 100px;
}
.box {
display: flex;
flex-direction: column;
background-color: gray;
height: 100px;
width: 100px;
position: relative;
top: 25px;
transition: top 200ms ease-in;
border-radius: 50px;
}
.box:hover {
top: -50px;
transition: top 200ms ease-in;
animation: ticker 25s cubic-bezier(1, 0, .5, 0);
}
#keyframes ticker {
0% {
margin-top: 0
}
25% {
margin-top: -30px
}
50% {
margin-top: -60px
}
75% {
margin-top: -90px
}
100% {
margin-top: 0
}
}
.box-inn {
flex: 1;
margin: 5%;
color: white;
text-align: center;
align-items: center;
}
.first {
background-color: blue;
}
.second {
background-color: red;
}
<div class="frame">
<div class="oval">
<div class="box">
<div class="box-inn first">
Text 1
</div>
<div class="box-inn second">
Text 2
</div>
</div>
</div>
</div>
You can use pseudo-elements. First hide :after with transform: translateY(100%) and overflow: hidden on parent, and on hover you translate :before for 100% and move :after to 0.
.elem {
position: relative;
width: 100px;
height: 100px;
border: 1px solid white;
color: white;
border-radius: 50%;
background: #4CA5D0;
overflow: hidden;
}
.elem:after,
.elem:before {
content: 'Top';
position: absolute;
transition: all 0.3s ease-in;
top: 0;
left: 0;
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.elem:after {
content: 'Bottom';
transform: translateY(100%);
}
.elem:hover:before {
transform: translateY(-100%);
}
.elem:hover:after {
transform: translateY(0);
}
<div class="elem"></div>
If you don't want to use pseudo-elements Fiddle
If your icons are images you may want a non-pseudo element method. Here's an example using a font awesome icon to illustrate an image (fa icons can be used with pseudo elements, however)
.link {
position: relative; /* for absolute positioned children to work */
display: inline-flex;
flex-direction: column;
height: 100px; /* this method uses absolutely position chldren so..*/
width: 100px; /* ..a fixed width and height was needed */
color: white;
border-radius: 100%;
border-color: white;
border-style: solid;
border-width: 2px;
overflow: hidden; /* hides the overflowing elements */
}
.icon {
position: absolute;
top: 50%; /* vertically position icon in center in combination with transform -50% */
left: 50%; /* same deal with horizontal centering */
transform: translate(-50%, -50%); /* horizontal, vertical */
transition: all 0.2s ease;
}
.text {
position: absolute;
top: 150%; /* positions text under the .link container element */
left: 50%;
transform: translate(-50%, -50%);
transition: all 0.2s ease;
}
.link:hover .icon {
top: -50%; /* positions icon above the .link container element */
}
.link:hover .text {
top: 50%; /* moves text into center of .link container element */
}
/* styling - ignore */
body {display: flex;justify-content: center;align-items: center; height: 100vh;margin: 0;font-size: 24px;background-color: hsl(189, 72%, 45%);font-variant: small-caps;font-family: verdana;}.icon i {font-size: 40px;}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet"/>
<a class="link" href="https://jsfiddle.net/Hastig/4akmbgc1/">
<div class="icon"><i class="fa fa-home"></i></div>
<div class="text">fiddle</div>
</a>
fiddle
https://jsfiddle.net/Hastig/4akmbgc1/
Following #Nenad Vracar answer:
On:
I need to update at runtime the text to display due it should be
translated depending on the language selected by the user.
You can use data-attributes along with the attr() CSS function in the pseudo-elements' content property.
Note: Change these data-attributes with JS in your language handling logic.
.elem {
position: relative;
width: 100px;
height: 100px;
border: 1px solid white;
color: white;
border-radius: 50%;
background: #4CA5D0;
overflow: hidden;
}
.elem:after,
.elem:before {
content: attr(data-top-text);
position: absolute;
transition: all 0.3s ease-in;
top: 0;
left: 0;
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.elem:after {
content: attr(data-bottom-text);
transform: translateY(100%);
}
.elem:hover:before {
transform: translateY(-100%);
}
.elem:hover:after {
transform: translateY(0);
}
<div class="elem" data-top-text="top_text" data-bottom-text="bottom_text"></div>
Another alternative is to use the :lang pseudo-class.
Using lang attribute in the element.
.elem {
position: relative;
width: 100px;
height: 100px;
border: 1px solid white;
color: white;
border-radius: 50%;
background: #4CA5D0;
overflow: hidden;
}
.elem:after,
.elem:before {
content: "top_text";
position: absolute;
transition: all 0.3s ease-in;
top: 0;
left: 0;
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.elem:after {
content: "bottom_text";
transform: translateY(100%);
}
.elem:hover:before {
transform: translateY(-100%);
}
.elem:hover:after {
transform: translateY(0);
}
.elem:lang(es):before {
content: "texto_superior";
}
.elem:lang(es):after {
content: "texto_inferior";
}
<div class="elem"></div>
<div class="elem" lang="es"></div>
Changing the html lang attribute:
document.getElementById('change-lang').addEventListener('click', function() {
document.documentElement.setAttribute('lang', 'es');
});
.elem {
position: relative;
width: 100px;
height: 100px;
border: 1px solid white;
color: white;
border-radius: 50%;
background: #4CA5D0;
overflow: hidden;
}
.elem:after,
.elem:before {
content: "top_text";
position: absolute;
transition: all 0.3s ease-in;
top: 0;
left: 0;
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.elem:after {
content: "bottom_text";
transform: translateY(100%);
}
.elem:hover:before {
transform: translateY(-100%);
}
.elem:hover:after {
transform: translateY(0);
}
:lang(es) .elem:before {
content: "texto_superior";
}
:lang(es) .elem:after {
content: "texto_inferior";
}
<div class="elem"></div>
<button id="change-lang">Cambiar a EspaƱol</button>