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.
Related
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
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 div element containing a paragraph tag of text. When I hover this div, I want the text to come out the div (from behind). I tried negative z-index but it didn't work.
.box p {
display: block;
position: absolute;
top: 0;
right: 0;
opacity: 0;
z-index: -1;
visibility: hidden;
transition: top .3s, opacity .3s, visibility .3s, z-index .3s;
}
.box:hover p {
top: -28px;
opacity: 1;
z-index: 1;
visibility: visible;
}
Two problems. First, you have visibility:hidden in both cases so the element will never show.
The second problem is, the div has no height when the <p> isn't visible or hovered over so you can't hover over it at all.
To fix this to help get you on your way:
div {height:100px;}
.box p {
display: block;
height:300px;
position: absolute;
top: 0;
right: 0;
opacity: 0;
z-index: -1;
transition: top .3s, opacity .3s, visibility .3s, z-index .3s;
}
.box:hover p {
top: -28px;
opacity: 1;
z-index: 1;
}
But that might be the ideal way for you and you'll need to adjust it.
Note that, on hover, you have top: -28px; so it's scrolled slightly off screen on the right hand side.
EDIT:
Another thing I want you to be aware of. z-index is not a transitional property. That is, you cannot transition from zero to 0.1 to 0.2 on your way to a rounded 1.0. z-index is an actual layer and you can only go in whole units from one level to the next.
How can I realize a smooth transition for my mobile menu?
The transform property is working, but I want it to happen slowly..
My Sass looks like this
.mobile-nav
display: none
position: relative
width: 100%
background: $white
padding: 30px 0 20px
transform: translateY(-100%)
#media (max-width: 775px)
.mobile-nav.is-o
display: block
transform: translateY(0%)
The main obstacle you're facing is that the display property is not animatable.
Like a light switch, display: none is off and display: block is on. There's no middle ground, no fade effects, no CSS transitions.
However, there are multiple other properties you can use for transitions. Among them:
height
opacity
z-index
background-color
Here's an example:
.mobile-nav-toggle {
font-size: 2em;
cursor: pointer;
}
.mobile-nav {
display: inline-block;
overflow: hidden;
width: 0;
height: 0;
opacity: 0;
transition: width 1s, height 1s, opacity 0s 1s, background-color 0s 2s;
}
.mobile-nav-toggle:hover + .mobile-nav {
width: 150px;
height: 150px;
opacity: 1;
background-color: lightgreen;
transition: 1s;
}
<div class="mobile-nav-toggle">☰</div>
<div class="mobile-nav">
<ul>
<li><a>Item</a></li>
<li><a>Item</a></li>
<li><a>Item</a></li>
</ul>
</div>
References:
Full list of animatable properties in CSS
Transitions on the display: property
I personally use opacity combined with visibility to achieve fade effect like I would like for whole element. Remember to manipulate z-index, so you "hidden" object won't be clickable when dissapeared.
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!