This question already has answers here:
How can I transition height: 0; to height: auto; using CSS?
(41 answers)
Closed 4 years ago.
Below is a simplified version of a restaurant menu i've created. When you hover over the dish, a description of the dish shows up, and i created a transition to make it smoother.
The next dish, the menu item below, gets pushed down when the description of the upper menu item is shown. I would like to create a transition so that the text below moves further down on the page more smoothly instead of it changing from one place to another instantly, since that looks rather glitchy on the page (if that makes any sense).
I would also like to make the opacity transition work both ways - right now, works when i hover over the item, but when i take the mouse off it, it goes away instantly, so the transition doesn't work both ways at the moment. i've tried using the not hover function with no luck.
Here's my code:
Fiddle demo
HTML:
<html>
<body>
<h4 class="navn"> Pizza </h4>
<div class="beskrivelse">
<p> ingredients: cheese, ham, pepperoni </p>
</div>
<h4 class="navn"> Hamburger </h4>
<div class="beskrivelse">
<p> Comes with salad and fries </p>
</div>
</body>
</html>
CSS:
h4:hover + .beskrivelse {
opacity: 1;
height: auto;
}
h4:hover {
color: red;
}
.beskrivelse {
height: 0;
opacity: 0;
overflow: hidden;
transition: opacity 3s ease-out;
}
.beskrivelse {
max-height: 0; /* <-- max-height since we don't know the actual height */
...
transition: all 3s ease-out; /* <-- transition all properties */
}
h4:hover+.beskrivelse {
...
max-height: 100px; /* <-- a safely large value */
}
Demo
Well, it looks jumpy because CSS values can only be transitioned to and from fixed unit values. height:0 and height:auto don't have units and therefore can't display a transition.
There are multiple workarounds, each with their own drawbacks. Here's a bunch more detail about the available options. Switching to max-height as isherwood said is one of the more accepted options.
That said, there are other ways you could solve it without trying to animate height.
h4 {
padding:0;
margin:0;
}
.beskrivelse {
/* give container position to keep child in place */
position: relative;
margin:0;
padding:0;
}
.beskrivelse p {
/* take the element out of the flow */
position: absolute;
top: 0;
left:100px;
z-index: 10;
/* move it away and hide it */
transform: translateY(200%);
opacity:0;
/*setup animation */
transition: all 0.25s ease-in-out;
/* make it look nice */
margin:0;
padding: 10px;
border-radius: 8px;
border: 1px solid #6DABE4
background: #ffff;
box-shadow: 0 0 5px 0 rgba(0,0,0,0.3);
}
h4:hover + .beskrivelse p {
transform: translateY(0);
opacity:1;
}
<h4 class="navn"> Pizza </h4>
<div class="beskrivelse">
<p> ingredients: cheese, ham, pepperoni </p>
</div>
<h4 class="navn"> Hamburger </h4>
<div class="beskrivelse">
<p> Comes with salad and fries </p>
</div>
Related
I'm maybe 2 weeks into coding so apologies if I don't format correctly (code and question itself).I am trying to set a delay for the time it takes the buttons to switch text. Thank you for the help!
I've tried googling this and youtube with no luck.
I have tried adding
transition
transition-delay
body{
background-color: black;
}
.column{
position: fixed;
left:0;
bottom:0;
top:55px;
width:72px;
z-index: 200;
padding-top: 20px;
}
.about,
.skills {
font-size:72px;
width: 10em;
text-align: left;
border:none;
background-color: black;
color:red;
}
.about:hover span {
display: none;
}
.about:hover:after {
transition-delay: 3s;
content: "ABOUT";
}
.skills:hover span {
display: none
}
.skills:hover:after {
content: "SKILLS"
}
<h1>
<div class="column">
<button class="about" data-hover="ABOUT">
<span>
I
</span>
</button>
<button class="skills">
<span>
AM
</span>
</button>
</div>
</h1>
First of all, I would look into the html semantics a bit. Having div tags inside an h1 doesn't make much sense. So consider changing the h1 to a div. Also, the 3s delay is enormous. Think of something a bit faster, like 300ms.
The real issue is that display states and transition don't really work together since it swaps between states like block and none. But there are other solutions to this. You could use position: relative; on a parent div and give the children position: absolute. This way, you could make the transitions with opacity instead.
I have made an example for you so you can get the idea. I have commented on the CSS so you can follow up on what is happening.
/* Lets give our spans some styling: */
span{
font-size: 30px;
font-weight: 600;
font-family: sans-serif;
margin-bottom: 2rem;
max-width: 60ch;
}
/* Lets make the "container" position relative,
this way the absolute children will stay inside the container */
.hover-effect{
position: relative;
}
/* Let's give both of the children position absolute */
.hover-effect span{
position: absolute;
color: black;
opacity: 100%;
transition: 300ms ease-in 300ms; /* Delay: 300ms*/
}
/* Let’s override the previous.
This actually happens when we remove the hover, so we want to
trigger this animation first, hence the delay of 0ms*/
.hover-effect span.on-hover{
opacity: 0%;
transition: 300ms ease-in 0ms;
}
/* When we hover the container, let's change both spans */
.hover-effect:hover span{
color: red;
opacity: 0%;
transition-delay: 0ms;
}
/* Let’s override the previous.
When we hover on the container, the span with the class "on-hover"
becomes visible, and we wait 300ms before it happens so that the
"disappearing" animation gets its time to trigger. */
.hover-effect:hover span.on-hover{
opacity: 100%;
transition-delay: 300ms;
}
<div class="hover-effect">
<span>Try and hover over me</span>
<span class="on-hover">Try and remove the hover</span>
</div>
This question already has an answer here:
How to show CSS transitions only on hover?
(1 answer)
Closed 1 year ago.
So, I have a hover transition that I would like to ease in on hover, but be instantaneous off hover.
Here's a sample snippet:
.invisible{
opacity: 0;
transition: 1s;
}
div{
cursor: pointer;
}
div:hover .invisible{
opacity: 100%;
}
<div>
<p>Hover Here</p>
<p class="invisible">Now you see me</p>
</div>
What can I change in the CSS to keep the text fading in over the space of 1 second, but instantly vanish when the mouse is moved away?
You can give transition to hover state only, by default it was given to all states.
Once you'll use it for :hover, transition will occur only for mouseover, not for mouseout.
.invisible {
opacity: 0;
}
div {
cursor: pointer;
}
div:hover .invisible {
opacity: 100%;
transition: 1s; /* moved this */
}
<div>
<p>Hover Here</p>
<p class="invisible">Now you see me</p>
</div>
You just need to specify a different transition-duration for the two states, resp. specify the duration not equal zero just for the hover state.
(transition: 0s; for the normal state - because you want it to be 0, when you return into this state, from the hover state. Can be implicit, if no transition-duration is already set for that state.)
.invisible{
opacity: 0;
/* transition: 0s; */
}
div{
cursor: pointer;
}
div:hover .invisible{
opacity: 100%;
transition: 1s;
}
<div>
<p>Hover Here</p>
<p class="invisible">Now you see me</p>
</div>
I'm trying to get a square div that says "read more" when hovering over a circle div with a picture inside it. Been trying different things and haven't found a working solution on google.
HTML
<div class = "portfolio" id = "first"> <!-- makes the circle -->
<a href = "cake-page.html">
<div class = "readm"> Read more </a> </div>
<img src = "cake.jpg" />
<p> The cake </p> </div>
CSS
.portfolio {
/* the circles on the portfolio-page */
position: relative;
border-radius: 100%;
display: inline-block;
height: 150px;
width: 150px;
border: 2px solid purple;
}
.portfolio.img {
opacity: 1;
transition: 1s ease;
background-size: 90px 0px;
overflow: hidden;
border-radius: 100px;
-webkit-border-radius: 50px;
-moz-border-radius: 50px;
width: 150px;
height: 150px;
}
.portfolio:hover {
/* hover effect on portfolio circles */
opacity: 0.6;
-webkit-transform: scale(1.2);
-ms-transform: scale(1.2);
transform: scale(1.2);
transition: 1 ease;
visibility: visible;
}
So either the text pushed the image down or it stays in the top of the circle and I can't get it to hover together with the other hover effect. I want the "read more" to pop-up in a rectangular div when hovering over together with the other hover effect.
I did not include the div class "readm" since I can't get it to work. FYI I'm pretty new to this. Thanks.
A little tough without a working example and it'd be good to see the readm css since we need to see what isn't working. That said, have you tried something like this:
.readm {
opacity:0;
position:absolute;
top:50%;
left:50%;
transform:translate(-50%, -50%);
}
.portfolio:hover .readm {
opacity:1;
}
Also I would place the start of that a tag inside the readm div.
First, you need to fix your markup.
You are closing the anchor ("a") tag before closing a DIV. That alone will make your CSS fail.
I presume you want to close the DIV like so:
<div class="readm">Read more</div>
Basically I'm trying to create this flipping effect that I found on this site
You can see the effect on the main title and subtitle when clicking on the far right arrow (to see the arrow hover over at the far right of the colored section) which makes the titles flip up.
I don't really know how to do this effect so I found an example on the web, but the problem is that it has the hover state to it and I can't get my head around how to make it auto start on page load instead of hovering. As you can see on this example the flip sides A and B are both colored, I wish to start from A side being background white and text in white then flip it into to the colored version, so with other words from invisible to visible.
Check my working Demo here
The code for this example is the following:
/* Set-up */
body {
color: rgb(6, 106, 117);
text-transform: uppercase;
font-family: sans-serif;
font-size: 100%;
background: #F4F6F8;
padding: 3em 0 0 0;
line-height: 62px;
-webkit-perspective: 1000px; /* <-NB */
}
/* Container box to set the sides relative to */
.cube {
width: 30%;
text-align: center;
margin: 0 auto;
height: 100px;
-webkit-transition: -webkit-transform .33s;
transition: transform .33s; /* Animate the transform properties */
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d; /* <-NB */
}
/* The two faces of the cube */
.flippety,.flop {
background: rgb(247, 247, 247);
border: 1px solid rgba(147, 184, 189, .8);
height: 100px;
}
/* Position the faces */
.flippety {
-webkit-transform: translateZ(50px);
transform: translateZ(50px);
}
.flop {
-webkit-transform: rotateX(-90deg) translateZ(-50px);
transform: rotateX(-90deg) translateZ(-50px);
}
/* Rotate the cube */
.cube:hover {
-webkit-transform: rotateX(89deg);
transform: rotateX(89deg); /* Text bleed at 90º */
}
<div class="cube">
<div class="flippety">
<h1>Flippity</h1>
</div>
<div class="flop">
<h2>Flop</h2>
</div>
</div>
My goal:
Is to create a flipping cube that flips my title up automatically (no hover) on page load.
If something is not clear please let me know and I will try to explain as clear as possible. Thank you!
In the example you give, there are no 3d transforms for the title flip. It is a simple 2D translation on the Y axis like this one:
div{
position:relative;
font-size:2em;
line-height:1.2em;
height:1.2em;
overflow:hidden;
}
h2{
font-size:1em;
margin:0; padding:0;
animation:slide .5s .5s ease-out forwards;
}
#keyframes slide {
to {transform:translateY(-1.2em);
}
<div id="titles">
<h2>this is title one</h2>
<h2>This is a second title</h2>
</div>
I'm not sure what you are trying to accomplish but if you only want it to flip once when the page is ready you can change the css class ".cube:hover" to ".cubeRotate" and then use jQuery to rotate it on page load like this:
$( document ).ready(function() {
$(".cube").addClass("cubeRotate");
});
You can see it here: https://jsfiddle.net/qro8euyo/ working with 2 seconds delay (otherwise it will be too fast for the user to catch it)
I'm trying make an animation as if I was typing. To achieve this I'm using CSS animation 'steps'.
The animation itself works just fine. However, if I want to animate multiple lines of text, they all start playing at the same time. Which isn't giving me the desired effect. (Tried using <br> in a single <h1>, which cut off the text, but again started the animations simultaneously.)
To counter this, I put the next line of text in an <h2> and set an animation-delay for every line of text. Which works, but the text is visible before the animation starts.
I want the text to be hidden until the animation starts playing, to really get that 'live typing' effect.
Anyone got any ideas on how I can achieve this?
HTML
<div class="content">
<h1>Hi there! My name is Jeff.</h1>
<h2>And I create cool stuff.</h2>
</div>
CSS
.content h1 {
background:white;
opacity:0.7;
white-space:nowrap;
overflow:hidden;
border-right: 3px solid black;
-webkit-animation: typing 2s steps(26, end),
blink-caret 1s step-end 2s;
}
.content h2 {
background:white;
opacity:0.7;
white-space:nowrap;
overflow:hidden;
border-right: 3px solid black;
-webkit-animation: typing 2s steps(26, end),
blink-caret 1s step-end infinite;
-webkit-animation-delay:3s;
}
#-webkit-keyframes typing {
from { width: 0; }
to { width:400px; }
}
#-webkit-keyframes blink-caret {
from, to { border-color: transparent }
50% { border-color: black }
}
jsFiddle
The simplest solution is to add:
animation-fill-mode:both;
to your h2 (with the necessary prefixes). That way, you aren't setting it to a zero width outside of your animation, so browsers that don't support this CSS will display the heading (which I guess is what you're after). See this fiddle.
The animation-fill-mode:
specifies how a CSS animation should apply styles to its target before
and after it is executing
Setting it to both in this instance means that your h2 will have a width of 0 before it starts executing, and a width of 400px after.
As the comments already include a solution, perhaps this might be another way of doing it - by using timeouts and setting visibility: hidden at the beginning (For simplification I just used jQuery to set the visiblitiy).
Include the following CSS rule:
.content {
visibility: hidden;
}
As JavaScript you would have:
window.setTimeout(function() {
$('#contentdiv h1').css('visibility', 'visible');
}, 100);
window.setTimeout(function() {
$('#contentdiv h2').css('visibility', 'visible');
}, 3100);
See the jsFiddle
p
{
font:500 22px consolas;
width:20ch;
white-space:nowrap;
overflow:hidden;
animation:type 5s steps(20) infinite;
}
#keyframes type
{
0%{ width:0; }
}
<p>Text Type Animation</p>
Not quite the OP's question, but in case someone else finds this useful:
I wanted to be able to typing-animate a pararaph of text, a single <p> tag which might contain text that would wrap, and produce an unknown number of actual lines. Applying a simple linear animation to the p tag itself wouldn't work, so instead, I took the approach of having several "hider" elements that would cover the paragraph of text, each one line high, and then I would animate each of those so they would shrink away, reveal characters from the line of text beneath them.
The HTML looks like this:
<div class="container">
<!-- container div is required to set absolute positions within it, so that .typing and .hiders exactly overlap -->
<p class="typing">
This paragraph of text will be animated
with a "typewriter" style effect, and it
will continue to work even if it splits across
multiple lines. Well, in this case, up to a
maximum of 5 lines, but you get the picture.
</p>
<div class="hiders">
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
</div>
</div>
You need a container, and position the .typing element and the .hiders using absolute so that they're on top of each other:
.container {
position: relative;
font-family: Consolas, monospace;
}
.typing {
position: absolute;
top: 0;
margin: 0;
z-index: -1;
}
.hiders {
margin: 0;
position: absolute;
top: 0;
width: 100%;
}
And the animation gets applied to each p inside the .hiders:
.hiders p {
position: relative;
clear: both;
margin: 0;
float: right; /* makes animation go left-to-right */
width:0; /* graceful degradation: if animation doesn't work, these are invisible by default */
background: white; /* same as page background */
animation: typing 2s steps(30, end);
animation-fill-mode: both; /* load first keyframe on page load, leave on last frame at end */
}
.hiders p:nth-child(2) {
animation-delay: 2s;
}
.hiders p:nth-child(3) {
animation-delay: 4s;
/* etc */
Here's the final fiddle:
https://jsfiddle.net/hjwp/514cLzxn/
Original credit for inspiration: Lea Verou