animation on hover for navigation - css

I love the animation on the navigation hover for this website but I can't find the code. Can someone help??
https://mikelevin.org/
My Nav HTML is below, I want to create CSS for a Nav like the link above.
<nav id="menu" role="navigation">
<ul id="topnav" class="topnav desktop-nav">
<li class="active">
About
</li>
<li >
Join
</li>
<li >
Volunteer
</li>
<li >
Contact
</li>
</ul>
</nav>
The inout class doesn't have anything defined yet, it's just what I figured I'd name the animation class

Simply look at the <a> element, it has a :before pseudo-element.
The before is in position absolute, relative to its parent, <a>, with those settings, it takes 100% width and height of its parent:
top: 0;
right: 0;
bottom: 0;
left: 0;
Then, look at the transform properties:
transform: scaleX(0);
transform-origin: 50%;
It's like setting the width to "0", with a transform.
I haven't look at the CSS when hover on <a>, but i'm pretty much sure that it's something like that (on the pseudo-element):
transform: scaleX(1);
That one will simply animate the element from 0 to 100% of its original size.

Using chrome developer tools (right click element > inspect), you can inspect one of the nav items' CSS rules. For example, I looked at the <li> with the text of "Donate". In the styles pane you will notice that you can toggle the element's state, meaning you can manually toggle the hover state (refer to screenshot below):
To which I see the following css displayed:
#main-navigation ul.nav>li {
opacity: 1;
transition: opacity .25s ease-in-out;
-moz-transition: opacity .25s ease-in-out;
-webkit-transition: opacity .25s ease-in-out;
visibility: visible;
Additionally, if you look in the elements pane for the <a> child under this <li> you'll notice that it's expandable. As you can see, there's a pseudo-element, indicated by the ::before:
Click on that ::before in the elements pane and you can bring up its css properties:
.navbar .navbar-nav>li:not(.btn):hover a:before,
.navbar .navbar-nav>li:not(.btn):hover .hestia-toggle-search:before {
color: inherit;
-webkit-transform: scaleX(1);
-ms-transform: scaleX(1);
transform: scaleX(1);
There's just a bit more css that is applied to the ::before element for its non-hover state, but I'll leave you to play around with the DevTools to figure it out :)

Related

Css alternative to slide down using transform: scale

SlideDown type of animations are very useful to show the user what is changing in the layout. I used to do this with JQuery, but I rather have a CSS only solution.
If the element is positioned absolute, everything is perfect with using transform: scale. But it is possible to do the same when the element is taking space and should move things around?
I don't mind that it grabs it's space in one big step - as long as the animation shows some kind of direction for the eye to follow.
There is the work around with max-height - like here: https://stackoverflow.com/a/8331169/647845
, but what I don't like is that I have to estimate the height, otherwise the animation looks clunky or you're missing content.
I'm perfectly fine for using transform: scale and having a jump in the other elements. In combination with display: block it does not work though. I'm looking for animating both up and down.
Is there a (simple) alternative?
In conclusion I'm looking for an alternative to animating the delay of display: none/block.
.lolcat
{
transition: transform 200ms ease-in-out;
transform: scale(1,0);
transform-origin: 0 0;
display: none;
}
.lolcat.expanded
{
transform: scale(1,1);
display: block; /* I wish you'd be delayable */
}
You can use margin-top property and animate menu.
See the Snippet below:
#lolcat-container{
overflow:hidden;
}
.lolcat
{
border:1px solid black;
background:red;
color:white;
margin-top:-100%;
animation-direction: reverse;
animation:1s 1 alternate forwards close;
}
#menu:hover .lolcat
{
animation:1s 1 alternate forwards open;
}
#keyframes open {
0% {
margin-top:-100%;
}
100% {
margin-top:0%;
}
}
#keyframes close {
0% {
margin-top:0%;
}
100% {
margin-top:-100%;
}
}
<div id="menu">
<a>hover me</a>
<div id="lolcat-container">
<ul class="lolcat">
<!-- Create a bunch, or not a bunch, of li's to see the timing. -->
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
</ul>
</div>
<div>
Content
</div>
</div>
You can also test it here

Trouble understanding CSS animations

I am trying to wrap my head around the CSS animation property. In my current code, I have basically this structure:
<div>
<div>
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</div>
</div>
The li's inside are generated via JS, and what I'd like to do is animate the expansion so it's not as abrupt. I attached
animation: 1s linear;
to the outermost div, but it doesn't animate. What I'm trying to do is as the li's are added/removed, the height of the wrapper should animate instead of simply change. I've been looking through various docs and sites, but I can't figure out if I don't understand the property or if I'm using it wrong.
First of all, it's good to know the difference between transition and animation in CSS, and when to use each.
transition is used when you want to animate changes to either specific properties (transition: opacity .5s, color .5s), or all properties (transition: all .5s) as they are altered. This way, if you change a property like opacity via - for example - a CSS hover state, or JavaScript, that change will animate.
animation is used to set a keyframe animation to an element, where you predefine a sequence of steps that can affect one or more properties of that element.
The type of animation you're requesting - simply animating an element in/out as it is added or removed from the DOM - does not exist in CSS alone. However, many JavaScript libraries can intelligently add/remove CSS classes while an element is added/removed, allowing CSS animations to carry out.
With that said, there is a way we could decently animate in <li> elements with CSS alone, by having them start with a keyframe animation.
Here's a live demo where I'm doing just that by animating each new <li>'s height from 0 to 2em (which I've specified as the line-height). Note that width and height can only transition to a specified value - not auto.
$('button').on('click', function() {
$('ul').append('<li>List Item</li>');
});
div {
border: 1px solid teal;
border-radius: 4px;
padding: 1em;
}
ul {
list-style: none;
margin: 0;
padding: 0;
}
li {
animation: grow 1s;
line-height: 2em;
overflow-y: hidden;
}
#keyframes grow {
0% {
height: 0;
}
100% {
height: 2em;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<ul>
<li>List Item</li>
</ul>
<button>Add to List</button>
</div>

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.

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/

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