You find plenty of tutorials on menu bars in HTML, but for this specific (though IMHO generic) case, I haven't found any decent solution:
# THE MENU ITEMS SHOULD BE JUSTIFIED JUST AS PLAIN TEXT WOULD BE #
# ^ ^ #
There's an varying number of text-only menu items and the page layout is fluid.
The first menu item should be left-aligned, the last menu item should be right-aligned.
The remaining items should be spread optimally on the menu bar.
The number is varying,so there's no chance to pre-calculate the optimal widths.
Note that a TABLE won't work here as well:
If you center all TDs, the first and the last item aren’t aligned correctly.
If you left-align and right-align the first resp. the last items, the spacing will be sub-optimal.
Isn’t it strange that there is no obvious way to implement this in a clean way by using HTML and CSS?
The simplest thing to do is to is to force the line to break by inserting an element at the end of the line that will occupy more than the left available space and then hiding it. I've accomplished this quite easily with a simple span element like so:
#menu {
text-align: justify;
}
#menu * {
display: inline;
}
#menu li {
display: inline-block;
}
#menu span {
display: inline-block;
position: relative;
width: 100%;
height: 0;
}
<div id="menu">
<ul>
<li>Menu item 1</li>
<li>Menu item 3</li>
<li>Menu item 2</li>
</ul>
<span></span>
</div>
All the junk inside the #menu span selector is (as far as I've found) required to please most browsers. It should force the width of the span element to 100%, which should cause a line break since it is considered an inline element due to the display: inline-block rule. inline-block also makes the span possible to block-level style rules like width which causes the element to not fit in line with the menu and thus the menu to line-break.
You of course need to adjust the width of the span to your use case and design, but I hope you get the general idea and can adapt it.
Modern Approach - Flexboxes!
Now that CSS3 flexboxes have better browser support, some of us can finally start using them. Just add additional vendor prefixes for more browser coverage.
In this instance, you would just set the parent element's display to flex and then change the justify-content property to either space-between or space-around in order to add space between or around the children flexbox items.
Using justify-content: space-between - (example here):
ul {
list-style: none;
padding: 0;
margin: 0;
}
.menu {
display: flex;
justify-content: space-between;
}
<ul class="menu">
<li>Item One</li>
<li>Item Two</li>
<li>Item Three Longer</li>
<li>Item Four</li>
</ul>
Using justify-content: space-around - (example here):
ul {
list-style: none;
padding: 0;
margin: 0;
}
.menu {
display: flex;
justify-content: space-around;
}
<ul class="menu">
<li>Item One</li>
<li>Item Two</li>
<li>Item Three Longer</li>
<li>Item Four</li>
</ul>
Ok, this solution doesn't work on IE6/7, because of the lack of support of :before/:after, but:
ul {
text-align: justify;
list-style: none;
list-style-image: none;
margin: 0;
padding: 0;
}
ul:after {
content: "";
margin-left: 100%;
}
li {
display: inline;
}
a {
display: inline-block;
}
<div id="menu">
<ul>
<li>Menu item 1</li>
<li>Menu item 2</li>
<li>Menu item 3</li>
<li>Menu item 4</li>
<li>Menu item 5</li>
</ul>
</div>
The reason why I have the a tag as an inline-block is because I don't want the words inside to be justified as well, and I don't want to use non-breaking spaces either.
Got a solution. Works in FF, IE6, IE7, Webkit, etc.
Make sure you don't put any whitespace before closing the span.inner. IE6 will break.
You can optionally give .outer a width
.outer {
text-align: justify;
}
.outer span.finish {
display: inline-block;
width: 100%;
}
.outer span.inner {
display: inline-block;
white-space: nowrap;
}
<div class="outer">
<span class="inner">THE MENU ITEMS</span>
<span class="inner">SHOULD BE</span>
<span class="inner">JUSTIFIED</span>
<span class="inner">JUST AS</span>
<span class="inner">PLAIN TEXT</span>
<span class="inner">WOULD BE</span>
<span class="finish"></span>
</div>
Works with Opera , Firefox, Chrome and IE
ul {
display: table;
margin: 1em auto 0;
padding: 0;
text-align: center;
width: 90%;
}
li {
display: table-cell;
border: 1px solid black;
padding: 0 5px;
}
yet another solution. I had no option to tackle the html like adding distinguished class etc., so I found a pure css way.
Works in Chrome, Firefox, Safari..don't know about IE.
Test: http://jsfiddle.net/c2crP/1
ul {
margin: 0;
padding: 0;
list-style: none;
width: 200px;
text-align: justify;
list-style-type: none;
}
ul > li {
display: inline;
text-align: justify;
}
/* declaration below will add a whitespace after every li. This is for one line codes where no whitespace (of breaks) are present and the browser wouldn't know where to make a break. */
ul > li:after {
content: ' ';
display: inline;
}
/* notice the 'inline-block'! Otherwise won't work for webkit which puts after pseudo el inside of it's parent instead of after thus shifting also the parent on next line! */
ul > li:last-child:after {
display: inline-block;
margin-left: 100%;
content: ' ';
}
<ul>
<li>home</li>
<li>exposities</li>
<li>werk</li>
<li>statement</li>
<li>contact</li>
</ul>
Make it a <p> with text-align: justify ?
Update: Nevermind. That doesn't work at all as I'd thought.
Update 2: Doesn't work in any browsers other than IE right now, but CSS3 has support for this in the form of text-align-last
For Gecko-based browsers, I came up with this solution. This solution doesn't work with WebKit browsers, though (e.g. Chromium, Midori, Epiphany), they still show trailing space after the last item.
I put the menu bar in a justified paragraph. Problem is that the last line of a justified paragraph won't be rendered justified, for obvious reasons. Therefore I add a wide invisible element (e.g. an img) which warrants that the paragraph is at least two lines long.
Now the menu bar is justified by the same algorithm the browser uses for justifying plain text.
Code:
<div style="width:500px; background:#eee;">
<p style="text-align:justify">
THE MENU ITEMS
SHOULD BE
JUSTIFIED
JUST AS
PLAIN TEXT
WOULD BE
<img src="/Content/Img/stackoverflow-logo-250.png" width="400" height="0"/>
</p>
<p>There's an varying number of text-only menu items and the page layout is fluid.</p>
<p>The first menu item should be left-aligned, the last menu item should be right-aligned. The remaining items should be spread optimal on the menu bar.</p>
<p>The number is varying,so there's no chance to pre-calculate the optimal widths.</p>
<p>Note that a TABLE won't work here as well:</p>
<ul>
<li>If you center all TDs, the first and the last item aren't aligned correctly.</li>
<li>If you left-align and right-align the first resp. the last items, the spacing will be sub-optimal.</li>
</ul>
</div>
Remark: Do you notice I cheated? To add the space filler element, I have to make some guess about the width of the menu bar. So this solution is not completely down to the rules.
Text is only justified if the sentence naturally causes a line break. So all you need to do is naturally force a line break, and hide whats on the second line:
CSS:
ul {
text-align: justify;
width: 400px;
margin: 0;
padding: 0;
height: 1.2em;
/* forces the height of the ul to one line */
overflow: hidden;
/* enforces the single line height */
list-style-type: none;
background-color: yellow;
}
ul li {
display: inline;
}
ul li.break {
margin-left: 100%;
/* use e.g. 1000px if your ul has no width */
}
HTML:
<ul>
<li>The</li>
<li>quick</li>
<li>brown</li>
<li>fox</li>
<li class="break"> </li>
</ul>
The li.break element must be on the same line as the last menu item and must contain some content (in this case a non breaking space), otherwise in some browsers, if it's not on the same line then you'll see some small extra space on the end of your line, and if it contains no content then it's ignored and the line is not justified.
Tested in IE7, IE8, IE9, Chrome, Firefox 4.
if to go with javascript that is possible (this script is base on mootools)
<script type="text/javascript">//<![CDATA[
window.addEvent('load', function(){
var mncontainer = $('main-menu');
var mncw = mncontainer.getSize().size.x;
var mnul = mncontainer.getFirst();//UL
var mnuw = mnul.getSize().size.x;
var wdif = mncw - mnuw;
var list = mnul.getChildren(); //get all list items
//get the remained width (which can be positive or negative)
//and devided by number of list item and also take out the precision
var liwd = Math.floor(wdif/list.length);
var selw, mwd=mncw, tliw=0;
list.each(function(el){
var elw = el.getSize().size.x;
if(elw < mwd){ mwd = elw; selw = el;}
el.setStyle('width', elw+liwd);
tliw += el.getSize().size.x;
});
var rwidth = mncw-tliw;//get the remain width and set it to item which has smallest width
if(rwidth>0){
elw = selw.getSize().size.x;
selw.setStyle('width', elw+rwidth);
}
});
//]]>
</script>
and the css
<style type="text/css">
#main-menu{
padding-top:41px;
width:100%;
overflow:hidden;
position:relative;
}
ul.menu_tab{
padding-top:1px;
height:38px;
clear:left;
float:left;
list-style:none;
margin:0;
padding:0;
position:relative;
left:50%;
text-align:center;
}
ul.menu_tab li{
display:block;
float:left;
list-style:none;
margin:0;
padding:0;
position:relative;
right:50%;
}
ul.menu_tab li.item7{
margin-right:0;
}
ul.menu_tab li a, ul.menu_tab li a:visited{
display:block;
color:#006A71;
font-weight:700;
text-decoration:none;
padding:0 0 0 10px;
}
ul.menu_tab li a span{
display:block;
padding:12px 10px 8px 0;
}
ul.menu_tab li.active a, ul.menu_tab li a:hover{
background:url("../images/bg-menutab.gif") repeat-x left top;
color:#999999;
}
ul.menu_tab li.active a span,ul.menu_tab li.active a.visited span, ul.menu_tab li a:hover span{
background:url("../images/bg-menutab.gif") repeat-x right top;
color:#999999;
}
</style>
and the last html
<div id="main-menu">
<ul class="menu_tab">
<li class="item1"><span>Home</span></li>
<li class="item2"><span>The Project</span></li>
<li class="item3"><span>About Grants</span></li>
<li class="item4"><span>Partners</span></li>
<li class="item5"><span>Resources</span></li>
<li class="item6"><span>News</span></li>
<li class="item7"><span>Contact</span></li>
</ul>
</div>
Simpler markup, tested in Opera, FF, Chrome, IE7, IE8:
<div class="nav">
nav item1
nav item2
nav item3
nav item4
nav item5
nav item6
<span class="empty"></span>
</div>
and css:
.nav {
width: 500px;
height: 1em;
line-height: 1em;
text-align: justify;
overflow: hidden;
border: 1px dotted gray;
}
.nav_item {
display: inline-block;
}
.empty {
display: inline-block;
width: 100%;
height: 0;
}
Live example.
try this
*{
padding: 0;
margin: 0;
box-sizing: border-box;
}
ul {
list-style: none;
display: flex;
align-items: center;
justify-content: space-evenly;
}
<ul>
<li>List item One</li>
<li>List item Two</li>
<li>List item Three </li>
<li>List item Four</li>
</ul>
This can be achieved perfectly by some careful measurements and the last-child selector.
ul li {
margin-right:20px;
}
ul li:last-child {
margin-right:0;
}
I know the original question specified HTML + CSS, but it didn't specifically say no javascript ;)
Trying to keep the css and markup as clean as possible, and as semantically meaningful as possible to (using a UL for the menu) I came up with this suggestion. Probably not ideal, but it may be a good starting point:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Kind-of-justified horizontal menu</title>
<style type="text/css">
ul {
list-style: none;
margin: 0;
padding: 0;
width: 100%;
}
ul li {
display: block;
float: left;
text-align: center;
}
</style>
<script type="text/javascript">
setMenu = function() {
var items = document.getElementById("nav").getElementsByTagName("li");
var newwidth = 100 / items.length;
for(var i = 0; i < items.length; i++) {
items[i].style.width = newwidth + "%";
}
}
</script>
</head>
<body>
<ul id="nav">
<li>first item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>last item</li>
</ul>
<script type="text/javascript">
setMenu();
</script>
</body>
</html>
Related
You find plenty of tutorials on menu bars in HTML, but for this specific (though IMHO generic) case, I haven't found any decent solution:
# THE MENU ITEMS SHOULD BE JUSTIFIED JUST AS PLAIN TEXT WOULD BE #
# ^ ^ #
There's an varying number of text-only menu items and the page layout is fluid.
The first menu item should be left-aligned, the last menu item should be right-aligned.
The remaining items should be spread optimally on the menu bar.
The number is varying,so there's no chance to pre-calculate the optimal widths.
Note that a TABLE won't work here as well:
If you center all TDs, the first and the last item aren’t aligned correctly.
If you left-align and right-align the first resp. the last items, the spacing will be sub-optimal.
Isn’t it strange that there is no obvious way to implement this in a clean way by using HTML and CSS?
The simplest thing to do is to is to force the line to break by inserting an element at the end of the line that will occupy more than the left available space and then hiding it. I've accomplished this quite easily with a simple span element like so:
#menu {
text-align: justify;
}
#menu * {
display: inline;
}
#menu li {
display: inline-block;
}
#menu span {
display: inline-block;
position: relative;
width: 100%;
height: 0;
}
<div id="menu">
<ul>
<li>Menu item 1</li>
<li>Menu item 3</li>
<li>Menu item 2</li>
</ul>
<span></span>
</div>
All the junk inside the #menu span selector is (as far as I've found) required to please most browsers. It should force the width of the span element to 100%, which should cause a line break since it is considered an inline element due to the display: inline-block rule. inline-block also makes the span possible to block-level style rules like width which causes the element to not fit in line with the menu and thus the menu to line-break.
You of course need to adjust the width of the span to your use case and design, but I hope you get the general idea and can adapt it.
Modern Approach - Flexboxes!
Now that CSS3 flexboxes have better browser support, some of us can finally start using them. Just add additional vendor prefixes for more browser coverage.
In this instance, you would just set the parent element's display to flex and then change the justify-content property to either space-between or space-around in order to add space between or around the children flexbox items.
Using justify-content: space-between - (example here):
ul {
list-style: none;
padding: 0;
margin: 0;
}
.menu {
display: flex;
justify-content: space-between;
}
<ul class="menu">
<li>Item One</li>
<li>Item Two</li>
<li>Item Three Longer</li>
<li>Item Four</li>
</ul>
Using justify-content: space-around - (example here):
ul {
list-style: none;
padding: 0;
margin: 0;
}
.menu {
display: flex;
justify-content: space-around;
}
<ul class="menu">
<li>Item One</li>
<li>Item Two</li>
<li>Item Three Longer</li>
<li>Item Four</li>
</ul>
Ok, this solution doesn't work on IE6/7, because of the lack of support of :before/:after, but:
ul {
text-align: justify;
list-style: none;
list-style-image: none;
margin: 0;
padding: 0;
}
ul:after {
content: "";
margin-left: 100%;
}
li {
display: inline;
}
a {
display: inline-block;
}
<div id="menu">
<ul>
<li>Menu item 1</li>
<li>Menu item 2</li>
<li>Menu item 3</li>
<li>Menu item 4</li>
<li>Menu item 5</li>
</ul>
</div>
The reason why I have the a tag as an inline-block is because I don't want the words inside to be justified as well, and I don't want to use non-breaking spaces either.
Got a solution. Works in FF, IE6, IE7, Webkit, etc.
Make sure you don't put any whitespace before closing the span.inner. IE6 will break.
You can optionally give .outer a width
.outer {
text-align: justify;
}
.outer span.finish {
display: inline-block;
width: 100%;
}
.outer span.inner {
display: inline-block;
white-space: nowrap;
}
<div class="outer">
<span class="inner">THE MENU ITEMS</span>
<span class="inner">SHOULD BE</span>
<span class="inner">JUSTIFIED</span>
<span class="inner">JUST AS</span>
<span class="inner">PLAIN TEXT</span>
<span class="inner">WOULD BE</span>
<span class="finish"></span>
</div>
Works with Opera , Firefox, Chrome and IE
ul {
display: table;
margin: 1em auto 0;
padding: 0;
text-align: center;
width: 90%;
}
li {
display: table-cell;
border: 1px solid black;
padding: 0 5px;
}
yet another solution. I had no option to tackle the html like adding distinguished class etc., so I found a pure css way.
Works in Chrome, Firefox, Safari..don't know about IE.
Test: http://jsfiddle.net/c2crP/1
ul {
margin: 0;
padding: 0;
list-style: none;
width: 200px;
text-align: justify;
list-style-type: none;
}
ul > li {
display: inline;
text-align: justify;
}
/* declaration below will add a whitespace after every li. This is for one line codes where no whitespace (of breaks) are present and the browser wouldn't know where to make a break. */
ul > li:after {
content: ' ';
display: inline;
}
/* notice the 'inline-block'! Otherwise won't work for webkit which puts after pseudo el inside of it's parent instead of after thus shifting also the parent on next line! */
ul > li:last-child:after {
display: inline-block;
margin-left: 100%;
content: ' ';
}
<ul>
<li>home</li>
<li>exposities</li>
<li>werk</li>
<li>statement</li>
<li>contact</li>
</ul>
Make it a <p> with text-align: justify ?
Update: Nevermind. That doesn't work at all as I'd thought.
Update 2: Doesn't work in any browsers other than IE right now, but CSS3 has support for this in the form of text-align-last
For Gecko-based browsers, I came up with this solution. This solution doesn't work with WebKit browsers, though (e.g. Chromium, Midori, Epiphany), they still show trailing space after the last item.
I put the menu bar in a justified paragraph. Problem is that the last line of a justified paragraph won't be rendered justified, for obvious reasons. Therefore I add a wide invisible element (e.g. an img) which warrants that the paragraph is at least two lines long.
Now the menu bar is justified by the same algorithm the browser uses for justifying plain text.
Code:
<div style="width:500px; background:#eee;">
<p style="text-align:justify">
THE MENU ITEMS
SHOULD BE
JUSTIFIED
JUST AS
PLAIN TEXT
WOULD BE
<img src="/Content/Img/stackoverflow-logo-250.png" width="400" height="0"/>
</p>
<p>There's an varying number of text-only menu items and the page layout is fluid.</p>
<p>The first menu item should be left-aligned, the last menu item should be right-aligned. The remaining items should be spread optimal on the menu bar.</p>
<p>The number is varying,so there's no chance to pre-calculate the optimal widths.</p>
<p>Note that a TABLE won't work here as well:</p>
<ul>
<li>If you center all TDs, the first and the last item aren't aligned correctly.</li>
<li>If you left-align and right-align the first resp. the last items, the spacing will be sub-optimal.</li>
</ul>
</div>
Remark: Do you notice I cheated? To add the space filler element, I have to make some guess about the width of the menu bar. So this solution is not completely down to the rules.
Text is only justified if the sentence naturally causes a line break. So all you need to do is naturally force a line break, and hide whats on the second line:
CSS:
ul {
text-align: justify;
width: 400px;
margin: 0;
padding: 0;
height: 1.2em;
/* forces the height of the ul to one line */
overflow: hidden;
/* enforces the single line height */
list-style-type: none;
background-color: yellow;
}
ul li {
display: inline;
}
ul li.break {
margin-left: 100%;
/* use e.g. 1000px if your ul has no width */
}
HTML:
<ul>
<li>The</li>
<li>quick</li>
<li>brown</li>
<li>fox</li>
<li class="break"> </li>
</ul>
The li.break element must be on the same line as the last menu item and must contain some content (in this case a non breaking space), otherwise in some browsers, if it's not on the same line then you'll see some small extra space on the end of your line, and if it contains no content then it's ignored and the line is not justified.
Tested in IE7, IE8, IE9, Chrome, Firefox 4.
if to go with javascript that is possible (this script is base on mootools)
<script type="text/javascript">//<![CDATA[
window.addEvent('load', function(){
var mncontainer = $('main-menu');
var mncw = mncontainer.getSize().size.x;
var mnul = mncontainer.getFirst();//UL
var mnuw = mnul.getSize().size.x;
var wdif = mncw - mnuw;
var list = mnul.getChildren(); //get all list items
//get the remained width (which can be positive or negative)
//and devided by number of list item and also take out the precision
var liwd = Math.floor(wdif/list.length);
var selw, mwd=mncw, tliw=0;
list.each(function(el){
var elw = el.getSize().size.x;
if(elw < mwd){ mwd = elw; selw = el;}
el.setStyle('width', elw+liwd);
tliw += el.getSize().size.x;
});
var rwidth = mncw-tliw;//get the remain width and set it to item which has smallest width
if(rwidth>0){
elw = selw.getSize().size.x;
selw.setStyle('width', elw+rwidth);
}
});
//]]>
</script>
and the css
<style type="text/css">
#main-menu{
padding-top:41px;
width:100%;
overflow:hidden;
position:relative;
}
ul.menu_tab{
padding-top:1px;
height:38px;
clear:left;
float:left;
list-style:none;
margin:0;
padding:0;
position:relative;
left:50%;
text-align:center;
}
ul.menu_tab li{
display:block;
float:left;
list-style:none;
margin:0;
padding:0;
position:relative;
right:50%;
}
ul.menu_tab li.item7{
margin-right:0;
}
ul.menu_tab li a, ul.menu_tab li a:visited{
display:block;
color:#006A71;
font-weight:700;
text-decoration:none;
padding:0 0 0 10px;
}
ul.menu_tab li a span{
display:block;
padding:12px 10px 8px 0;
}
ul.menu_tab li.active a, ul.menu_tab li a:hover{
background:url("../images/bg-menutab.gif") repeat-x left top;
color:#999999;
}
ul.menu_tab li.active a span,ul.menu_tab li.active a.visited span, ul.menu_tab li a:hover span{
background:url("../images/bg-menutab.gif") repeat-x right top;
color:#999999;
}
</style>
and the last html
<div id="main-menu">
<ul class="menu_tab">
<li class="item1"><span>Home</span></li>
<li class="item2"><span>The Project</span></li>
<li class="item3"><span>About Grants</span></li>
<li class="item4"><span>Partners</span></li>
<li class="item5"><span>Resources</span></li>
<li class="item6"><span>News</span></li>
<li class="item7"><span>Contact</span></li>
</ul>
</div>
Simpler markup, tested in Opera, FF, Chrome, IE7, IE8:
<div class="nav">
nav item1
nav item2
nav item3
nav item4
nav item5
nav item6
<span class="empty"></span>
</div>
and css:
.nav {
width: 500px;
height: 1em;
line-height: 1em;
text-align: justify;
overflow: hidden;
border: 1px dotted gray;
}
.nav_item {
display: inline-block;
}
.empty {
display: inline-block;
width: 100%;
height: 0;
}
Live example.
try this
*{
padding: 0;
margin: 0;
box-sizing: border-box;
}
ul {
list-style: none;
display: flex;
align-items: center;
justify-content: space-evenly;
}
<ul>
<li>List item One</li>
<li>List item Two</li>
<li>List item Three </li>
<li>List item Four</li>
</ul>
This can be achieved perfectly by some careful measurements and the last-child selector.
ul li {
margin-right:20px;
}
ul li:last-child {
margin-right:0;
}
I know the original question specified HTML + CSS, but it didn't specifically say no javascript ;)
Trying to keep the css and markup as clean as possible, and as semantically meaningful as possible to (using a UL for the menu) I came up with this suggestion. Probably not ideal, but it may be a good starting point:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Kind-of-justified horizontal menu</title>
<style type="text/css">
ul {
list-style: none;
margin: 0;
padding: 0;
width: 100%;
}
ul li {
display: block;
float: left;
text-align: center;
}
</style>
<script type="text/javascript">
setMenu = function() {
var items = document.getElementById("nav").getElementsByTagName("li");
var newwidth = 100 / items.length;
for(var i = 0; i < items.length; i++) {
items[i].style.width = newwidth + "%";
}
}
</script>
</head>
<body>
<ul id="nav">
<li>first item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>last item</li>
</ul>
<script type="text/javascript">
setMenu();
</script>
</body>
</html>
I was wondering how to remove the vertical space between a unordered list and div. I know it's possible with using - margins, but I have a feeling that isn't really a clean method.
This is my code:
.menu {
list-style-type: none;
background-color: #660066;
}
.menu li {
display: inline;
padding-left: 40px;
padding-right: 40px;
}
.div {
width: 100%;
height: 500px;
background-color: #660066;
}
<nav>
<ul class="menu">
<li>Check 1</li>
<li>Check 2</li>
<li>Check 3</li>
<li>Check 4</li>
</ul>
</nav>
<article class="div">
In this case your ul simply has standard margin on top and bottom. margin: 0; solves this.
jsfiddle
ul{
margin: 0;
}
Always do a reset like shown below for both UL and LI. That way spaces will only be present when you apply them by yourself.
ol, ul {
margin: 0;
padding: 0;
}
Click here to see why it is important to set a reset.
You have to set up your position since you are going to move in close proximity to the original location your position will be relative from there you move can move it up or down , it should look like this
.div
position:relative;
bottom:30px;
I have following html for menu
<ul>
<li id="btnHome">Link One</li>
<li id="btnAbout">Link Two</li>
<li id="btnContact">Link Three</li>
<li id="btnLinks">Link Four</li>
</ul>
and following is my css for it
ul {
margin: 0;
padding: 0;
}
ul li {
list-style-type: none;
}
#nav {
background: #999;
padding: 2%;
}
#nav ul li {
float: left;
margin-right: 2%;
}
I use above for IE6 and 7 in order to display links in a single row. float: left displays menu items in a row but it also changes the style for #nav div and menu items do not appear inside #nav div anymore.
How can I fix this issue for IE6 and 7?
Note: I am using display: inline-block for modern browser and this works fine.
You could use a CSS declaration like zoom: 1; for #nav element to trigger hasLayout on IE 6-7.
#nav {
background: #999;
padding: 2%;
*zoom: 1;
}
Note: The star/asterisk prefix is a CSS hack for targeting IE 6/7.
Other options
Using overflow: hidden; for the #nav element to create a new block formatting context.
Creating an element with clear: both; CSS declaration as the last child of the #nav element.
You might want to take a look at Nicolas Gallagher's micro clearfix hack.
Not sure without the rest of the document but you could try adding a
<div style="clear:both;"></div>
right after your close your ul element, that should grow the size of your containing #nav to the place your floated content occupies in it.
I'm not sure how to build a horizontal list that looks like this:
Here are the rules:
There is an unlimited number of items in the list.
Each item should be on a single line and not wrap to a 2nd line.
Multiple items can be on a single line if there is space for them to fit
If multiple items are on a single line, they should be separated by a divider
The divider looks like a bullet, but it could be an image
Need it to work in modern browsers as well as IE8+
The thing I'm not sure how to do is to make the bullets appear only between items, and not also before or after each row of items.
For those of you who don't have to worry about IE8, this is as simple as:
ul li { list-style: none; display: inline; }
ul li:after { content: " \00b7"; }
ul li:last-child:after { content: none; }
This solution matches all of OP's requirements, except IE8 compatibility (that was 2013).
Simple markup. No JavaScript. No :last-child
Link to CodePen
ul {
display: inline-block;
padding: 0;
margin: .5rem;
text-align: center;
background-color: #fff;
}
li { display: inline; }
li a { white-space: nowrap; }
li:after {
content: " ";
letter-spacing: 1em;
background: center center no-repeat url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwAAADsABataJCQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+wAAAAnSURBVBhXY/Dz89MA4sNA/B9Ka4AEYQIwfBgkiCwAxjhVopnppwEApxQqhnyQ+VkAAAAASUVORK5CYII=);
}
body { background-color: #D3D3D3; }
<div id="d">
<ul>
<li><a>Profile Image</a></li>
<li><a>Name</a></li>
<li><a>Activity Information</a></li>
<li><a>Distance</a></li>
<li><a>Pace</a></li>
<li><a>Points Earned</a></li>
</ul>
</div>
<div style="width: 20rem"><script>document.write(d.innerHTML)</script></div>
<div style="width: 10rem"><script>document.write(d.innerHTML)</script></div>
For almost all browsers, you can use the CSS3 selector last-child instead of JavaScript:
ul li { display: inline; white-space: pre; }
ul li:after { content: " \00b7 "; }
ul li:last-child:after { content: ""; }
The white-space: pre stops wrapping within list items (because usually you want it to wrap between list items), and is a hack that allows you to increase the space between list items by adding spaces on the second line.
u00b7 ⋅ (MIDDLE DOT) is the standard unicode character for interpuncts, but you could also use u2022 • (BULLET), u2b24 ⬤ (BLACK LARGE CIRCLE), U+2043 ⁃ (HYPHEN BULLET), or any other unicode character you choose.
Note that some characters may not be supported on all systems.
Here is a further improved version. I kept getting an inconsistency at certain page widths where two bullets would be missing rather than just the last one. i.e.
link1 · link2 · link3 link4
link5 · link6
I think the issue was that removing the last bullet separator could itself affect the text flow if the page width was just right. The new script locks the original text flow by adding and removing literal line breaks.
I have the same script to run every time the screen is resized so you don't get stuck with awkward line breaks.
<style>
ul { width: 700px; text-align : center }
ul li { display: inline; white-space: nowrap; }
ul li:after { content: " \00b7"; }
ul li.nobullet:after { content: none; }
</style>
<body onresize="processBullets()" onload="processBullets()">
<ul>
<li>Harvard Medical School</li>
<li>Harvard College</li>
<li>Harvard Medical School</li>
<li>Harvard College</li>
<li>Harvard Medical School</li>
<li>Harvard College</li>
<li>Harvard Medical School</li>
<li>Harvard College</li>
</ul>
<body>
<script>
function processBullets() {
var lastElement = false;
$("br").remove(".tempbreak");
$("ul li").each(function() {
$(this).removeClass("nobullet");
if (lastElement && lastElement.offset().top != $(this).offset().top) {
$(lastElement).addClass("nobullet");
$(lastElement).append('<br class="tempbreak" />');
}
lastElement = $(this);
}).last().addClass("nobullet");
}
</script>
If you don't mind creating a PNG image (with transparent background) of the bullet (or other separator), then you can use a natural space between the list items painted with this as the background.
Where the list items wrap onto the next line, the space---and thus its background---won't be rendered.
This avoids layout issues relating to the space taken up by the separator, as well as avoiding any Javascript/jQuery, taking advantage of the browser's own layout engine to do the work. You can adjust the space for the separator with the word-spacing attribute.
You'll need to ensure there is no other whitespace within the markup that might otherwise be used as the natural space. You could use a higher-res image than the 5x5 here, in conjunction with background-size, so that it still looks ok when zooomed, but note IE8 doesn't support scaling of background images. The other drawback is that if you want to change the colour you'll have to edit the PNG.
FIDDLE
Code based on modifying #bleuscyther's answer:
CSS :
ul { max-width: 700px; padding: 0; text-align: center; }
ul li { display: inline; white-space: nowrap; }
ul .separator {
word-spacing: 1.1em;
background-repeat: no-repeat;
background-position: 50% 60%;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAOElEQVQI113M0Q3AIBRC0aM76P7jmHSmSj/6mibyc4EQkEEWuYtDmU1SXO1d6H7tjgupIl8+P+cD22cff9U1wbsAAAAASUVORK5CYII=);
}
HTML :
<ul>
<li>Harvard Medical School</li><span class='separator'>
</span><li>Harvard College</li><span class='separator'>
</span><li>Harvard Medical School</li><span class='separator'>
</span><li>Harvard College</li><span class='separator'>
</span><li>Harvard Medical School</li><span class='separator'>
</span><li>Harvard College</li><span class='separator'>
</span><li>Harvard Medical School</li><span class='separator'>
</span><li>Harvard College</li>
</ul>
user2511031's solution is almost ideal... it's just not a valid HTML. There should not be any SPAN outside LI, inside UL.
But it doesn't mean that there is no really ideal solution. I found one!
No need to put the spans allover and clean white-spaces in the markup. Place the needed space into the ":after" pseudo element content, apply the background image to it.
It does the same!
ul { max-width: 700px; padding: 0; text-align: center; }
ul li { display: inline; white-space: nowrap; }
ul li:after {
content: " ";
word-spacing: 2em;
background-repeat: no-repeat;
background-position: 50% 60%;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAOElEQVQI113M0Q3AIBRC0aM76P7jmHSmSj/6mibyc4EQkEEWuYtDmU1SXO1d6H7tjgupIl8+P+cD22cff9U1wbsAAAAASUVORK5CYII=);
}
Here's the Fiddle
I just used text-indent to successfully style a bulleted list as follows:
HTML:
<ul class="horizontal">
<li>Payment</li>
<li>Check</li>
<li>Direct Deposit</li>
</ul>
CSS:
ul.horizontal li {
list-style-type:disc;
float: left;
text-indent:-4px;
margin-right:16px;
}
In the simplest of ways, all you would require is setting text-align: center on the ul and display: inline-block on li in your stylesheet.
You can use an image as a separator if you wish by leveraging the :after pseudo class on li.
Here's an example.
http://jsfiddle.net/caramba/tSnnP/
<div>
<ul>
<li><span class="icon bull"></span>xxx</li>
<li><span class="icon bull"></span>xxx</li>
<li><span class="icon bull"></span>xxx</li>
</ul>
<ul>
<li><span class="icon bull"></span>xxx</li>
<li><span class="icon bull"></span>xxx</li>
<li><span class="icon bull"></span>xxx</li>
<li><span class="icon bull"></span>xxx</li>
<li><span class="icon bull"></span>xxx</li>
</ul>
</div>
<style type="text/css">
div {
white-space: nowrap;
width: 100%;
}
span {
display:inline-block;
margin:0 5px;
}
ul {
text-align:center;
}
ul li {
display:inline;
margin:20px;
}
.hide {
display:none;
}
.icon {
position:relative;
display:inline-block;
background-position:-1000px -1000px;
background-image:url(http://www.alexander-bown.com/wp-content/uploads/2011/05/big-black-dot.jpg);
background-repeat:no-repeat;
background-size:5px 5px;
width:5px;
height:5px;
}
.icon {
background-position:0px 0px;
top:-2px;
}
</style>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('ul li:first-child').children('span').addClass("hide");
});
</script>
ul li {
display: inline;
text-align: center
}
.separator {
display: inline-block;
background-color: black;
width: 5px;
height: 5px;
border-radius: 45px;
vertical-align: middle;
}
<ul>
<li>item 1</li> <div class='separator'></div>
<li>item 2</li> <div class='separator'></div>
<li>item 3</li> <div class='separator'></div>
<li>item 4</li> <div class='separator'></div>
<li>item 5</li>
</ul>
You can also build this in JavaScript using a loop and concatenating a new li for x amount of list items but seeing as your post doesnt say anything about a dynamically generated list I'll leave it just as this for now.
<table>
<tr>
<td>
<ul>
<li>First menu item</li>
</ul>
</td>
<td>
<ul>
<li>Second menu item</li>
</ul>
</td>
<td>
<ul>
<li>Third menu item</li>
</ul>
</td>
</tr>
</table>
So what I need help with, is how do I remove the newline after a <li> and or <ul>
This is my css:
#ranks li {
background: url(/img.png) no-repeat top left;
}
#ranks .sprite-admin{ background-position: 0 0; width: 157px; height: 44px; }
#ranks .sprite-banned{ background-position: -207px 0; width: 157px; height: 44px; }
and this is the html:
<ul id="ranks"><li class="sprite-admin"></li></ul>
It all works well while only one of the <ul id ="etc"> is there, but if there are multiple, it will make a new line and 'stack' them.. is it possible to make them not stack, and just go left to right?
Thanks
EDIT:
Demo : /removed/
You have a few options:
#ranks li {
float: left;
}
This will float all of your list items to the left, without wrapping, until horizontal screen space is no longer available. Alternatively,
#ranks li {
display: inline-block;
}
Which will also put your elements side-by-side, but handle them as bock level elements. If you don't care about block-level styling, you could go with straight inline-display:
#ranks li {
display: inline;
}
Which will treat the list items like any other inline element (such as <span> or <a>).
There are some other inherent styles that exist on list items, as well as their list parent, that you may need to do away with. Be sure to check out margin, and padding.
Demo: http://jsbin.com/iconud/edit#html,live
Look Out Ahead!
You may find that there is an unsightly gap between your list items when they're positioned side-by-side. This is a common problem with inline-lists. One solution is to remove the newline space between closing and opening list item tags:
<ul id="ranks"><li>
Index</li><li>
Contact</li><li>
Portfolio</li>
</ul>
Or have them all inline, a little less discernible:
<ul id="ranks">
<li>Index</li><li>Contact</li><li>Portfolio</li>
</ul>
This is a little tough on the eyes. With HTML, since closing tags aren't always required, you can also leave off the closing tag (though this makes me a bit nervous):
<ul id="ranks">
<li>Index
<li>Contact
<li>Portfolio
</ul>
Multiple Lists Inline Too!
From some of the OP's comments, it appears they might be trying to get not only list items inline, but lists themselves. If that's the case, apply the same aforementioned rules to the lists themselves:
#ranks,
#specs {
margin: 0;
padding: 0;
display: inline-block;
}
#ranks li,
#specs li {
display: inline-block;
border: 1px solid #CCC;
padding: 5px 10px;
}
Here were have identified two sets of rules using selectors that search for id's, and then tags. You could simplify this by apply a common class to the lists, or by basing the selectors off of a common parent element. Next is the markup:
<ul id="ranks">
<li>Index</li>
<li>Contact</li>
<li>Portfolio</li>
</ul>
<ul id="specs">
<li>Foo</li>
<li>Bar</li>
</ul>
This results in both lists, and their items, being displayed in a horizontal fashion.
Demo: http://jsbin.com/iconud/2/edit
with some css
<style type="text/css">
#ranks li { display:block; float:left; }
</style>
updated as comments: with display:block
ul li{ display:inline;} do the trick?
<li> by default is display:block;
if you give it display:inline; or diplay:inline-block; that should remove the linebreak
This is a basic example of horizontal UL's
HTML
<ul id="list">
<li class="item">Item 1</li>
<li class="item">Item 2</li>
<li class="item">Item 3</li>
</ul>
<span class="clearFloats">
CSS
.item {
float: left;
}
.clearFloats {
clear: both;
}
JSFiddle Example: http://jsfiddle.net/peterf/DEUBf/
Another option is to set font-size: 0 in the ul, then restore the desired font-size in the li tags. I prefer this as it's contained within the ul tag, doesn't need further hacks like clear:both, and explains better what the styling is meant to do (hide anything not inside a list item).
ul {
list-style-type: none;
font-size: 0;
}
li {
display: inline-block; /* Or inline, as you like */
font-size: 16px;
}