I have tried multiple methods to get this transition to work, however, ran out of ideas. The transition works fine when checking, but not unchecking. Things I have tried:
not using visibility to unhide more-info div
using all, however, it transitions, but with a fade affect, which is not what I want transition: all 300ms ease-in-out;
HTML:
<input :id="id" type="checkbox" class="checkbox" role="button">
<div class="more-info">
Content
</div>
CSS:
.more-info {
max-height: 0;
transition: max-height 300ms ease-in-out;
visibility: hidden;
opacity: 0;
overflow: hidden;
position: absolute;
bottom: 0;
width: calc(100% + 2px);
margin-bottom: -1px;
}
.checkbox {
display: none;
}
.checkbox:checked ~ .more-info {
max-height: 700px;
visibility: visible;
opacity: 1;
}
visibility: hidden; and opacity: 0; cancels the animation, as, in theory, the animation is running in max-height, the fact that you set it as hidden doesn't show the expected result.
Removing visibility: hidden; and adding opacity to your transition should fix the problem, opacity will hide the element while max-height goes to 0
Related
I'm working on this mobile menu where you can expand and collapse different categories. When doing so, a sliding animation should be performed on the expanded submenu (when expanding) or on the top-level menu (when collapsing).
The structure of the HTML is the following:
<div class="slideOpenMainMenu">
<div class="sideMenuGeneral">
...Top-level menu...
</div>
<div class="sideMenuPanelMainChildren">
...Expanded submenu...
</div>
</div>
By adding and removing classes, I show the appropriate div while hiding the other from view. As you'll notice, I go out of my way to not use anything like display:none; since then I won't be able to animate the containers. Instead I use a combination of width, height, visibility and flex properties to hide and show the containers.
/* Menu parent container */
.slideOpenMainMenu {
position: fixed;
width: 100%;
box-sizing: border-box;
background: linear-gradient(90deg, #12416e 0%, #0d3050 100%);
display: flex;
justify-content: center;
}
/* Top-level menu - Initial state */
.sideMenuGeneral {
width: 100%;
max-width: 620px;
display: flex;
flex-flow: column;
padding: 20px 16px 0 16px;
box-sizing: border-box;
overflow: hidden;
}
/* item submenu - Initial state */
.sideMenuPanelMainChildren {
width: 0;
height: 0;
flex: 0 1 0;
max-height: 100vh;
overflow: hidden;
visibility: hidden;
-webkit-overflow-scrolling: touch;
}
/* Top-level menu - Expanded state */
.slideOpenMainMenu.item-expanded .sideMenuGeneral {
width: 0%;
padding: 0 !important;
visibility: hidden;
}
.slideOpenMainMenu.item-expanded .sideMenuPanelMainChildren {
flex: 1 1 auto;
flex-flow: column;
width: 100%;
height: auto;
overflow: scroll;
visibility: visible;
}
For the animation, I use transform:translateY and opacity properties to create the sliding effect I want.
/* Initial state */
.slideOpenMainMenu .sideMenuPanelMainChildren {
opacity: 0;
transform: translateX(30%);
transition: opacity 0.5s ease, transform 0.5s ease, visibility 0s ease;
}
.slideOpenMainMenu .sideMenuGeneral {
opacity: 1;
transform: translateX(0%);
transition: opacity 0.5s ease, transform 0.5s ease, visibility 0s ease;
}
/* Expanded state */
.slideOpenMainMenu.item-expanded .sideMenuPanelMainChildren {
opacity: 1;
transform: translateX(0%);
}
.slideOpenMainMenu.item-expanded .sideMenuGeneral {
opacity: 0;
height: 0px;
transform: translateX(-50%);
}
As you can see on this fiddle, the animation works well in Chrome and Firefox. Not so well on Webkit and Edge. From what I can tell, there seems to be some kind of conflict between the change in width and the transitions, because when I disable changes in width, you can see the animation play out. What could cause the change in behavior between platforms? Is there a way to correctly sequence the changes?
So while writing this question, I arrived at the answer (as it often happens). The issue seems to be rooted in that the sequence of CSS property changes is different on different browsers. by adding a tiny delay (0.01s) to the transform transition I got it to work, like so:
transition: opacity 0.3s ease, transform 0.3s ease 0.01s, visibility 0s ease;
Still, I find this a little odd and also interesting. If anyone has info on how these things are sequenced in the browser that'd be really great to learn.
I have a problem with obtaining the effect of the dropdown menu to Wordpress template. I tried already do for many hours and it is unchanged. My knowledge of CSS is not too big, so I ask you for help.
I added to the template function dropdown menu that works on the theme of the child. I would like to get rid of gaps that are unnecessary for items from the sub-menu. Example, I'm interested in the effect as in the case of the "Test 1" and "dropmenu."
Child code:
.sub-menu {
visibility: hidden; /* hides sub-menu */
opacity: 0;
top: 100%;
left: -20px;
height: 0px;
width: 100%;
transform: translateY(-2em);
z-index: -1;
transition: all 0.3s ease-in-out 0s, visibility 0s linear 0.3s, z-index 0s linear 0.01s;
}
.menu-item:hover .sub-menu {
visibility: visible; /* shows sub-menu */
opacity: 1;
display: block;
height: 64px;
z-index: 1;
transform: translateY(0%);
transition-delay: 0s, 0s, 0.3s; /* this removes the transition delay so the menu will be visible while the other styles transition */
}
.menu-item {
position: relative;
display: inline-block;
}
Image: explanation
Website: here link
The space is coming from .sub-menu. You have height: 0; on .sub-menu, which is good, but the margin-top on the li's is overflowing and creating that space.
Adding overflow: hidden; to .sub-menu seems to fix it.
I have an element with a max-height of 0. I want to transition it to no max-height auto or none; whatever makes it expand based on the number of elements present. I don't want to use JS nor flex, yet.
Here's the jsfiddle: https://jsfiddle.net/m9pd8bjh/19/
HTML:
<nav>
<input type="checkbox" id="menu-main-checkbox" hidden>
<label class="toggler" for="menu-main-checkbox">Menu</label>
<div class="hide toggleable">
<ul>
<li>Home</li>
<li>Sample Page</li>
</ul>
</div>
</nav>
CSS:
.hide {
visibility: hidden;
overflow: hidden;
max-height: 0;
}
input[type=checkbox]:checked~.toggleable {
visibility: visible;
max-height: 68px;
}
.toggleable {
transition: visibility 1.5s ease-in-out, max-height .75s ease-in-out;
}
.toggler {
cursor: pointer
}
nav {
background: #e74c3c;
}
When I set the max-height to 68px (the height fitting two list items) it works perfectly, but when I set the max-height to 500px, for example, leaving room for future list items, it takes time to transition from 500 to 0, making it give a delay before the list items disappear again.
I do not wish to use scaling as it complicates it and I have to come up with a solution to solve the spacing under it. It keeps the spacing under the element and reserves it for when it opens out.
One workaround what I found was to use animation with #keyframes.
Remember to add vendor-prefixes.
Browser support for this is the following:
Firefox 5+, IE 10+, Chrome, Safari 4+, Opera 12+
I modified your CSS to this:
.hide {
visibility: hidden;
overflow: hidden;
max-height: 0;
}
input[type=checkbox]:checked~.toggleable {
visibility: visible;
animation: height1 .75s forwards;
}
input[type=checkbox]:not(:checked)~.toggleable {
visibility: visible;
animation: height2 .50s forwards;
}
.toggleable {
transition: visibility 1.5s ease-in-out;
}
.toggler {
cursor: pointer
}
nav {
background: #e74c3c;
}
#keyframes height1 {
0% { max-height: 0; }
100% { max-height: 500px; }
}
#keyframes height2 {
0% { max-height: 500px; }
100% { max-height: 0; }
}
If used like this there will be smaller delay when clicking again.
Here is the updated jsfiddle: https://jsfiddle.net/m9pd8bjh/25/
I am building a lightbox based on the CSS3 selector :target which selects an element based on the hash in the url. I want to animate the target element on the :target event, but this doesn't seem to work.
Let's say we have a div #banana which is shown when a link to #banana is pressed.
#banana {display: none;}
#banana:target {display: block;}
This works fine. But when trying to animate the element, that doesn't work. See this fiddle.
div#banana {
display: none;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
opacity: 0;
transition: opacity 5s linear 1s;
}
div#banana:target {
display: block;
opacity: 1;
}
The element won't fade in. It is as if the browser skips the animation and immediately triggers the end result.
The problem is that you are changing the display property. The display property can't be transitioned since you can't really animate an element turning from nothing into a block.
The display property can be left out altogether. You will however need to give your element visibility: hidden so that it will not prevent the link from being clicked, then transition it to visibility: visible:
div#banana {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
opacity: 0;
transition: opacity 5s linear 1s;
visibility: hidden;
}
div#banana:target {
opacity: 1;
visibility: visible;
}
Updated fiddle
It's not possible to animate display property. There is simply no gradual stages between none and block.
In your case you can "hide" element by using huge negative top position and revert it back to 0 on target event. Actual transition will be handled by changing opacity.
div#banana {
position: fixed;
left: 0;
top: -1000px;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
opacity: 0;
transition: opacity 1s linear;
}
div#banana:target {
top: 0;
opacity: 1;
}
<div id="banana">
close
</div>
Do you want a banana? Click me!
In HTML we have a number like 12.34 When someone hovers their mouse over it I'd like it to expand with some sort of transition to reveal additional significant digits, for example 12.345678.
Is this possible with just CSS and what would be the simplest way? (e.g. I probably don't want to use a fixed width div with overflow hidden, which then expands, because the width could be variable with numbers like 123.45, 1,234.56 etc.) So I'm thinking have two divs one rounded, one with all digits - but then we'd need some way to transition between them smoothly. Thanks!
I agree with Marc B - there are too many possible variations to determine the dot position to use just one field without resorting to using JS. However this is my solution, with two fields
http://jsfiddle.net/chrisdanek/mSjsj/1/
<span class="num">
<span class="abbr">123.45</span>
<span class="full">123.4567</span>
</span>
<span class="num">
<span class="abbr">123,345,567.45</span>
<span class="full">123,345,567.45000</span>
</span>
<span class="num">
<span class="abbr">123,345,567.455634434</span>
<span class="full">short one</span>
</span><!-- this one is not possible with numbers, but just to show how it works with shorter second number -->
And CSS
.num {
position: relative;
display: inline-block;
padding: 5px;
border: 1px solid red;
-webkit-transition: width 0.2s;
-moz-transition: width 0.2s;
-o-transition: width 0.2s;
transition: width 0.2s;
}
.abbr {
position: relative;
top: 0;
left: 0;
display: block;
opacity: 1;
z-index: 1;
-webkit-transition: opacity 0.2s;
-moz-transition: opacity 0.2s;
-o-transition: opacity 0.2s;
transition: opacity 0.2s;
}
.full {
top: 5px; left: 5px;
position: absolute;
display: block;
z-index: 0;
opacity: 0;
-webkit-transition: opacity 0.2s;
-moz-transition: opacity 0.2s;
-o-transition: opacity 0.2s;
transition: opacity 0.2s;
color: red;
}
.num:hover .abbr { position: absolute; top: 5px; left: 5px; opacity: 0; z-index: 0; }
.num:hover .full { position: relative; top: 0; left: 0; opacity: 1; z-index: 1; }
The best I could come up with is opacity change, as it doesn’t require setting width on the container. Without that it’s impossible to make a transition for width (you’ll notice transition code is added, but it’s not being executed). Perhaps someone else can come up with a workaround.
I couldn't get the opacity transitions to work cleanly on our side for some reason. But this is a much simpler version in case it helps someone: (in SASS)
.num {
display: inline-block;
.abbr { display: block; }
.full { display: none; }
&:hover {
.abbr { display: none; }
.full { display: block; }
}
}