I have a navigation bar that is fluid on both desktop and mobile devices. However, the drop-down items widths don't resize based on the parent's width. I would like to hover over a drop-down item and it has the same width as the list item I hovered over. At the moment it has a fixed width but I can't seem to get it working by trying other options. I also cannot get the entire navigation bar to center, as at the moment it is stuck to the left. Thanks for the help!
Here's a codepen of the code: https://codepen.io/Macast/pen/rYQPNe
HTML:
<nav>
<div id="logo">
<img src="images/J.-Freeman-&-Son-Landscape-Logo-White.png">
</div>
<label for="drop" class="toggle">Menu</label>
<input type="checkbox" id="drop" />
<ul class="menu">
<li><a href="#">Home</a></li>
<li>
<!-- First Tier Drop Down -->
<label for="drop-1" class="toggle">Short +</label>
<a href="#">Short</a>
<input type="checkbox" id="drop-1" />
<ul>
<li><a href="#">History</a></li>
<li><a href="#">Our Services</a></li>
<li><a href="#">Our Aim</a></li>
</ul>
</li>
<li>
<!-- First Tier Drop Down -->
<label for="drop-2" class="toggle">Dropdown Even Longer +</label>
<a href="#">Dropdown Even Longer</a>
<input type="checkbox" id="drop-2" />
<ul>
<li><a href="#">Option</a></li>
<li><a href="#">Option</a></li>
<li><a href="#">Option</a></li>
<li>
<!-- Second Tier Drop Down -->
<label for="drop-3" class="toggle">More Options +</label>
<a href="#">More Options</a>
<input type="checkbox" id="drop-3" />
<ul>
<li><a href="#">Option</a></li>
<li><a href="#">Option</a></li>
<li><a href="#">Option</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">Option</a></li>
<li><a href="#">Option</a></li>
<li><a href="#">Option</a></li>
<li><a href="#">Option</a></li>
</ul>
</nav>
CSS:
.toggle,
[id^=drop] {
display: none;
}
/* Giving a background-color to the nav container. */
nav {
margin: 0;
padding: 0;
background-color: #254441;
}
#logo {
display: block;
text-align: center;
/*padding: 0 30px;*/
/*float: left;*/
/*font-size: 20px;*/
/*line-height: 60px; */
}
#logo img {
width: 30%;
}
/* Since we'll have the "ul li" "float:left"
* we need to add a clear after the container. */
nav:after {
content: "";
display: table;
clear: both;
}
/* Removing padding, margin and "list-style" from the "ul",
* and adding "position:reltive" */
nav ul {
/*float: right;*/
padding: 0;
margin: 0;
list-style: none;
position: relative;
}
/* Positioning the navigation items inline */
nav ul li {
margin: 0px;
display: inline-block;
float: left;
background-color: #254441;
text-align: center;
}
/* Styling the links */
nav a {
display: block;
padding: 14px 20px;
color: #FFF;
font-size: 17px;
text-decoration: none;
text-align: center;
}
nav ul li ul li:hover {
background: #000000;
}
/* Background color change on Hover */
nav a:hover {
background-color: #000000;
}
/* Hide Dropdowns by Default
* and giving it a position of absolute */
nav ul ul {
display: none;
position: absolute;
/* has to be the same number as the "line-height" of "nav a" */
top: 60px;
}
/* Display Dropdowns on Hover */
nav ul li:hover > ul {
display: inherit;
}
/* Fisrt Tier Dropdown */
nav ul ul li {
width: 170px;
float: none;
display: list-item;
position: relative;
text-align: center;
}
/* Second, Third and more Tiers
* We move the 2nd and 3rd etc tier dropdowns to the left
* by the amount of the width of the first tier.
*/
nav ul ul ul li {
position: relative;
top: -60px;
/* has to be the same number as the "width" of "nav ul ul li" */
left: 170px;
}
/* Change ' +' in order to change the Dropdown symbol */
li > a:after {
content: ' +';
}
li > a:only-child:after {
content: '';
}
/* Media Queries
--------------------------------------------- */
@media all and (max-width: 768px) {
#logo {
display: block;
padding: 0;
width: 100%;
text-align: center;
float: none;
}
#logo img {
width: 100%;
box-sizing: border-box;
padding: 20px;
}
nav {
margin: 0;
}
/* Hide the navigation menu by default */
/* Also hide the */
.toggle + a,
.menu {
display: none;
}
/* Stylinf the toggle lable */
.toggle {
display: block;
background-color: #254441;
padding: 14px 20px;
color: #FFF;
font-size: 17px;
text-decoration: none;
border: none;
text-align: center;
}
.toggle:hover {
background-color: #000000;
}
/* Display Dropdown when clicked on Parent Lable */
[id^=drop]:checked + ul {
display: block;
}
/* Change menu item's width to 100% */
nav ul li {
display: block;
width: 100%;
}
nav ul ul .toggle,
nav ul ul a {
padding: 0 40px;
}
nav ul ul ul a {
padding: 0 80px;
}
nav a:hover,
nav ul ul ul a {
background-color: #000000;
}
nav ul li ul li .toggle,
nav ul ul a,
nav ul ul ul a {
padding: 14px 20px;
color: #FFF;
font-size: 17px;
}
nav ul li ul li .toggle,
nav ul ul a {
background-color: #212121;
}
/* Hide Dropdowns by Default */
nav ul ul {
float: none;
position: static;
color: #ffffff;
/* has to be the same number as the "line-height" of "nav a" */
}
/* Hide menus on hover */
nav ul ul li:hover > ul,
nav ul li:hover > ul {
display: none;
}
/* Fisrt Tier Dropdown */
nav ul ul li {
display: block;
width: 100%;
}
nav ul ul ul li {
position: static;
/* has to be the same number as the "width" of "nav ul ul li" */
}
}
@media all and (max-width: 330px) {
nav ul li {
display: block;
width: 94%;
}
}
To adjust the dropdown menu size to the same size as the containing list-item, declare a left
and right
property value of 0
on the dropdown element in question (nav ul ul
), then remove the explicitly declared width
on the nested list items of the dropdown menu (nav ul ul li
).
Example:
nav ul ul {
display: none;
position: absolute;
top: 60px;
/* additional property values declared */
left: 0;
right: 0;
}
This works because the dropdown menus are already positioned absolute
and the containing parent element list item (nav ul li
) is already positioned relative
.
You can position absolute
elements relative to their parents if their parents are relative
.
So all we are doing here is defining the extent of the dropdown menu width to "stretch" from "left to right" of the parent's width.
Code Snippet Demonstration:
.toggle,
[id^=drop] {
display: none;
}
/* Giving a background-color to the nav container. */
nav {
margin: 0;
padding: 0;
background-color: #254441;
}
#logo {
display: block;
text-align: center;
/*padding: 0 30px;*/
/*float: left;*/
/*font-size: 20px;*/
/*line-height: 60px; */
}
#logo img {
width: 30%;
}
/* Since we'll have the "ul li" "float:left"
* we need to add a clear after the container. */
nav:after {
content: "";
display: table;
clear: both;
}
/* Removing padding, margin and "list-style" from the "ul",
* and adding "position:reltive" */
nav ul {
text-align: center;
padding: 0;
margin: 0;
list-style: none;
position: relative;
}
/* Positioning the navigation items inline */
nav ul li {
margin: 0px;
display: inline-block;
background-color: #254441;
text-align: center;
position: relative;
}
/* Styling the links */
nav a {
display: block;
padding: 14px 20px;
color: #FFF;
font-size: 17px;
text-decoration: none;
text-align: center;
}
nav ul li ul li:hover {
background: #000000;
}
/* Background color change on Hover */
nav a:hover {
background-color: #000000;
}
/* Hide Dropdowns by Default
* and giving it a position of absolute */
nav ul ul {
display: none;
position: absolute;
/* has to be the same number as the "line-height" of "nav a" */
top: 60px;
left: 0;
right: 0;
}
/* Display Dropdowns on Hover */
nav ul li:hover > ul {
display: inherit;
}
/* Fisrt Tier Dropdown */
nav ul ul li {
/*width: 170px;*/
float: none;
display: list-item;
position: relative;
text-align: center;
}
/* Second, Third and more Tiers
* We move the 2nd and 3rd etc tier dropdowns to the left
* by the amount of the width of the first tier.
*/
nav ul ul ul li {
position: relative;
top: -60px;
/* has to be the same number as the "width" of "nav ul ul li" */
left: 170px;
}
/* Change ' +' in order to change the Dropdown symbol */
li > a:after {
content: ' +';
}
li > a:only-child:after {
content: '';
}
/* Media Queries
--------------------------------------------- */
@media all and (max-width: 768px) {
#logo {
display: block;
padding: 0;
width: 100%;
text-align: center;
float: none;
}
#logo img {
width: 100%;
box-sizing: border-box;
padding: 20px;
}
nav {
margin: 0;
}
/* Hide the navigation menu by default */
/* Also hide the */
.toggle + a,
.menu {
display: none;
}
/* Stylinf the toggle lable */
.toggle {
display: block;
background-color: #254441;
padding: 14px 20px;
color: #FFF;
font-size: 17px;
text-decoration: none;
border: none;
text-align: center;
}
.toggle:hover {
background-color: #000000;
}
/* Display Dropdown when clicked on Parent Lable */
[id^=drop]:checked + ul {
display: block;
}
/* Change menu item's width to 100% */
nav ul li {
display: block;
width: 100%;
}
nav ul ul .toggle,
nav ul ul a {
padding: 0 40px;
}
nav ul ul ul a {
padding: 0 80px;
}
nav a:hover,
nav ul ul ul a {
background-color: #000000;
}
nav ul li ul li .toggle,
nav ul ul a,
nav ul ul ul a {
padding: 14px 20px;
color: #FFF;
font-size: 17px;
}
nav ul li ul li .toggle,
nav ul ul a {
background-color: #212121;
}
/* Hide Dropdowns by Default */
nav ul ul {
float: none;
position: static;
color: #ffffff;
/* has to be the same number as the "line-height" of "nav a" */
}
/* Hide menus on hover */
nav ul ul li:hover > ul,
nav ul li:hover > ul {
display: none;
}
/* Fisrt Tier Dropdown */
nav ul ul li {
display: block;
width: 100%;
}
nav ul ul ul li {
position: static;
/* has to be the same number as the "width" of "nav ul ul li" */
}
}
@media all and (max-width: 330px) {
nav ul li {
display: block;
width: 94%;
}
}
<nav>
<div id="logo">
<img src="images/J.-Freeman-&-Son-Landscape-Logo-White.png">
</div>
<label for="drop" class="toggle">Menu</label>
<input type="checkbox" id="drop" />
<ul class="menu">
<li><a href="#">Home</a></li>
<li>
<!-- First Tier Drop Down -->
<label for="drop-1" class="toggle">Short +</label>
<a href="#">Short</a>
<input type="checkbox" id="drop-1" />
<ul>
<li><a href="#">History</a></li>
<li><a href="#">Our Services</a></li>
<li><a href="#">Our Aim</a></li>
</ul>
</li>
<li>
<!-- First Tier Drop Down -->
<label for="drop-2" class="toggle">Dropdown Even Longer +</label>
<a href="#">Dropdown Even Longer</a>
<input type="checkbox" id="drop-2" />
<ul>
<li><a href="#">Option</a></li>
<li><a href="#">Option</a></li>
<li><a href="#">Option</a></li>
<li>
<!-- Second Tier Drop Down -->
<label for="drop-3" class="toggle">More Options +</label>
<a href="#">More Options</a>
<input type="checkbox" id="drop-3" />
<ul>
<li><a href="#">Option</a></li>
<li><a href="#">Option</a></li>
<li><a href="#">Option</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">Option</a></li>
<li><a href="#">Option</a></li>
<li><a href="#">Option</a></li>
<li><a href="#">Option</a></li>
</ul>
</nav>
In Addition:
You can horizontally center the navigation menu by removing the float
rule declared on nested list-items (nav ul li
), as this will negate any attempt to align content (unless you use flex-box
), then declare text-align: center
on the containing unordered list (.menu
), as demonstrated below:
nav ul {
text-align: center;
padding: 0;
margin: 0;
list-style: none;
position: relative;
}