I've been working on a navigation bar. I've got it styled the way I like, but for some reason am having issues getting submenus to work.
The code looks like:
<div id="head">
<input id="toggle" type="checkbox">
<label for="toggle" class="icon">
<div><!-- --></div>
<div><!-- --></div>
<div><!-- --></div>
</label>
<div id="nav">
<div>
<ul>
<li class="page_item page-item-8">Home</li>
<li class="page_item page-item-10 page_item_has_children">About
<ul class="children">
<li class="page_item page-item-22 page_item_has_children">Once More
<ul class="children">
<li class="page_item page-item-23 page_item_has_children">Another Sub Page
<ul class="children">
<li class="page_item page-item-25">Final Link</li>
<li class="page_item page-item-24">Something Else</li>
</ul>
</li>
</ul>
</li>
<li class="page_item page-item-21">Another Page</li>
<li class="page_item page-item-20">Subpage</li>
</ul>
</li>
<li class="page_item page-item-13 current_page_item">Shop</li>
<li class="page_item page-item-9">FAQ</li>
<li class="page_item page-item-11">Contact</li>
</ul>
</div>
</div>
</div>
The CSS looks like:
/* Toggle */
#toggle {
display: none;
}
/* Nav */
#nav li.current_page_item a {
background: #d2b48c;
border-radius: 40px;
color: #260f03;
}
#nav li a {
border-bottom: 1px solid transparent;
border-top: 1px solid transparent;
color: #fff;
display: inline-block;
font-family: 'Lato', sans-serif;
font-size: 14px;
letter-spacing: 4px;
margin: 20px;
padding: 10px 10px 10px 15px;
text-decoration: none;
text-transform: uppercase;
}
/* Media */
#media screen and (max-width: 600px) {
/* Icon */
.icon {
background: #260f03;
margin: 0 auto;
padding: 20px 20px 30px;
position: absolute;
width: 100%;
z-index: 500;
}
.icon div {
background: #d2b48c;
border-radius: 3px;
height: 2px;
margin: 10px auto 0;
position: relative;
transition: all 0.3s ease-in-out;
width: 3em;
}
/* Toggle */
#toggle:checked + .icon div:nth-child(1) {
margin-top: 25px;
transform: rotate(-45deg);
}
#toggle:checked + .icon div:nth-child(2) {
margin-top: -2px;
transform: rotate(45deg);
}
#toggle:checked + .icon div:nth-child(3) {
opacity: 0;
transform: rotate(45deg);
}
#toggle:checked + .icon + #nav {
top: 0;
transform: scale(1);
}
/* Nav */
#nav {
background: rgba(38, 15, 3, 0.95);
bottom: 0;
height: 100%;
left: 0;
overflow: hidden;
position: fixed;
right: 0;
top: -100%;
transform: scale(0);
transition: all 0.3s ease-in-out;
z-index: 200;
}
#nav div {
height: 100%;
overflow: hidden;
overflow-y: auto;
position: relative;
}
#nav ul {
padding-top: 90px;
text-align: center;
}
#nav li a:before {
background: #fff;
content: '';
height: 0;
left: -0.5em;
position: absolute;
transition: all 0.2s ease-in-out;
width: 0.25em;
}
#nav li a:hover:before {
height: 100%;
}
}
#media screen and (min-width: 601px) {
/* HIDE the dropdown */
#nav li ul { display: none; }
/* DISPLAY the dropdown */
#nav li:hover > ul {
display: block;
position: absolute;
}
/* Nav */
#nav ul {
background: #260f03;
font-size: 0;
text-align: center;
}
#nav li {
display: inline;
}
#nav li a:hover {
border-bottom: 1px solid #d2b48c;
border-top: 1px solid #d2b48c;
}
}
JS Fiddle (with submenus):https://jsfiddle.net/2v8zhL3e/1/
JS Fiddle (without submenus): https://jsfiddle.net/b0mj7gp4/
I've found a bunch of tutorials on how to do this, but they are all using a float on the li.
I did have a go at it...
I hid the dropdown: #nav li ul { display: none; }
Then I showed it on hover:
#nav li:hover > ul {
display: block;
position: absolute;
}
Which kind of works...but the links show to the left of the main navigation item, I'd like to just tweak this so the links are stacked and show centered under their corresponding header.
I feel like I'm close, can anyone point me in the right direction?
Thanks,
Josh
You can add display: flex to the li:hover ul, then make the flex-direction: column and make the non-hover event position: absolute, left: 0. This creates an issue with the ul child element floating to the far left. So to fix this issue, you need to style its parent to have a relative position. The following should do the trick.
#nav li {
position: relative;
}
#nav li ul {
left: 0;
position: absolute;
}
#nav li:hover > ul {
display: flex;
flex-direction: column;
}
You haven't position: relative in li.
And, it would be better to use position: absolute without hover, in default.
#nav li {
position: relative;
}
#nav li > ul {
position: absolute;
display: none;
}
#nav li:hover > ul {
display: block;
}
Related
The ::after selector will inserts something after the content, is this targetable with the preceding selector ~?
For example, HTML:
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
::after
</ul>
CSS:
ul::after {
content: '';
display: block;
height: 50px;
width: 100%;
background: red;
}
ul li:hover ~ ::after {
background: blue;
}
CODE EXAMPLE
Below you are able to find a working version of what I am after. However I did this with the "sub-menu-bar" div included. Now it seems the ::after pseudo element is positioned at the exact location in the DOM inspector. It would be nice if it could be done without the div.
The reason why the submenu bar is on the UL is because I don't want the bar to move when switching between two items which have a submenu.
ul, li
{
list-style: none;
padding: 0;
margin: 0;
}
a
{
cursor: pointer;
display: block;
color: inherit;
text-decoration: none;
text-transform: uppercase;
}
a > *
{
user-select: none;
}
ul.menu
{
position: relative;
display: flex;
width: 100%;
flex-wrap: wrap;
justify-content: center;
background: #FFF;
}
ul.menu > li.menu-item > a
{
padding: 0px 10px;
height: 50px;
overflow: hidden;
transition: height 0.3s;
}
ul.menu > li.menu-item > ul.sub-menu
{
position: absolute;
right: 0px;
bottom: 0px;
left: 0px;
display: flex;
width: 100%;
height: 0px;
align-items: center;
justify-content: center;
transition: height 0.4s;
color: #FFF;
}
ul.menu > li.menu-item > ul.sub-menu > li.menu-item
{
overflow: hidden;
}
ul.menu > li.menu-item > ul.sub-menu > li.menu-item > a
{
padding: 0px 10px;
transform: translateY(100%);
opacity: 1;
transition-property: transform, opacity;
transition-timing-function: cubic-bezier(0.52, 0.16, 0.24, 1);
transition-delay: 0s;
transition-duration: 0.2s;
}
ul.menu > div.sub-menu-bar
{
content: '';
display: block;
width: 100%;
height: 2px;
flex-basis: 100%;
transition: height 0.4s;
background: #000;
}
ul.menu > li.menu-item-has-children:hover > ul.sub-menu
{
height: 50px;
}
ul.menu > li.menu-item-has-children:hover > ul.sub-menu > li.menu-item > a
{
transform: translateY(0%);
opacity: 1;
transition-delay: 0.2s;
}
ul.menu > li.menu-item-has-children:hover ~ div.sub-menu-bar
{
height: 50px;
}
<ul class="menu">
<li class="menu-item"><a>Item #1</a></li>
<li class="menu-item menu-item-has-children">
<a>Item #2</a>
<ul class="sub-menu">
<li class="menu-item"><a>Subitem #2.1</a></li>
<li class="menu-item"><a>Subitem #2.2</a></li>
</ul>
</li>
<li class="menu-item menu-item-has-children">
<a>Item #3</a>
<ul class="sub-menu">
<li class="menu-item"><a>Subitem #3.1</a></li>
<li class="menu-item"><a>Subitem #3.2</a></li>
</ul>
</li>
<li class="menu-item"><a>Item #4</a></li>
<li class="menu-item"><a>Item #5</a></li>
<div class="sub-menu-bar"></div> <!-- Can we avoid this with ::after pseudo element? -->
</ul>
<p>Content below the navigation.</p>
When I hover on a specific list item (li) targeted with a class name.
I like the background color of the ::after element to change, which is
located on ul::after.
Yes, you can achieve this effect using pointer-events.
The way to do it is to apply to both the <ul> and the <li> the style:
ul, li {
pointer-events: none;
}
and apply to the hoverable <li> the style:
li.hover-over-this {
pointer-events: auto;
}
Working Example:
ul {
position: relative;
margin-left: 0;
padding-left: 0;
font-weight: bold;
background-color: white;
cursor: pointer;
}
li {
width: 50%;
padding: 6px;
color: rgb(255, 255, 255);
line-height: 24px;
background-color: red;
list-style: none;
}
ul:hover::after {
content: 'Hovering!';
position: absolute;
top: 0;
right: 0;
width: 100px;
height: 100px;
line-height: 100px;
color: rgb(255, 0, 0);
text-align: center;
background-color: rgb(255, 255, 0);
}
ul, li {
pointer-events: none;
}
li.hover-over-this {
pointer-events: auto;
}
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li class="hover-over-this">Hover Over This</li>
<li>5</li>
</ul>
Further Reading:
https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events
This does not require a ~. the ~ selector selects all siblings after the element. The pseudo element ::after is inside the li.
li:hover ~ li would for example target all li elements after the li that is hovered.
For what you want to do, use:
ul li:hover:after {
background: blue;
}
Edit:
Sorry, I didn't see the after applied to ul. This is not possible with pure CSS as there is no "parent" selector. You can only use ul:hover:after (or anything higher in hierarchy than ul) to target the after element.
What you could do:
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
<li></li>
</ul>
li:hover ~ li:last-of-type {
//something
}
I am trying to modify a CSS only menu that implements a horizontal flyout. The original code does it on hover. I am trying to achieve the same thing on touch/tap - that is: tap once to show it, tap again to close it.
Is this possible using pure CSS ?
I've inserted the code below, but please refer to the codepen - it renders better. The challenge I am facing is right now I have to keep it pressed for the menu to show - how do I toggle without using javascript?
The codepen: http://codepen.io/pliablepixels/pen/WwPgwg
/*
Forked from http://codepen.io/IanLunn/pen/NPapxy */
/*
sass flyout.scss >flyout.css (sudo gem install sass)
or sass flyout.scss --style compressed >flyout.min.css
"IL" logo Copyright (c) Ian Lunn Design Limited 2015
Modified by pliable pixels
*/
.drawer {
position: absolute;
z-index: 10;
top: 0;
left: 0;
/*height: 100%;*/
padding: .4em 0;
background: #7D294E;
color: white;
text-align: center;
/* Remove 4px gap between <li> */
font-size: 0;
}
.drawer li {
pointer-events: none;
position: relative;
display: inline-block;
vertical-align: middle;
list-style: none;
transform: translateZ(0);
}
.drawer a {
pointer-events: auto;
position: relative;
display: block;
min-width: 5em;
margin-bottom: .4em;
padding: .4em;
line-height: 100%;
/* Reset font-size */
font-size: 16px;
text-decoration: none;
color: white;
transition: background 0.2s;
}
.drawer a:active, .drawer a:focus {
background: #B44659;
}
.drawer i {
display: block;
margin-bottom: .2em;
font-size: 2em;
}
.drawer span {
font-size: .625em;
font-family: sans-serif;
text-transform: uppercase;
}
.drawer li:active ul {
/* Open the fly-out menu */
transform: translateX(0);
background: #B44659;
/* Enable this if you wish to replicate hoverIntent */
}
.drawer > li {
display: block;
/* Fly out menus */
}
.drawer > li > a {
background: #7D294E;
}
.drawer > li:active, .drawer > li:focus {
z-index: 100;
}
.drawer > li:active, .drawer > li:focus a {
background: #B44659;
}
.drawer > li a:active {
background: #F56356;
}
.drawer > li ul {
position: absolute;
/* Stack below the top level */
z-index: -1;
top: 0;
left: 100%;
/* height: 100%;*/
width: auto;
white-space: nowrap;
/* Close the menus */
transform: translateX(-100%);
background: #B44659;
transition: 0.2s transform;
}
<ul class="drawer">
<li>
<a href="">
<span>Info</span>
</a>
<ul>
<li>
<a href="http://www.google.com">
<span>Item 1</span>
</a>
</li>
<li>
<a href="http://www.google.com" >
<span>Item 2</span>
</a>
</li>
<li>
<a href="http://www.google.com">
<span>Item 3</span>
</a>
</li>
</ul>
</li>
</ul>
Check out the following code, that should work for you.
Show
<div id="something">Bingo!</div>
CSS:
#something {
display: none;
}
#something:target {
display: block;
}
Heres a codepen: http://codepen.io/anon/pen/EKreRy
The following code work for me
<!DOCTYPE html>
<html>
<body>
<a href="#something" id='target'>Show</a>
<div id="something">Bingo!hide</div>
<style>
#something {display: none;}
#something:target {display: block;}
#target:target #something{display: none;}
</style>
</div>
</body>
hey guys I am having a few issues with my menu, theres a weird padding that pushes my menu to the right a few pixels but I managed to fix it on the main parents, originally they were both pushing out the same amount.
Pic
and heres a better view
I am running through my css and adding padding-left:0px;
Heres my code if anyone can assist me.
<div class="css_menu_two_line">
<ul class="two_line_menu">
<li>Menu 1</li><li>
Menu 2</li><li class="current">Menu 3 SHOW
<ul>
<li>Submenu 3-1</li>
<li>Submenu 3-2</li>
<li>Submenu 3-3</li>
<li>Submenu 3-4</li>
<li>Submenu 3-5</li>
</ul>
</li><li>Menu 4</li><li>Menu 5</li>
</ul>
</div>
css:
.css_menu_two_line {
width:100%;
overflow:hidden;
}
.two_line_menu {
padding-left: 0;
position: relative;
margin-bottom: 40px;
background:#77f url('img_bg.gif') repeat-x;
}
.two_line_menu a {
display: block;
color: #fff;
text-decoration: none;
padding:10px;
}
.two_line_menu li:hover a {
color: #fff;
background: #aaf;
}
.current a {
color: #fff;
background: #aaf;
}
.two_line_menu li { display: inline-block; }
.two_line_menu li ul { display: block;
position: absolute;
left: 0;
width: 100%;
background: #aaf;
top: 38px; }
.two_line_menu li:hover ul {
display: block;
position: absolute;
left: 0;
width: 100%;
background: #aaf;
top: 38px;
}
.two_line_menu li ul li:hover a { color: #000; }
fiddle: http://jsfiddle.net/uf2cnakc/
You need to take away the padding from .two_line_menu li ul. To do this we can add the following style padding: 0;.
A lot of HTML elements have default styles, so beware of this.
Your CSS for this class should now look something like this:
.two_line_menu li ul {
display: block;
position: absolute;
left: 0;
width: 100%;
background: #aaf;
top: 38px;
padding: 0; /* Just added */
}
Demo Here
Your CSS contained display:inline which has block child element and position absolute as well. Try this CSS property.
.two_line_menu li { display: block; float:left; }
.two_line_menu li ul{ position:absolute; left:0; padding:0; width:100%; background: #aaf; top:38px; }
.two_line_menu li ul li{ float:left;}
Right now the parent menu has an opacity shift on hover, this is being transferred to the sub menu (current & previous) as well. I want the sub menu to have a clear background so that the opacity band of the parent is the only thing that is visible. Is there a way to use an li class for the submenu that makes it exempt from the li class that is governing the parent. I've been trying different things but can't seem to make it work properly.
Demo
HTML
<div>
<ul id="mainmenu">
<li class="liHome">
<a class="maintextcolour" href="#item-x1y1" id="Home" rel=
"none">INFO</a>
</li>
<li class="liServices">
<a class="maintextcolour" href="#item-x1y2" id="Services" rel=
"SubMenuY2">EXHIBITIONS</a>
<ul class="submenu" id="SubMenuY2">
<li class="sub1">
<a class="maintextcolour" href="#">CURRENT</a>
</li>
<li class="sub1">
<a class="maintextcolour" href="#">PREVIOUS</a>
</li>
</ul>
</li>
<li id="liEnvironment">
<a class="maintextcolour" href="#item-x1y3" id="Environment"
rel="none">CV</a>
</li>
<li id="liCareer">
<a class="maintextcolour" href="#item-x1y4" id="Career" rel=
"none">NEWS</a>
</li>
<li id="liContact">
<a class="maintextcolour" href="#item-x1y5" id="Contact" rel=
"none">MORE</a>
</li>
</ul>
</div>
CSS:
#charset UTF-8;
/* CSS Document */
body {
background-color: #666;
background-size: 100%;
background-repeat: no-repeat;
}
#mainmenu {
margin: 0;
padding: 0;
list-style-type: none;
position: relative;
}
#mainmenu li {
clear: left;
position: relative;
}
#mainmenu a {
display: block;
overflow: hidden;
float: left;
width: 100%;
position: relative;
opacity: 1;
-webkit-transition: all .4s ease-in-out;
padding-left: 20px;
}
#mainmenu li:hover a {
background-position: 0 0;
background-color: clear;
background-color: rgba(255,255,255,0.5);
width: 100%;
opacity: 0;
-webkit-transition: none;
}
#mainmenu li.active a {
background-position: 0 0;
background-color: clear;
width: 100%;
}
.submenu {
list-style-type: none;
float: left;
display: none;
position: absolute;
left: 135px;
top: 0;
width: auto;
}
#mainmenu li a:hover + .submenu,.submenu:hover {
display: block;
}
.submenu li {
display: inline-block;
clear: none !important;
}
.submenu li a {
float: right;
margin-left: 10px;
}
.maintextcolour {
font-family: Arial, Helvetica, sans-serif;
font-size: 24px;
color: #FFF;
text-decoration: none;
}
.maintextcolour:hover {
font-family: Arial, Helvetica, sans-serif;
font-size: 24px;
color: #0FF;
text-decoration: none;
}
.headertext {
font-family: Arial, Helvetica, sans-serif;
font-size: 14px;
color: #FFF;
text-decoration: none;
}
Here is the updated Fiddle link. I have just added color to the following css:
#mainmenu > li:hover > a {
background-position: 0 0;
background-color:clear;
color:#0fffff;
background-color:rgba(255,255,255,0.5);
width:100%;
\
opacity: 0;
-webkit-transition: none;
}
Hope you want this.
I have a menu that has an image for its title, and changes images when it isn't hovered anymore. However, I want it to keep the same image while I'm hovering over the submenu that opens up beneath it, rather than revert back to its unhovered state. Can this be done with HTML/CSS?
Here's the CSS Code:
ul#nav {
margin: 0 0 0 0px;
}
ul.drop a {
display:block;
color: transparent;
}
ul.drop, ul.drop li, ul.drop ul {
list-style: none;
margin: 0;
padding: 0;
border: 0px solid #fff;
background: transparent;
color: transparent
}
ul.drop {
position: relative;
z-index: 597;
float: left;
}
ul.drop li {
float: left;
line-height: 1.3em;
vertical-align: middle;
zoom: 1;
}
ul.drop li.hover, ul.drop li:hover {
position: relative;
z-index: 599;
cursor: default;
background: transparent;
}
ul.drop ul {
display:none;
position: absolute;
top: 100%;
left: 0;
z-index: 598;
width: 100%;
background: transparent;
border: 0px solid #fff;
}
ul.drop:hover ul {
display:block;
}
ul.drop ul li {
float: none;
}
ul.drop ul ul {
top: -2px;
left: 100%;
}
ul.drop li:hover > ul {
visibility: visible
}
And here's the HTML
<ul class='drop' id='nav' style='padding-bottom:8px;'>
<li><img alt='Share' border='0' onmouseout='this.src='normal.png'' onmouseover='this.src='hovered.png'' src='normal.png' style='padding:0px; margin:0px;'/>
<ul>
<li style='background-color:#202020;width:160px;padding:0px; margin:0px;'>
<!-- Share Buttons -->
</li>
</ul>
</li>
</ul>
Mmm.. i have a special trick for you, i hope you like it. I make HTML like this :
<ul id="nav" class="drop">
<li class="icon1">HOVER ME
<ul>
<li> HIDDEN MENU </li>
</ul>
</li>
<li class="icon1">HOVER ME 2
<ul>
<li> HIDDEN MENU </li>
</ul>
</li>
</ul>
and special css trick like this:
...
ul.drop li.icon1{
background: url(YOUR_IMAGE) no-repeat left top;
width: 140px;
}
ul.drop li.icon1:hover{
background: url(YOUR_IMAGE_HOVER) no-repeat left top;
}
...
Here the demo : http://jsfiddle.net/CsV7a/