How to make the <li> item width fit the text length? - css

How can I make the <li> item width fit the text length in Bootstrap 3? My menu item is shorter than the text which causes my class="active" to look ugly.
This is the navbar in which it occurs:
<div id="menu" class="col-md-1">
<ul class="nav nav-pills nav-stacked">
<li class="active">Startseite</li>
<li>Kontakt</li>
</ul>
</div>

make a .custom_li class and give
.custom_li{
display:inline-block;
}
EDIT
To force same size, i'll suggest using max-width and place it under some media-query
li{
display: inline-block;
max-width:50%; /* limit width */
word-break:break-all; /* wrap extended text*/
border:1px solid red /* demo */
}
demo here
some optional things
some optional things

When I tried display: inline-block; it removes the bullet.
Instead, I use float:left; to have them only as wide as text, while preserving the bullet. Optionally, add clear:both; to keep it as a vertical list with each item on a new line.
CSS
.my-list > li {
float: left;
clear: both; /* remove this if you want them flowing inline */
}
HTML
<ul class="my-list">
<li>First Item</li>
<li>Second Item</li>
<li>Third Item</li>
<li>Fourth Item</li>
</ul>

If the display: inline-block; or display: block; is messing up the alignment.
Then just use width: fit-content;

Prevent it becoming a block by adding display: inline-block; to the proper element.
Post more code and preferably CSS if you want details.

I got it to work with the following css:
ul {
margin: 0 auto;
width: fit-content;
}
li{
display:flex;
margin: 0.5rem auto;
}
Basically what I did was make the container width to fit content. Used the CSS hack to make sure it would center using the margin. In the li tag I wanted the contents to be centered so I set it that way

Related

CSS grid, how do I treat children as grid cells?

I have a menu structure
<ul class="menu">
<li>
menu item
<ul class="menu">
<li>menu item</li>
</ul>
</li>
</ul>
If I set the outer menu item display: grid by default the cells will be just the top 'li'. How can I flatten the structure making all the 'li' items grid cells?
You can declare intermediate elements as "not even there" with display: contents (see article on bitsofco.de) which visually flatten sublists because if child li and grandchild ul aren't grid items anymore, then text node and grand-grand-child li are now the grid items BUT it causes huge problems related to semantics and accessibility as it's implemented in browsers for now.
E.g. you shouldn't in the first place flatten visually something that is hierarchical in your HTML code.
CSS solution: codepen
.menu_outer {
display: grid;
max-width: 20rem;
border: 1px solid darkblue;
padding-left: 0;
}
.menu_outer > li,
.menu_outer .menu {
display: contents;
}
.menu > li {
background-color: lightblue;
}
/* styling */
li {
list-style-type: none;
}
<ul class="menu_outer">
<li>
menu item
<ul class="menu">
<li>menu item</li>
</ul>
</li>
</ul>
Support of display: contents is partial: Firefox (accessible in incoming versions), Chrome and Safari (buggy under the hood) but not Edge and lol#IE
How about this?
.menu li { display: grid; }

align taller block to the right of shorter block

How can I make this work as in the image below:
<ul style="width:16em;list-style:none;padding-left:0">
<li><label>name:</label><span>whatever</span></li>
<li><label>categories:</label>
<ul class="flat"><li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
</ul>
</li>
</ul>
.flat {list-style:none}
.flat li {display:inline; padding-left:0}
label {float:left;width:7em;}
I mean, I want the second line of li items left aligned by the first line of li items. "item 1" is fine, the others should align by it. (revised upon comments)
Remove width:11em;, they just don't fit in.
This is a definition list, so use the proper <DL> element (definition list) instead of a <UL>. Then, you can accomplish everything you would like to in two short lines of CSS.
http://jsfiddle.net/smclark89/tkUjc/
<dl>
<dt>name:</dt>
<dd>
<ul>
<li>Whatever</li>
</ul>
</dd>
<dt>categories:</dt>
<dd>
<ul>
<li><span>item 1</span></li>
<li><span>item 2</span></li>
<li><span>item 3</span></li>
<li><span>item 4</span></li>
</ul>
</dd>
dt { float:left; }
dd li { list-style-type:none; }
Your markup seems totally fine, and I'm not quite sure why there seems to be issues achieving what you want. It's pretty straightforward stuff unless I am missing something:
http://jsfiddle.net/ryanwheale/UhQ9W/9/
My solution positions the label and whatever is next to it right next to each other. Since your outer element is 16em, we make the width equal 16 (note, you could also use percentages):
label:first-child {
float: left;
width: 7em; /* magic number: 9 + 7 = 16 (7 / 16 = 43.75%) */
}
label:first-child + * {
float: left;
width: 9em; /* magic number: 9 + 7 = 16 (9 / 16 = 56.25%) */
}
Then, for the "flat" items, we simply float them next to each other and give them a width of 50%:
.flat li {
float: left;
width: 50%;
}
Note: if you want to add padding to anything, I suggest adding box-sizing: border-box; to anything which is being floated.
Also, floats might give you issues when things start to expand and wrap... so there is another solution with inline-block which will solve this. Let me know how this works and I can provide a better solution if you have issues with things not lining up properly once real content is in there.
Add padding-left: 7em; to .flat: fiddle
Or add float: left; width: 9em; padding: 0; to .flat: fiddle
Remove the float, the display:inline (unless you want them to display next to eachother) and just use text-align and then use list-style-position:inside; to fix the bullets:
<ul style="width:13em; border:1px">
<li><label style="text-align:left; width:7em">test</label>
<ul style="text-align:right;list-style-position:inside;">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
</ul>
</li>
</ul>
Also, you shouldn't use inline CSS (style attribute) that is bad practice.
Without display:inline jsFiddle
With display:inline jsFiddle
here is a way of doing it, in case you can restructure the html as well. See it on JSFiddle
<ul>
<li><label>name:</label>
<ul class="flat">
<li>whatever</li>
</ul></li>
<li><label>categories:</label>
<ul class="flat">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
</ul>
</li>
</ul>
ul {
list-style: none;
padding: 0;
}
label {
display: inline-block;
width: 4.5em;
}
.flat {
display: inline-block;
vertical-align: top;
width: 6em;
margin-bottom: .5em;
}
.flat li {
display: inline-block;
}
Additional styles are need to make this work. Switching to floats and using percentages for the widths makes it possible to aligned the label and content on the right properly.
Here's the updated styles
.flat {
list-style:none;
float: left;
width: 64%;
padding: 0;
margin-left: -0.75em;
overflow: hidden;
}
.flat li {
float: left;
width: 38%;
padding-left: 0.75em;
}
label {
float:left;
width:35%;
}
http://jsfiddle.net/QhSC9/
If you are able to update the markup, I'd recommend you look into dl.
#smclark89: agree, I'd say a <dl> seems more appropriate here too. The cleanest I can come up with is this jsfiddle
Slight modifications to your CSS file:
notes:
-using a clear after every odd <li> sets the beginning of the next <li>to the far end of the next line.
-adding float:left; to .flat sets the first <li> inline with the label.
CSS
.flat {list-style:none;float:left;}
.flat li {display:inline; padding-left:0;}
label {float:left;width:7em;}
ul {padding:0px;}
li {float:left;}
ul .flat li:nth-child(odd) {clear:both;}
EXAMPLE
http://jsfiddle.net/UhQ9W/19/
I have set the list items floating and clearing the floated elements every third one in order to create the layout you have attached above.
Keep in mind that this demo is width agnostic. All the tricks lays in this line of code
.flat li:nth-of-type(3n) {
background:#ff0000;
clear:left;
}
http://jsfiddle.net/QhSC9/
Use overflow: hidden on the ul
http://jsfiddle.net/HerrSerker/UhQ9W/8/
.flat {
list-style:none;
overflow:hidden;
padding:0
}
The overflow: hidden changes the block formatting context of the .flat element as described here
Check this out. I know that this isn't the proper way to do it but based on the other answers you cannot change major elements/tags also styles.
Fiddle
CSS
label {
clear:left;
float:left;
width:7em;
height:22px;
}
I just added height:22px and clear:left to create your desired output.

How do I get rid of white spaces between spans without manipulating the HTML?

This is my code for a drop down menu. I pulled the code from a tutorial that produced this: http://www.webdesigndev.com/wp-content/uploads/2009/07/fancydropdown.html
But instead of text navigation I have images as you can see in the CSS attached to the span id's. With this code, I'm given the dropdown menus for each span correctly, I just can't get rid of the white space between them.
I know a new line in HTML between divs/spans create whitespaces, but I want to know a way to rid of them in CSS.
<div id="menu">
<ul class="tabs">
<li class="hasmore"><span id="bird"></span>
<ul class="dropdown">
<li>Menu item 1</li>
<li>Menu item 2</li>
<li class="last">Menu item 6</li>
</ul></li><li class="hasmore"><span id="wild"></span>
<ul class="dropdown">
<li>Menu item 1</li>
<li>Menu item 2</li>
<li class="last">Menu item 6</li>
</ul>
</li>
</ul>
</div>
This is some CSS that applies:
#menu ul
{
margin: 0 auto;
}
ul.tabs
{
display: table;
margin: 0;
padding: 0;
list-style: none;
position: relative;
}
ul.tabs li
{
margin: 0;
padding: 0;
list-style: none;
display: table-cell;
float: left;
position: relative;
}
ul.tabs a
{
position: relative;
display: block;
}
#bird {
background-image:url(images/birdingnav.png);
width:80px;
height: 20px;
text-indent:-9009px;
font-size: 0px;
border: 0;
}
#wild {
background-image:url(images/wildernessnav.png);
width:119px;
height: 20px;
text-indent:-9009px;
font-size:0px;
border: 0;
}
What do I need to do to this code in CSS to get rid of the white space that appears between my span images?
This is a common problem. More common with inline-block than inline, as inline usually means it's in the flow of text, where white space is relevant. With inline-block, people are using it for layout, and the white space becomes a problem.
There is a new CSS property specifically trying to deal with this issue - white-space:collapse; and white-space-collapse: discard;, but sadly it isn't supported by any of the major browsers yet. So that's not an option.
In the absence of that, the solutions to this tend to be a bit hacky.
One common solution is to set the container element to font-size:0;. This effectively renders the white space irrelevant; it's still there, but doesn't take up any space. The downside here is that you then need to set the font-size back again for the internal elements. If you're using a dynamic layout, with em based font-sizes, this can be tricky to handle.
Switching the layout to a float:left layout will remove this issue, but introduces other problems. Personally I've never liked working with float, but it might be the answer for some cases.
You could also use Javascript to remove the spaces, but that really is a hack.
Other than that, re-arranging the HTML code to remove the spaces is the most likely best solution. I know it's not the one you wanted though.
Try setting display: inline-block on the image elements. Spans are supposed to be inline, so the best solution would be to not use spans at all, but since you said don't change the html...
See how there's no spaces between the images in this fiddle: http://jsfiddle.net/rVTZc/
From this style:
#menu ul li a:hover span {
background: url("images/topselectionright.png") repeat scroll right top transparent;
}
remove
right top
If I understand you correctly, maybe ul { font-size:0 } would help?

Gap/margin issue with Firefox/IE

I wish to have a bunch of rectangles containing text, sitting next to each other, and wrapping to the next line where necessary. I have a maximum width for each rectangle, and any text that doesn't fit inside the rectangle should be hidden.
Here is the code I have written
HTML
<div id="outer">
<ul id="list">
<li>The name of soemthing</li>
<li>Something else</li>
<li>Something else 2</li>
<li>Something else 3 </li>
<li>Something else 4</li>
</ul>
</div>
CSS
#outer {
background-color: #0000ff;
width: 500px;
}
#list {
margin: 0px;
padding: 0px;
list-style-type: none;
}
#list li {
display: inline-block;
max-width: 100px;
overflow: hidden;
white-space:nowrap;
height: 24px;
padding: 0px;
background: #ff0000;
margin: 0px;
}
It works perfectly in Chrome.
In Firefox/IE, there is a small vertical gap/margin added between each rectangle.
I can make the gap go away by removing the 'overflow: hidden' on the LI elements, but this ofcourse allows rectangles to grow freely - which is what im trying to avoid.
Anybody know why this is happening?
Try putting all the <li> tags on the same line. The browsers are rendering the line break as white space.
<div id="outer">
<ul id="list">
<li>The name of soemthing</li><li>Something else</li><li>Something else 2</li><li>Something else 3</li><li>Something else 4</li>
</ul>
</div>
Can you use floated block elements instead or do they have to be inline-block elements?
Here's your example, and here's the code working with shrink-wrapped floating elements.
You simply need to add vertical-align: top to #list li: http://jsfiddle.net/thirtydot/PF4fW/
Every time you use display: inline-block, you should consider setting vertical-align.
Look at "Series A" here to compare the different possible common values.

Why is this :after element being affected by line breaks?

I have a simple menu coded up like this
<ul id="main-menu" class="container">
<li>About Us</li>
<li>Home</li>
<li>Villas & Yachts</li>
<li>Islands</li>
<li>Gallery</li>
<li>Blog</li>
<li>Get In Touch</li>
</ul>
which looks like this
The little dots in-between each menu item are created using the :after pseudo element. Eveything is working fine, but I also need sub menus, which will be nested lists.
The problem is, when i add a line break to the menu like this
<ul id="main-menu" class="container">
<li>About Us</li>
<li>Home</li>
<li>Villas & Yachts
<!-- LINE BREAK -->
</li>
<li>Islands
<!-- LINE BREAK -->
</li>
<li>Gallery</li>
<li>Blog</li>
<li>Get In Touch</li>
</ul>
I get this result in Safari & Chrome (But not Firefox)...
It seems to me as though webkit is treating the whitespace as 'pre'. The CSS for the :after element looks like this
ul#main-menu li:after
{
content: "\00b7";
width: 61px;
float: right;
text-align: center;
border: rgba(225,225,225,0.25) 1px solid;
}
I've also tried setting white-space: normal/nowrap on the ul, li and :after elements which doesn't affect anything.
Can anyone see where I'm going wrong, or is this a problem with Webkit/Firefox?
UPDATE
I've created a demo at http://jsfiddle.net/zmVbH/
The issue is that the line break is white space which makes the floated content drop a line. The issue can be reproduced by adding a single space between the </a> and </li>. Try making the inserted content display:inline-block instead of floated.
ul#main-menu li:after
{
content: "\00b7";
width: 61px;
display:inline-block;
text-align: center;
border: rgba(0,0,0,0.25) 1px solid;
white-space: normal;
}
Updated JSFiddle.
UPDATE BY OP
Yup, inline-block fixes this, but it's not quite that simple since inline-block has some patchy browser support.
ul#main-menu li:after
{
content: "\00b7";
width: 61px;
float: right;
text-align: center;
border: rgba(225,225,225,0.25) 1px solid;
/* FIX */
display:-moz-inline-stack; /* For older versions of Firefox */
display:inline-block; /* Anything that supports inline-block */
/* IE FIX */
zoom:1;
*display:inline;
}

Resources