CSS Transitions for drop down menu not working - css

I have the following two-level menu:
<ul class="mid-nav-top-ul">
<li class="mid-nav-top-li"><a class="mid-nav-top-a">Trading News</a>
<ul class="mid-nav-two-ul">
<li class="mid-nav-two-li"><a class="mid-nav-two-a" href="#">Articles</a></li>
<li class="mid-nav-two-li"><a class="mid-nav-two-a" href="#">Stocks</a></li>
<li class="mid-nav-two-li"><a class="mid-nav-two-a" href="#">Forex</a></li>
<li class="mid-nav-two-li"><a class="mid-nav-two-a" href="#">Commodities</a></li>
<li class="mid-nav-two-li"><a class="mid-nav-two-a" href="#">Options</a></li>
</ul>
</li>
</ul>
I have the following CSS to make it a drop-down sort of menu:
.mid-nav-two-ul{height: 0px; -webkit-transition: height 0.5s; transition: height 0.5s;}
.mid-nav-top-ul:hover .mid-nav-two-ul{height: auto;}
It doesn't take into account the transition - it drops down/ changes height instantaneously.
Any ideas?
Thanks

Firstly, setting the height of the menu ul won't necessarily affect what's visible. If the overflow is set to hidden, e.g. overflow: hidden; then the height change will affect content inside because we then understand what to do with 'overflowing' content.
Secondly, we cannot animate the height property directly, you must use max-height. You can then set max-height to be some arbitrary value that is guaranteed to be higher than your ul list will ever be.
Here's working code:
.mid-nav-two-ul
{
max-height: 0px;
overflow: hidden;
-webkit-transition: max-height 0.5s;
transition: max-height 0.5s;
}
.mid-nav-top-ul:hover .mid-nav-two-ul
{
max-height: 1000px;
}
Here's a working JSFiddle for you.

Related

CSS width transition and hover

I'm trying to implement a slide show like menu with CSS. It's working fine except for transition. If transition is used the elements are not in sync anymore. Whole menu losing width if multiple elements are hovered in short time. Everything works fine if transition is removed.
Is there anything I have to be aware of when using CSS transitions and hover together? I thought a transition-timing-function: linear; would be enough to get width in sync. It seems like the transition is started early on the fading out element than fading in element.
Some technical notes about implementation:
It's a ul list. Menu items are represented as li. Selected menu item has a selected. This one is shown if there isn't any user interaction. The other ones are collapsed. If an element is hovered it's opened and all other ones are collapsed. There should be a transition effect when changing from collapsed to shown.
ul {
list-style: none;
display: inline-block;
padding: 0;
/*
* remove gaps between inline elements
* https://css-tricks.com/fighting-the-space-between-inline-block-elements/
*/
font-size: 0;
}
ul li {
display: inline-block;
overflow: hidden;
/*
* Transition
*/
transition: width 0.5s;
transition-timing-function: linear;
width: 50px;
}
ul li:hover,
ul li.selected,
ul:hover li.selected:hover {
width: 564px;
}
ul:hover li.selected {
width: 50px;
}
<ul>
<li>
<a href="http://www.3ker-ras-group.com/profil.html">
<img src="http://www.3ker-ras-group.com/images/m_profil.jpg" alt="Unser Profil">
</a>
</li>
<li class="selected">
<a href="http://www.3ker-ras-group.com/referenzen.html">
<img src="http://www.3ker-ras-group.com/images/m_referenzen_der_3ker_ras_group.jpg" alt="Referenzen der 3KER RAS GROUP">
</a>
</li>
<li>
<a href="http://www.3ker-ras-group.com/jobs.html">
<img src="http://www.3ker-ras-group.com/images/m_hoehenarbeiter_jobs.jpg" alt="Jobs für Höhenarbeiter">
</a>
</li>
<li>
<a href="http://www.3ker-ras-group.com/shop-kletterbedarf.html">
<img src="http://www.3ker-ras-group.com/images/m_kletterbedarf_shop.jpg" alt="Unser Shop für Kletterbedarf">
</a>
</li>
<li>
<a href="http://www.3ker-ras-group.com/kontakt.html">
<img src="http://www.3ker-ras-group.com/images/m_kontakt_zum_unternehmen.jpg" alt="Kontakt aufnehmen">
</a>
</li>
</ul>
Trigger the issue by moving cursor fast from left to right. It occurs at least in Firefox and Chrome. Didn't tested safari, IE and edge.
Here is a JSFiddle: https://jsfiddle.net/vj12qswz/3/
All elements should fit in one line. Adjust preview window width if necessary.
Works fine if you use javascript to add a specific class on hover.
Probably best to add "onclick" event as well because hover not gonna work on touch devices.

Dynamic Height Animation in CSS

After trying the following techniques, I am still stuck with how to animate an element's height in CSS.
The max-height Method JSFiddle
For my case, this is no good because all elements have varying heights. Furthermore you will notice a slight delay before the height starts to animate back up to 0px. This happens when the height of an element is much smaller (say 50px) than the 500px max-height set in the animation.
The transform Method JSFiddle
Again, this is no good for my case as you can see that it's not revealing more/less of the element like in the max-height method. This method is better for varying elements with varying height, but you can see it's rotating in from top to bottom. The scaleY method has the same problems.
So you can see that I need the animation to reveal the element from top to bottom. Also, the animation should have no delay revealing/hiding the element on mouse-over and mouse-out.
I have set a wrapper around your ul
And I have transformed both the wrapper and the ul in the Y axis, one upwards and the other in the opposite direction. Setting the amount of the transform to 100% makes it adjust exactly to the dimensions of the element.
So, it's kind of a sliding door that reveals the content progressively.
It' key for the succes of this technique that the 2 elements have the same height. I have transfered the margin by default of the ul to the wrapper
.wrap {
margin: 10px;
overflow: hidden;
transform: translateY(-100%);
transition: transform 1s linear;
position: relative;
}
.wrap ul {
margin: 0px;
transform: translateY(100%);
transition: inherit;
}
.trigger:hover .wrap {
transform: translateY(0%);
}
.trigger:hover .wrap ul {
transform: translateY(0%);
}
.trigger ~ .trigger {
margin-left: 200px;
}
<div class="trigger"> Hover
<div class="wrap">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
<div class="trigger"> Hover
<div class="wrap">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
</ul>
</div>
</div>
Note that the hover zones are a little bit tricky. But I haven't give much time to this issue as I understand this not key to what you want

CSS3 hiding transition

I have a menu where the height and visibility transitions on hover, and transitions back when it's not hovered. It works fine, but the links collapse on top of each other when it's fading back to hidden. I've been searching everywhere and I can't figure out how to keep them from collapsing on top of each other. So my question is, how do I stop it from doing that? Is it just some simple solution that I'm overlooking, or is it something more complex?
HTML
<header>
<section id="logo_section">
<h1>FLASH OF REALITY</h1>
<p>Photography, Film, & Animation in Utah</p>
</section>
<nav>
<ul>
<li>Home</li>
<li>Photography</li>
<li>Video</li>
<li>Animation</li>
<li>My Portfolio</li>
<li>Service</li>
<li>Blog</li>
<li>About Me</li>
/ul>
</nav>
</header>
CSS
header ul li {
visibility: hidden;
height: 0px;
transition: visibility .5s, height .5s;
}
header:hover ul li {
visibility: visible;
height: 57px;
}
As you transition the height of the <li> items, they will each gradually go to 0, so they'll all just be sitting on top of each other as they have no height.
Instead of transitioning the <li>, you could transition a max-height of the <ul> from 0 to a value that is taller than the list will be.
header ul {
max-height: 0;
transition: max-height .5s;
overflow: hidden;
}
header:hover ul {
max-height: 600px;
}
http://jsfiddle.net/4CfeU/2/

How do I stop my divs from moving around while zooming?

Good day everyone,
I am working on a website for a local astronomy club that I am doing for free to build up both my portfolio and skill set.
I have a navigation bar within my header at the top of the page. When I zoom out to about 90% the elements within the navigation bar move around and cause the layout to look a little funky.
If it helps, I have a live example at
http://www.JamesRobertCook.com/BCAAS/
Here is the HTML for my navigation bar:
<div id="header_bar">
<div id="nav">
<div id="cssmenu">
<ul>
<li class="active"><span>Home</span></li>
<li class="has-sub"><span>Products</span>
<ul>
<li class="has-sub"><span>Product 1</span>
<ul>
<li><span>Sub Item</span></li>
<li class="last"><span>Sub Item</span></li>
</ul>
</li>
<li class="has-sub"><span>Product 2</span>
<ul>
<li><span>Sub Item</span></li>
<li class="last"><span>Sub Item</span></li>
</ul>
</li>
</ul>
</li>
<li><span>About</span></li>
<li class="last"><span>Contact</span></li>
</ul>
</div>
</div>
And here is the CSS associated:
#header_bar {
background: rgba(44, 44, 44, 0.75);
height: 36px;
margin: 0 auto;
}
#nav {
height: 36px;
margin: 0 auto;
width: 960px;
}
#cssmenu {
height: 36px;
background-color: rgb(44, 44, 44)s;
}
#cssmenu ul {
margin: 0;
padding: 0;
}
#cssmenu > ul > li {
float: left;
margin-left: 15px;
position: relative;
#cssmenu > ul > li > a {
color: rgb(160,160,160);
font-family: Verdana, 'Lucida Grande';
font-size: 15px;
line-height: 36px;
padding: 15px 85px;
-webkit-transition: color .15s;
-moz-transition: color .15s;
-o-transition: color .15s;
transition: color .15s;
I thought that sticking it inside of a container and giving it a fixed height/width would do the trick, but I tried that locally and had no success.
Thanks for any help! If possible, could you please explain what I was doing wrong? I'd like to learn from my mistakes!
Thanks!
EDIT
I just noticed that when zooming, the content in my three 'featured' boxes, overlaps the respective div it lives in as well! I certainly broke something.
I am sooooooo sorry. I got side-tracked looking at a content div down further on the page and totally lost focus on your true problem. I hope a simple solution to your original problem will help you forgive me.
#header_bar {
background: rgba(44, 44, 44, 0.75);
height: 36px;
margin: 0 auto;
min-width: 960px;
}
That min-width: 960px; (the 960px is 960 pixels which is the same width as the rest of the primary content of the page) means that the <div> with id="header_bar" can not be any smaller than 960px which makes it fit with the rest of your content even if someone views on a super low resolution, resizes the browser window or zooms in really far.
Again, so sorry for totally screwing that one up, but on a side note, I believe I could give you some pointers on a few things if you are interested. Just for example, you seem to overuse <div>'s and <span>'s in your page. Those two elements are not exclusive to receiving some of the styling which you have applied to them and the child elements in some cases or the parent elements of those elements could receive the style and you could eliminate those elements entirely.
If you want more detailed explanation on the tips and hints and such, I love playing sounding board for ideas and discussing programming/development and I think I could show you a few things I've learned over the years that would help you.
Your div elements need to grow taller or you need to set the overflow on them if you don't want the text to run through the borders, but aside from that I don't see where your div elements are doing anything unusual. They are static sized and they don't change size for anything. They "move" because the user is resizing/zooming and they can't stay static during that. You would have to find a way to keep your users from resizing/zooming to prevent anything changing.
Try using % as the unit versus px to assign width for the <li> (list item)
(i.e) if you are using five <li> in ur menu, assign width:20% to <li>

Dropdown Menu - Make the <ul> submenu 100% width

I am going a bit crazy trying to achieve something my client wants. I could tell them it's not possible but I love a good challenge ;)
Basically, I'm trying to do a dropdown menu in which the dropdown <ul>, or:
ul.menu li ul
is surrounded by a div. Kind of:
<ul class="menu">
<li>
Item
<div class="submenu">
<ul>.....</ul>
</div>
</li>
</ul>
I want that div to have width:100% and fill the whole width of the page but have the UL inside aligned to the appropriate <li>.
The problem is the <div class="submenu"> will be as wide as the relative container, be it the main <ul class="menu"> or a <div> wrapping the <ul class="menu">.
The website itself has 1000px width and is centered width margin:0 auto;
I hope I have explained myself properly :S Here is a link to a mock up I have put together: Dropdown Menu Mock up
Any help highly appreciated.
Thanks,
Alex
Old question, but hopefully answer will help someone. I had to work on something similar to this a month or so ago.
Here is a fiddle of what I basically did (note: you have to do some extra work for this to work the same in older IEs): http://jsfiddle.net/doubleswirve/xbLrW/2/
I didn't use a nested div and instead stuck with nested lists. With a basic markup like the following:
<div class="nav">
<ul>
<li>
Products
<ul>
<li>Widget A</li>
<li>Widget B</li>
<li>Widget C</li>
</ul>
</li>
<li>
Locations
<ul>
<li>Location A</li>
<li>Location B</li>
<li>Location C</li>
</ul>
</li>
<li>
Staff
<ul>
<li>President</li>
<li>VP</li>
<li>Manager</li>
</ul>
</li>
</ul>
</div>
You can use the following styling:
/* GENERAL */
body { overflow-x: hidden; } /* trick from css-tricks comments */
/* FIRST LEVEL */
.nav > ul > li {
display: inline-block;
position: relative;
padding: 3px 10px 3px 0;
z-index: 100;
}
/* SECOND LEVEL */
.nav > ul > li > ul {
position: absolute;
left: 0;
top: 100%;
padding: 0 1000em; /* trick from css-tricks comments */
margin: 0 -1000em; /* trick from css-tricks comments */
z-index: 101;
visibility: hidden;
opacity: 0;
background: rgba(255, 240, 240, 0.8);
}
.nav > ul > li:hover > ul {
visibility: visible;
opacity: 1;
}
.nav > ul > li > ul > li {
padding: 3px 0;
}
If you wanted to get snazzy with the CSS, you could add this to the second level ul:
.nav > ul > li > ul {
...
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
transition: all 0.3s ease;
}
If anyone is interested in making this work similarly in old IEs or wants deeper nested lists, let me know.
To give you a head start, here are some useful links that helped me:
Full browser width bars (CSS tricks article/comment)
Fixing z-index (helpful for IE7)
Chris Coyier really covers us at work lol.
You're quite right, in that that box model doesn't work that way.
There is one thing I can think of, and that is to set your divs to
position:absolute
and use the top, left, right attributes to position them. But, as you say, that won't work if you have position: relative on a parent element.
To be honest, it'll be difficult to achieve this without a horrible mess of workarounds which will probably break between browsers. I've seen peers and colleagues spend ages trying to implement things like this, building more and more precarious code 'fixes' to get it to work cross-browser, receiving complaints from clients about it not working in IE6 and Firefox 1.5, only to give up on that 'feature' entirely.

Resources