I have a problem with my hamburger menu, especially with the icons. My HTML looks like this:
<input type="checkbox" id="check"/>
<header class="IndexHeader">
<nav class="navigation">
<label class="Hamburger" for="check">โฐ</label>
<label class="schliessen" for="check">โ</label>
<ul class="IndexNavliste">
a list...
</ul>
</nav>
</header>
I want my .schliessen label to rotate 180 degrees when I click on the .Hamburger label, so that it is like an animation effect. I tried it like this with jQuery:
$(".Hamburger").click(function(){
$(".schliessen").css("transform","rotate(180deg)");
});
That didn't really work for me. Also, I think I need a transition in it so that I really can see it when I click the label. I also tried to do it in the CSS directly so when my checkbox is checked. That works but I couldn't see the animation and my hover effect didn't work anymore after that...
.Hamburger{
display: block;
transition: 500ms;
}
.schliessen{
transition: 500ms;
}
.schliessen:hover{
color: black;
}
#check:checked + .IndexHeader .navigation .Hamburger{
display: none;
}
#check:checked + .IndexHeader .navigation .schliessen{
display: block;
transform: rotate(180deg);
}
The issue with transition and transform:rotate("180deg") is happening because transform never gets a new value from first click onwards on Hamburger. To overcome that I have added and removed classes on clicks.
Have also removed un-necessary CSS and added what is required for this problem :
Here is the working code:
codepen.io/emmeiWhite/pen/XWjBXRY?editors=1111
Related
I'm currently attempting a do very specific kind of navigation bar for my website. The main 'feature' of it is that on hover over each menu item, the item itself grows, while both the item before and the item after moves x pixels away from the item.
The styling of these elements is what would perform these transformations, using the following:
.navitem{
display:inline;
transition: transform .75s ease-in-out;
}
.navitemRight {
transform: translate(10px);
}
.navitemLeft{
transform: translate(-10px);
}
.navitemCenter{
text-shadow:0px 0px 1px black;
transform: scale(1.20);
}
The problem is that there seems to be no way to apply these style whenever an item is hovered. It seems as though for each item, they should have these kind of stylings :
.item2 : hover ~ item 1{
blabla
}
.item2 : hover ~ item 3{
blabla
}
but they should generated somehow, since the navigation bar's items are dynamic.
I tried using React and really thought I was going to get away with it, where onMouseEnter and onMouseLeave changed the state of the component, and everytime, it would re-render the navbar, with the correct style, like so:
almost working but ugly when hover out
But it does not satisfy me because we only get the transform when hovering, and lose the transition whenever the state changes, which is why the change is so ugly when I hover out. For reference, here's an example of what it looks like when you have the same trasnform and transition:
simple transform
Anyways, I am sure there is a way to do it, using Javascript probably, maybe sass or Jquery, both of which im not really familiar with. If you have any idea, or maybe a reference to tools that could help me with that, it would be very apprecited!Thanks
You can apply conditional classes on each element, based on your component state. The conditional classes will be added/removed based on template string literals
Here's an example that does basically what you want, but through a different method. It's all in CSS so it will not have and rendering issues.
I've moved all .nav-links to the left 10px if they aren't being hovered (this is therefore their default state).
Once you hover on one this will increase in size by 1.2 as you would like.
All subsequent .nav-links after the hovered one (using the subsequent sibling selector ~) will move to the right by 10px to accomodate the increase in size.
You can fine tune this to your preferences, but at least it gives you a nice structure to work from and looks reasonably slick I think!
Demo
nav {
padding: 0px 24px;
}
.nav-link {
display: inline-block;
transition: transform .75s ease-in-out;
background: whitesmoke;
height:20px;
width:40px;
padding: 4px 8px;
text-align: center;
}
.nav-link:not(:hover) {
transform: translate(-10px);
}
.nav-link:hover {
transform: scale(1.2);
}
.nav-link:hover ~ .nav-link {
transform: translate(10px);
}
<nav>
<a class='nav-link'>Link</a>
<a class='nav-link'>Link</a>
<a class='nav-link'>Link</a>
<a class='nav-link'>Link</a>
</nav>
I have a problem with my navbar, can someone help me ?
I have different links (<a>) that "unfold" an unordered list (<ul> of links <li><a><li>).
My <ul> is set to opacity: 0, and in my CSS I have :
.tab ul {
opacity: 0;
pointer-events: none;
}
.tab a:focus + ul {
opacity: 1;
transform: translateY(0px);
pointer-events: all;
}
(this is only the part of the code that doesn't work)
When I click the link, the tab does unfold, and pointer-events is set to all (I know it is because the sublinks color changes when hovered).
My problem is that whenever I click a sublink, the focus on the tab link is lost, and it seems to set pointer-events to none BEFORE executing the sublink's action (a basic href="page.html").
I tried removing :focus (as if the tab was in constant focus state), and the sublinks redirect me on the pages as intended.
I also tried putting pointer-events: all on ul > li > a, but it didn't work.
That's why I came to the conclusion that the tab link lose focus and the pointer event is set to none before the sublink is actually clicked.
Does someone know a way to work around this and execute the sublink's action before the focus loss ?
The tab is unfold and the sublink is hovered (mouse invisible on the screenshot thought) :
If I understood you correctly, then maybe add this solution can help you:
.tab a + ul:hover {
opacity: 1;
transform: translateY(0px);
pointer-events: all !important;
}
Because the focus of the link is lost, the submenu disappears, but you can leave the submenu by ul:hover.
P.S. By the way, on the example of the site that you specified, add this code at the end, it quite works (I tried using Web Inspector):
.menu-loisirs a + ul:hover, .menu-sports a + ul:hover {
opacity: 1;
transform: translateY(0px);
pointer-events: all !important;
}
For this kind of interaction, :focus-within is usually quite suitable. When the "trigger" link and wrapper of its children share same wrapper, it makes sense to bind logic to state of that parent wrapper. To make such structure keyboard accessible, can use .wrapper:not(:hover):not(:focus-within) .trigger + .content { /* visually hidden state styles */}:
.tab:not(:hover):not(:focus-within) a + ul {
display: none; /* for brevity, use accessible hiding in real world */
}
/* not necessary */
p[id]:not(:target) {
display: none;
}
a[href]:empty:before {
content: '๐ ' attr(href);
}
p[id]:empty:before {
content: 'ยง ' attr(id)
}
<div class="tab">
<ul>
<li>
</li>
<li>
</li>
</ul>
</div>
<div class="tab">
<ul>
<li>
</li>
<li>
</li>
</ul>
</div>
<p id="a"></p>
<p id="a1"></p>
<p id="a2"></p>
<p id="b"></p>
<p id="b1"></p>
<p id="b2"></p>
Check the browser support (not supported in IE11 and older browsers) and consult accessibility and screen reader support before using in production.
This is really a matter of me messing around in the CSS, and ending up unknowingly deleting or overriding something. When I hover over the nav link which drops down a list, it fades in. However, it doesn't fade out when it disappears after moving the mouse away.
Link to fiddle
<nav class="bg">
<ul class="width nav">
<li><span></span></li>
<li>Link</li>
<li><span></span></li>
<li>DropLink
<ul class="drop dr2">
<li>Link</li>
<li>Link</li>
<li>Link</li>
</ul>
</li>
<li><span></span></li>
</ul>
</nav>
CSS (sorry for the mess on this one. In the full CSS file, it's all combined to save on space):
*{margin:0;padding:0;font-size:small;font-family:Roboto;vertical-align:middle;}
.drop,nav{border:1px solid #BBB;}
body>.main,nav>ul{font-size:0;}
.width{margin:0 auto;width:84%;}
.width,.bg{min-width:1000px;}
.bg,.drop{background:linear-gradient(#444,#000,#444);}
nav{border-left:none;border-right:none;}
nav>ul:after{content:"";}
nav a{padding:8px;}
nav a:hover, nav a:active{color:#BBB;}
.drop{z-index:2;left:-9999px;top:-9999px;opacity:0;border-top:none;}
.dr1{transform:translateX(-28.5%);width:230%;}
.dr2{transform:translateX(-27%);width:216%;}
.drop li{white-space:nowrap;display:block;}
.nav li:hover .drop{left:0;top:100%;opacity:1;transition:opacity .5s,top 0s,left 0s;}
nav span{border-left:1px solid #000;border-right:1px solid #555;padding:7px 0;}
nav{font-weight:bold;}
nav>ul{text-align:justify;}
nav>ul,nav>ul:after{width:100%;}
a{text-decoration:none;}
a{color:#FFF;}
.nav li:hover .drop{text-align:center;}
nav a,nav li,nav>ul:after{display:inline-block;}
nav li,nav>ul{position:relative;}
.drop{position:absolute;}
While I'm asking, I might as well kill two birds with one stone and ask something else. If you zoom in on the bar where the borders are, you'll see that they don't actually have the same height as the navbar itself. If I increase the padding in the relevant area in my CSS, it becomes one pixel too long. If I don't, it's one pixel too short. It is never 100% the height of the bar. I asked this question not too recently, but after changing the entire navbar code, I've been unable to replicate the solution.
Your problem is that you are only setting the left and top rules on hover, but when you aren't hovering the dropdown completely leaves the view, so although the opacity if fading, you can't see it.
What you need to do is change two group selectors to have the same position whether hovering or not.
E.G.
.nav li:hover .drop {
left:0;
top:100%;
opacity:1;
transition:opacity .5s, top 0s, left 0s;
}
Should become two selectors:
.nav li .drop {
left: 0;
top: 100%;
pointer-events: none;
opacity: 0;
transition: opacity .5s, top 0s, left 0s;
}
.nav li:hover .drop {
pointer-events: auto;
opacity: 1;
}
In addition, your text-align property should be set even when not hovering, otherwise the text will shift left.
E.G.
Delete:
.nav li:hover .drop {
text-align:center;
}
Add:
.nav li .drop {
text-align:center;
}
If you make these corrections, you should get: jsfiddle.net/4PLbd/28
Note:
I don't want to be nitpicky, but your code is styled terrible and makes fixing things difficult, always try to make code readable. I did not clean up a lot of code here, although it should be.
You should probably consider re coding this, half of your CSS was unecessary and also had to be cleaned up. I also took out code that was not needed, I can show you how to do it better, for instance the spaces with span elements, not necessary. Also, good code structure is important, as it will help you find and locate problems. I cleaned this up as best as I could. Again, this gets your first question done.
Here is just a few CSS changes that I made. Check the Jsfiddle
.drop {
opacity: 0;
transition: all .5s ease;
}
ul.nav li:hover .drop {
opacity: 1;
transition: all .5s ease;
}
I've been trying to get this right for a couple of days now, and so far, I haven't really made progress on getting the dropdown working at all, though partly because the guides I've read all make use of symbols in the CSS that I'm unfamiliar with, such as the tilde and 'greather than' symbols. In any case, here is the base code that I have:
<nav class="bg">
<ul class="width">
<li>Link</li>
<li>
<ul>
<li>Link</li>
<li>Link</li>
</ul>
</li>
</ul>
</nav>
CSS:
.width{margin:0 auto;min-width:1000px;width:84%;}
nav ul{width:100%;text-align:justify;font-size:0;position:relative;}
nav ul:after{content:"";width:100%;display:inline-block;}
nav li{list-style:none;display:inline-block;}
nav a{display:inline-block;padding:10px;}
I think the next step is to put display:none; on the inner <ul> elements to hide them by default, but the next part is where I get lost. How do you use CSS to make one object do something when something else happens to another object? In this case, how would you use the CSS to make the dropdown list appear when the relevant link is hovered?
Here is a Demo
First of all you need to understand how CSS Selectors are working.
For the way to add a Dropdown, you go for the hover on the parent element and wrap that around the sub-menu. Than if the hover event is fired everything inside will be able to select true :hover
Like:
.nav li:hover .sub-menu {
left: 0;
top: 100%;
}
I also added the Fade-In effect. There for you work with css-transition.
But be careful, if your Sub-menu will be on/off with display:block and :none it wont work i guess.
U may play around with that in that fiddle to fiddle out what you can do and how your changes effect the output.
.nav .sub-menu {
position: absolute;
left: -1000px;
top: -1000px;
opacity: 0;
-o-transition: opacity .25s;
-ms-transition: opacity .25s;
-moz-transition: opacity .25s;
-webkit-transition: opacity .25s;
transition: opacity .5s;
}
.nav li:hover .sub-menu {
left: 0;
top: 100%;
opacity: 1;
}
You can even create a dropdown without using any selectors. But it is important to know about selectors. Go through this link to know more about selectors.
You can have a look at Pure CSS Dropdown Menu to check how to create dropdown menu with css.
You have yourself correctly pointed out the problem and that is :
How do you use CSS to make one object do something when something else
happens to another object?
I think this simplest demo, would shed some light on your above question.
Specifically have a deeper look at below CSS in the demo.
#circle:hover .popup{
display : block;
}
How do you use CSS to make one object do something when something else happens to another object? In this case, how would you use the CSS to make the dropdown list appear when the relevant link is hovered?
li > a ul { display: none; }
li > a:hover ul { display: block; }
You can also play with transitions to add fade-in effect.
I've got two divs, div 1, and underneath it is hidden div 2. When I hover over div 1, I want it to hide, and show div 2. Then, once I mouse off of the area (now div 2), div 1 is displayed again.
Here is the code:
<a href="javascript://" class="hoverable">
<div class="normal" style="background:#666;">Hover over me!</div>
<div class="hover" style="background:#888;">Now you see me!</div>
</a>
and here is the css:
<style>
.hoverable {
cursor:default;
color:#000;
text-decoration:none;
}
.hoverable .hover {
display:none;
}
.hoverable:hover .normal {
display:none;
}
.hoverable:hover .hover {
display:block;
}
</style>
My only problem with this is that is is very quick, cut and dry, and not very "fancy". I'd like to add something simple like a fade effect.
I've gotten this working, without the fade effect, here:
http://jsfiddle.net/pBDGW/
If anyone knows how to make those two divs transition with a fade-out, please let me know!
You can use CSS transition with opacity like this:
.hoverable {
cursor:default;
color:#000;
text-decoration:none;
position: relative;
display: block;
}
.hoverable .hover {
opacity:0;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.hoverable .hover,
.hoverable .normal{
transition: opacity .5s;
-o-transition: opacity .5s;
-ms-transition: opacity .5s;
-moz-transition: opacity .5s;
-webkit-transition: opacity .5s;
}
.hoverable:hover .normal {
opacity:0;
}
.hoverable:hover .hover {
opacity:1;
}
You can see the jsfiddle here: http://jsfiddle.net/pBDGW/12/
Some explanation:
The transition applied to both div are the main code that make them fade in & out. You can read more about it here: http://css3.bradshawenterprises.com/transitions/
Since you want the first div to fade out, and the second div to fade in, there will be a moment when both div have to be visible partially, hence position: absolute and some positioning on the second div (to make it overlap with the first div).
You are wrapping an anchor (<a>) around both div, which is actually not encouraged, so I have to give it display: block; . A better approach (HTML-wise) is to wrap both div inside another div (still use the same class hoverable), and use 2 different anchors inside each div.
EDIT: this approach http://jsfiddle.net/pBDGW/14/ works too. Here you only fade out the first div, while the second div is always visible but is hidden under the first div when not hovering. It is shorter css, but I don't recommend this approach though because I sometimes have issues with getting the first div to go on top on different browsers.
You can use jQuery, it has functions fadeIn and fadeOut and also its easy to hide() and show() on events mouseOver and mouseLeave.
You can see fiddle here.
$(document).ready(function(){$(".hover").hide();
$(".normal").mouseover(function(){
$(".normal").fadeOut(0);
$(".hover").fadeIn(1000);
});
$(".hover").mouseout(function(){
$(".normal").fadeIn(1000);
$(".hover").fadeOut(0);
});});
You can use transitions:
ADD THIS TO YOUR :HOVER
-o-transition:.5s;
-ms-transition:.5s;
-moz-transition:.5s;
-webkit-transition:.5s;
transition:.5s;
This adds the effect of fade IN/OUT
Addition: this will only work if you have property set for :hover, for example if you want to change the color, or background or what ever..