Adjust <li> width to its content's width - html

I have following CSS code:
nav li {
display: inline-block;
text-align: center;
}
nav li a {
display: block;
width: 100%;
height: 100%;
}
nav li :hover {
background-color: var(--main-color);
color: white;
}
Which makes elements in my navbar look like this:
But there's actually 4 items, not 6. I'll add some padding in <li>:
But when I hover over the first item, I have this ugly white space from both sides of it. Margin does exactly the same thing. Let's remove margin/padding and set <li> width manually to 120px:
First two items are now formatted somehow acceptably, but items a and b take visually far too much space than necessary. What I aim for would be something like this (made in image editor):
In other words, I'd like my <li> elements to have their width adjusted to their content with extra padding, while child <a> elements still take up 100% of <li> space. Any ideas?

Edit
I've updated updated the JSFiddle that you've posted.
You need to change your a element to not have display:block (should be inline instead). Also, you don't need to specify width and height of 100%. Just make your padding: 15px for the a, and you'll have equal, well-spaced hover padding.
I adapted your code above and put it into a codepen, see here:
http://codepen.io/himmel/pen/BNJZoL
Here is how I changed your CSS:
nav li {
display: inline-block;
text-align: center;
}
nav li a {
padding-left: 15px; ** add padding to both sides
padding-right: 15px;
display: inline;
}
nav li :hover {
background-color: brown;
color: white;
}

Try using table layout
body {margin:0}
nav ul {
padding:0;
margin:0;
width: 100%;
display: table;
}
nav li {
display: table-cell;
text-align: center;
}
nav li a {
background: #fafafa;
display: block;
width: 100%;
box-sizing: border-box;
padding: 10px;/*or whatever*/
}
nav li :hover {
background-color: brown;
color: white;
}
<nav>
<ul>
<li>Item</li>
<li>Very long item</li>
<li>a</li>
<li>b</li>
</ul>
</nav>

Related

Header with three elements, one left, one center, one right

I'm just starting to develop in HTML and CSS, and despite reading about the box model I am still having trouble with some of the basics of positioning.
I want to create a header navigation bar with three elements - one to the left of the page, one to the right, and one in the center. I want these elements to be inline with each other.
At the moment, they are represented in HTML like so
<body>
<div class="header">
<ul class="child">
<li id="lodestone">The Lodestone</li>
<li id="mogstation">The Mog Station</li>
<li id="user">User Account</li>
</ul>
</div>
I have then attempted to align them using the 'text-align' property in CSS.
.header {
background-color: #ffd9e7;
border: black;
display: block;
box-sizing: border-box;
}
.header ul {
display: inline-block;
}
.header > ul > li {
display: inline-block;
}
#lodestone {
text-align: left;
}
#user {
text-align: right;
}
#mogstation {
text-align: center;
}
However, instead of the expected result it produces this.
The three items are aligned, next to each other, on the left.
Can anyone recommend what css property I should be using to solve this problem? My research has shown there are ways of using float, but other people recommend against it, and when I try I get issues with the text overflowing off the page.
If you give the ul and lis a width and (100 ul /30 for li s for example) then they should display correctly
.header {
background-color: #ffd9e7;
border: black;
display: block;
box-sizing: border-box;
}
.header ul {
display: inline-block;
width:100%;
}
.header > ul > li {
display: inline-block;
position:relative;
vertical-align:top;
width:30%;
}
#lodestone {
text-align: left;
}
#user {
text-align: right;
}
#mogstation {
text-align: center;
}
<div class="header">
<ul class="child">
<li id="lodestone">The Lodestone</li>
<li id="mogstation">The Mog Station</li>
<li id="user">User Account</li>
</ul>
</div>
I added vertical-align:top; but it's excess to requirements, you could take that out..
Fiddle
Hope this helps
Take a look at CSS Flexbox for a different approach to layout your elements
header{
display: flex;
justify-content: space-around;
}
<header>
<div>A</div>
<div>B</div>
<div>C</div>
</header>
Why not make the li elements a third of the width?
First make the ul 100% width, you'll also need to ensure there's no padding on the right of the ul as it tends to be automatically added by browsers:
.header ul {
display: inline-block;
padding: 0;
width: 100%;
}
Then have each li 33%
.header > ul > li {
display: inline-block;
width: 33%;
}
Style the rest as required

Horizontal menu not stretching to full width on hover in certain browsers

I have a horizontal menu that is made up of a series of ul's and li's. The submenus look great so I don't need to do anything with those. The primary ul looks great until you hover over the far right li.
When doing that, it looks good in Safari but the hover comes about 2 pixels short of the background on the ul in Firefox and IE and even more in Chrome. I have tried adjusting the padding to make it look good in Firefox and IE but then you still have the same issue in Chrome and in Safari, that far right li breaks down to a new line. Of course, adjusting it to look good in Chrome makes all the other browsers break to a new line. This site is using Wordpress which creates the menu dynamically so I can only change the CSS. Here is the basic idea for the code:
<html>
<head>
<style type="text/css">
#header {
margin: 0 auto;
width: 980px;
}
ul li {
font-size: 13px;
line-height: 21px;
}
#header .main-nav #menu-main-navigation {
background: #169BAC;
width: 100%
}
#header .main-nav > div ul {
width: 100%;
list-style: none;
float: left;
margin: 0;
padding: 0;
vertical-align: baseline;
}
#header .main-nav > div ul li ul{
top: 43px;
}
#header .main-nav .menu-div>ul>li {
padding: 5px 14px;
float: left;
border-right: solid 1px #54AEC2;
}
#header .main-nav .menu-div ul li:hover {
background: #2A588D;
}
#header .main-nav .menu-div>ul>li:first-child {
padding-top: 9px;
height: 28px;
}
#header .main-nav .menu-div>ul>li:last-child {
padding: 5px 26px;
border-right: none;
}
#header .main-nav .menu-div>ul>li a{
line-height: 15px;
text-decoration: none;
color: #FFF;
padding: 0px 13px;
text-align: center;
display: inline-block;
}
</style>
<head>
<body>
<header id="header">
<nav class="main-nav">
<div class="menu-div">
<ul id="menu-main-navigation" class="menu">
<li id="menu-item-275">Home</li>
<li id="menu-item-310">For New<br />Patients</li>
<li id="menu-item-376">Cleanings &<br />Prevention</li>
<li id="menu-item-381">General<br />Dentistry</li>
<li id="menu-item-453">Restore Your<br />Smile</li>
<li id="menu-item-462">Dental Anxiety &<br />Sedation Options</li>
<li id="menu-item-463">Dentistry For<br />Kids</li>
<li id="menu-item-464">Insurance &<br />Payment Options</li>
</ul>
</div>
</nav>
</header>
</body>
You can see the site at http://riverbend.caswellwebcreations.com.
Thank you for any help that you can give me on this.
The width of the li elements is being defined by their padding and the font-size (and padding) of the a elements inside them. The font propertys are not uniform between browsers, some browsers put text bigger or smaller than others. That seems to be the problem.
If you want to stretch the li elements "cross-browser" you should define the width of the li elements via css like this:
#menu-item-275{
width: 64px;
}
#menu-item-310{
width: 77px;
}
#menu-item-376{
width: 96px;
}
#menu-item-381{
width: 82px;
}
#menu-item-453{
width: 104px;
}
#menu-item-462{
width: 131px;
}
#menu-item-463{
width: 105px;
}
#menu-item-464{
width: 132px;
}
If you sum the width of each li item (plus padding and border) you get the width of the menu container: 980px. And the browsers will take that width to render the li's.
I hope this works!
UPDATE
Just found another (and more easy) solution!: https://stackoverflow.com/a/14361778/3762078
#header .main-nav .menu-div>ul>li:last-child {
padding: 5px 20px;
border-right: none;
float: none; /* ADD THIS */
overflow: hidden; /* AND THIS */
}
'float: none'. Forces last li element to be as wide as it can (the
default block element's behavior).
'overflow: hidden'. Prevents the last li element to stretch to ul's full width.
Although this doesn't prevent the width changes to all li elements on every browser, hence making the last li's width be thinner or wider (and sometimes expanding that li's height), is a nice solution.

How to make horizontal dropdown content area stick around?

I'm trying to create a horizontal menu with dropdown content boxes. I'm using the same method I'd use for a vertical menu with children that expand on :hover of their parent. It works fine, except that I can't seem to find a method that forces the dropdown content to stick around once the cursor moves from the parent element itself. You can see what I mean at http://asubtleweb.com/clients/kingswood/ ... The dropdown content isn't clickable because it contracts as soon as the mouse moves from its parent element.
Here's my CSS:
#header_menu nav { display: table; width: 30%; float: left; text-align: center; }
#header_menu nav ul, nav#mainmenu ul { list-style-type: none; }
#header_menu nav li { display: inline; margin-right: 2.5%; }
#header_menu nav a, nav#mainmenu a { font: 400 1.25em 'Oswald', sans-serif; color: black; text-transform: uppercase; }
#header_menu li .navhover { display: block; width: 100%; position: absolute; top: 50px; left: 0px; background-color: black; background-color: rgba(0,0,0,0.6); color: white; text-align: left; max-height: 0px; overflow: hidden; transition: all 1s linear; -wekbkit-transition: all 1s linear; }
#header_menu li:hover .navhover { max-height: 300px; min-height: 300px; }
#header_menu li .navhover article { margin: 20px; }
#header_menu li .navhover.news article { width: 30%; margin: 2.5% 0% 2.5% 2.5%; float: left; }
...and my HTML:
<div id="header_menu">
<nav>
<ul>
<li id="mission">
Mission
<div class="navhover">
[[CONTENT]]
</div>
</li>
<li id="news">
News
<div class="navhover news">
[[CONTENT]]
</div>
</li>
<li id="reserve">Reserve</li>
</ul>
</nav>
</div>
I've also tried making each parent element its own absolutely positioned block that expands on :hover, with no luck. I didn't expect to have so much trouble with the concept, but it's stumping me.
Simply add z-index: 1; to #header_menu li .navhover
As Francesco Frapporti pointed out:
Simply add z-index: 1; to #header_menu li .navhover
Edit: There is an error on your website moveWindow is not defined see body element
Simply add this to your css....
#header_menu li .navhover:hover{min-height:0;max-height:0;}
then it should work just fine!
The problem is that the parent element you are using with :hover doesn't actually "touch" the child element. So there is space between the parent and child element and that causes the parent element to lose focus when moving the mouse toward the child.
Choose whichever method you like to eliminate the gap between parent and child. Make the parent larger, move the child closer to the parent, etc.

White-space: nowrap makes elements to be outside of window

I am trying to have an UL on the right of a SPAN (http://jsfiddle.net/Shg9L/24/).
<div>
<span>Categories</span>
<ul>
<li>Book</li>
<li>Computer</li>
</ul>
</div>
When the window is resized down the LIs should get stacked but not under the SPAN.
The problem is when I resize the window some of the LI items on the right becomes hidden.
I think it is because of "white-space: nowrap" but without it I'm not able to make it work.
Can this be solved?
Display your unordered list as a block and hide the overflow. It will then take up all the available width. The list items will stack neatly in line with the edge of the unordered list when there isn't enough room:
div ul {
list-style: none;
padding: 0;
margin: 0;
display: block;
overflow:hidden;
}
The white-space:nowrap on your container <div> isn't needed as far as I can see. You can remove it.
JSFiddle
http://jsfiddle.net/Shg9L/29/
removed a coupple of things and added position:absolute; and inline:display-block to some elements
div {background-color:orange;}
div span {
background-color: #E0E0E0;
margin-right: 8px;
margin-bottom: 8px;
padding: 8px;
}
div ul {
position:absolute;
top:0px;left:100px;
list-style: none;
padding: 0;
margin: 0;
display: inline-block;
}
div ul li {
background-color: #F0F0F0;
margin-right: 8px;
margin-bottom: 8px;
padding: 8px;
display:inline-block;
}

Why isn't the text in this list floating correctly?

I have a list. Each item in the list contains an icon span and text span like so:
<ul id="features">
<li>
<span class="icon"></span>
<span class="text">blah blah blahlrceoahuoa steohuasnoet huntaoheu saoetnhu saoetuhsaoe tuhsaoetnhu saoehtuasoetnhu saou</span>
</li>
</ul>
Using the following CSS
#features { list-style-type: none; }
#features li { overflow: auto;}
#features li span { float: left; }
#features .icon { background: #000; height: 55px; width: 55px; display: inline-block;}
#features .text { margin-left: 24px; display: inline-block; }
I believe this code should produce text which floats next to the icon, and automatically adjusts its width accordingly. However this isn't the case see jsfiddle.
Why isn't the text floating next to the icon?
width: auto will instruct the text span to assume as much width as it requires, based on its content. This is what causes the entire span to wrap when that space is not available.
Ah, trying to make fixed and fluid width live together in harmony... an old problem.
Here's an updated fiddle with the solution: http://jsfiddle.net/dwZaN/11/
#features { list-style-type: none; margin-top: 24px; margin-right: 24px; }
#features li { margin-bottom: 24px; overflow: auto; width: 100%; }
#features li span { }
#features .icon { background: #000; height: 55px; width: 55px; float: left; }
#features .text { padding-left: 75px; display: block; }
Basically...
Float your fixed-width icon
Don't float your fluid-width element, but give it padding-left with enough room to account for your icon and some buffer room (this automatically gives it 100% and subtracts whatever padding-left you specify)
Both elements should be block-level. You don't actually need to specify anything for the icon, but your text span needs to be display: block (or you can just switch to DIV's which are already block-level)
Also, since you specify a right margin in your parent UL, adding width: 100% makes it expand beyond the browser window and creates a horizontal scrollbar. Simply remove it.
You should be using a CSS background in the inner element and floating the LI. You do not need a separate element for the icon.
#features li { float left }
#features li span {
display:block;
background-image: url(...);
background-repeat:no-repeat;
height:25px;
padding-left:30px;
}
See my tutorial: I love lists.
If you want to use a font instead of an image, you can use position:relative, on your LI and add:
li:before {
content: "\25A0"; <--- this is a UTF-8 square
left: -1em;
position: absolute;
top: 0.1em;
}
(adjust your spacing values accordingly)