The navigation I'm referring to looks something like this:
home | about | contact
So what's the best and most flexible HTML/CSS to use for this type of navigation? The best thing I can come up with is to wrap the delimiters in a span so that I can control the spacing around them. For example:
home<span>|</span>about
Is that the best approach?
This all comes down to your target browsers, and if validating as strict HTML4.01 is important to you (ie: a boss/committee thinks it's a "big deal") or not.
Personally, for purposes of nav-menus, I go the route of wrapping everything in an unordered list.
If 4.01-compliance is important, I'll wrap that in a div.nav
If html5 is cool (which it is, with an oldIE JS-shim, as long as there are no committees involved), I'll wrap everything in a <nav id="main-nav"> or similar.
<ul><li>home</li><li>about</li></ul>
Then in CSS:
#main-nav li { display : inline-block; list-style : none; }
From there, you can set your padding on each <li> element to whatever you want.
You can use the :after pseudo-selector to inject "|" or any custom image you want, after each one (and you can use the :last-child:after to make sure that there's no image after the last one, if that's what you want).
You can even play around with the a, turning it into a block-element, and playing with padding to make the entire li block clickable, and not just the text.
See the oldIE-compatibility hack here: how to make clickable links bigger, if necessary.
You could simply add a left border to every element, except the first one:
HTML:
<ul id="nav-list">
<li>Home</li>
<li>Blog</li>
<li>Link</li>
</ul>
With the CSS:
#nav-list li {
display: inline-block;
border-left: 1px solid black;
padding: 4px;
}
#nav-list li:first-child {
border-left: 0;
}
See the above code in action on jsfiddle!
This is rather cross-browser compatible (IE7+) but it can be easily polyfilled with something like Selectivizr for IE6. Thanks to Rob W for suggesting to use border-left and first-child to reach more browsers!
Related
Is there a way to print target page numbers with hyperlinks which linked to various places within the same document?
<h1>Table of Contents</h1>
<ul>
<li>Introduction</li>
</ul>
...
<section id="introduction"> <!-- Appears, for example, on page 3 when printed -->
<h1>Introduction</h1>
...
</section>
So that the output is like:
Table of Contents (page 0)
Introduction.........................3
...
Introduction (page 3)
I only need this to work with the Google Chrome browser when printing to PDF (on OS X).
Is there some CSS or JavaScript trickery which would allow me to achieve this?
It looks like this is part of a new working draft of the CSS specification:
http://www.w3.org/TR/2014/WD-css-gcpm-3-20140513/#cross-references
I doubt that there is any browser support yet...
I have no idea if this will work in a PDF or not, but to answer the question of how this can be done in CSS:
You can generate the numbers using counter-increment on a pseudo element in css:
note that I changed your <ul> to an <ol> as this is an ordered list, whether you use the list-style or not.
ol {
counter-reset: list-counter;
}
li:after {
counter-increment: list-counter;
content: counter(list-counter);
float: right;
}
Making the little dotted line in between the text and the number takes a little more work, but you can achieve that by adding in some extra span elements and using css display: table; and display: table-cell; to lay them out properly:
<ol>
<li><span>Test</span><span class="line"></span></li>
<li><span>Test2</span><span class="line"></span></li>
<li><span>Test3</span><span class="line"></span></li>
</ol>
li {
display: table;
}
li span, li:after {
display: table-cell;
vertical-align: bottom;
}
li span.line {
border-bottom: 1px dotted #000;
width: 100%;
}
Setting the width to 100% on the span.line element, while not setting any width at all forces it to fill all of the remaining space (this is due to table-cell display elements not being allowed to break to new lines, and preventing overflow of content)
See full demo
It's not the cleanest approach to have to add the extra span elements, but it is a bit of a tricky task. Perhaps someone else will be able to take the time to think of a more efficient way to accomplish it? You could always just put an underline under the entire <li>, and skip the extra markup, at the cost of being a little less cool.
So I have a navigation menu that is generated by my CMS:
The menu's HTML is straightforward (edited for clarity):
<ul>
<li>Journal</li>
<li>Art</li>
<li>Work</li>
</ul>
I want the items to show up as hand-written text, in keeping with the general theme of the site, using separate PNG files for each menu item.
To do that, I used the CSS content property like so:
#headerNav .nav li a[href="/_site/en/journal/"]
{ content: url(/path/to/image.png); }
And it worked great! The HTML text of each item was replaced by the correct image:
However, alas, then I learned not every browser supports the content property on selectors other than :before and :after! Chrome and Safari do it, but Firefox doesn. However when I use :before, the HTML node isn't replaced, but the image is added:
How do I work around this?
What didn't work:
Making the <a> element display: none removed the :before part as well.
Making the <a> element position: absolute and moving it elsewhere won't work either.
Making the <a> element width: 0px screws up the layout because the images added through content aren't in the document flow.
What I don't want to do:
Of course I can output the images by hand but I want to work with the HTML the CMS is giving me, which is <li>s with text in them.
Any solution involving background-image would require me to specify each item's width and height in the style sheet, which I would like to avoid for the purposes of this question.
Turning the handwriting into a font is not an option.
Using JavaScript to replace the items on the fly is not an option. This needs to work using pure HTML and CSS.
Since you are doing this into a navigation bar you should have a fixed height making the next method possible to work:
First insert the image as content on the :before element and make it display:block to push the actual text of the a tag below.
li a:before {
content:url(http://design.jchar.com/font/h_1.gif);
display:block;
}
Then hide that text with a fixed height on your a tag:
li a{
height:50px;
overflow:hidden;
}
The Working Demo
Answer was answered before OP added the line
Any solution involving background-image would require me to specify
each item's width and height in the style sheet, which I would like to
avoid for the purposes of this question.
So if anyone interested in background-image solution can refer this, else can simply skip.
Am not sure how optimum solution I am suggesting is, but surely you can use background-image for each a element, using nth- pseudo, and set the fonts color to transparent, or use text-indent property with overflow: hidden;
So it will be something like
nav ul li {
display: inline-block;
}
nav ul li:nth-of-type(1) a {
background-image: url(#);
display: block;
width: /* Whatever */ ;
color: transparent;
text-indent: -9999px; /* Optional */
overflow: hidden;
font-size: 0; /* Optional, some people are really sarcastic for this */
/* Below properties will be applicable if you are going for sprite methods */
background-position: /* Depends */ ;
background-size: /* If required */ ;
}
The reason why I would suggest you is :-
Advantages :
Cross browser compatible
Can you sprite methods to cut down http requests to request image for each tab
Also, you are not losing the text which is between the a tags, which is really good as far as screen readers are concerned.
Disadvantages :
Set custom width for each
Note: If you are going for a sprite solution, than background-position is anyways a must property to be used, so be sure you check out the support table first, before opting the sprite method.
Credits - For support table
I would put PNG images into img tag and then set alt attribute.
<ul>
<li><img src="journal.png" alt="Journal"/></li>
<li><img src="art.png" alt="Art"/></li>
<li><img src="work.png" alt="Work"/></li>
</ul>
This question already has answers here:
How to remove the space between inline/inline-block elements?
(41 answers)
Closed 7 years ago.
How to you get rid of the white space between list items? I am trying to make it so that the images are right next to each other. Even though I have set the styling to margins: 0;, they are still separated.
CSS
ul.frames{
margin: 20px;
width: 410px;
height: 320px;
background-color: grey;
float: left;
list-style-type: none;
}
ul.frames li {
display:inline;
margin: 0;
display: inline;
list-style: none;
}
ul.frames li img {
margin: 0 0 0 0;
}
HTML
<li>
<img id="myImg" src="img.jpg" width="102.5px" height="80px"/>
</li>
<li>
<img id="myImg2" src="img.jpg" width="102.5px" height="80px"/>
</li>
<li>
<img id="myImg3" src="img.jpg" width="102.5px" height="80px"/>
</li>
<li>
<img id="myImg4" src="img.jpg" width="102.5px" height="80px"/>
</li>
Updated Sept. 1st, 2014
In modern browsers, flex-box is the preferred method of doing this. It's as simple as:
ul {
display: flex;
}
See a JSFiddle here.
For legacy browser support refer to the other options below, which are still just fine, albeit slightly more complex.
Though each of the other answers gives at least one good solution, none seem to provide all of the possibilities. And that's what I'll try to do here.
Firstly, to answer your implicit question of why there's spacing, it's there because you've set your LIs to display as inline elements.
inline is the default display value for text and images in all of the browsers that I know of. Inline elements are rendered with spacing between them whenever there's whitespace in your code. This is a good thing when it comes to text: these words that I've typed are spaced apart because of the space I've included in the code. And there's also space between each line. It's this very behavior of inline elements is what makes text on the web readable at all.
But sometimes we want non-text elements to be inline to take advantage of other properties of this display style. And this typically includes a desire for our elements to fit snugly together, quite unlike text. And that seems to be your problem here.
Without further ado, here are all the ways I know of to get rid of the spacing:
Keeping them inline
(Not recommended) Apply negative margin to the LIs to move them over.
li { margin: -4px; }
Note that you'll need to 'guess' the size of a space. This isn't recommended because, as Arthur excellently points out in the comments below, users can change the Zoom of their browser, which would more than likely mess up the rendering of your code. Further, this code requires too much guesswork and calculation. There are better solutions that work under all conditions.
Get rid of the whitespace
<li>One</li><li>Two</li>
Use comments to make the whitespace a comment JSFiddle
<li>One</li><!--
--><li>Two</li>
Skip the closing tag (HTML4 valid / HTML5 Valid) JSFiddle
<li>One
<li>Two
Put the whitespace in the tag itself (Note: Early Internet Explorers will not like this)
<li>One</li
><li>Two</li
>
Take advantage of the fact that the spacing between the elements is calculated as a percentage of the font size of the parent. Consequently, setting the parent's font size to 0 results in no space. Just remember to set a non-zero font-size on the li so that the text itself has a nonzero font size. View on JSFiddle.
Floating them
Float them instead. You'll probably want to clearfix the parent if you do this.
li { float: left; display: block; }
Incredible but no one here has provided the proper solution for this problem.
Just do this:
ul.frames {
font-size: 0;
}
ul.frames li {
font-size: 14px; font-size:1.4rem;
display: inline;
}
Keep in mind that we won't always have access to modify the markup. And trying to remove the spaces from the <li>s with JavaScript would be totally unnecessary when the solution is simply two font-size properties.
Also, floating the <li>s introduces another potential problem: You wouldn't be able center and right align the list items.
If you try to do float:right; on the <li>s then their order will be swapped, meaning: the first item in the list would be last, the second item is the one before the last, and so on.
Check out this other post here in SO: A Space between Inline-Block List Items
You should just remove all the spaces in the ul tags just like this: http://jsfiddle.net/dFRYL/3/
Since the <li> elements are inline, in you write spaces in or between them you will have spaces displayed.
The reason you get the spaces is because you have spaces between the elements (line break)
<ul>
<li>One</li><li>
Two</li><li>
Three</li>
</ul>
You can use negative margins like this:
margin-right: -4px;
margin-bottom: -4px;
Take a look here.
It also works up and down, I added another one to show that here.
Using display:inline; causes whitespace in your HTML to create whitespace when displaying the HTML.
There are two solutions to this:
1) Change how you make them appear inline, I would recommend using floats on all of the list items, then using a clearfix of sorts.
2) Remove all whitespace between your list items, e.g.
<li><img id="myImg" src="http://stephboreldesign.com/wp-content/uploads/2012/03/lorem-ipsum-logo.jpg" width="102.5px" height="80px"/></li><li><img id="myImg2" src="http://stephboreldesign.com/wp-content/uploads/2012/03/lorem-ipsum-logo.jpg" width="102.5px" height="80px"/></li><li><img id="myImg3" src="http://stephboreldesign.com/wp-content/uploads/2012/03/lorem-ipsum-logo.jpg" width="102.5px" height="80px"/></li><li><img id="myImg4" src="http://stephboreldesign.com/wp-content/uploads/2012/03/lorem-ipsum-logo.jpg" width="102.5px" height="80px"/></li>
Personally I would recommend option 1 (I hate display: inline)
here is my attempt at it. Hope it helps. As Sean Dunwoody mentioned, white space in your html can be a cause of the space, but I've floated the li and made the image to display:block;. Left comment on where I made changes. Hope it helps: http://jsfiddle.net/FJ3nV/
Here my small but main changes:
/*
* Added float left
*/
ul.frames li {
margin: 0;
list-style: none;
float:left;
}
/*
* Moved inline sizing here just to clear up obtrusive html.
* Added display block.
*/
ul.frames li img{width:102px; height:80px; display:block;}
I would change your li elements to inline-block.
One person did not recommend
li { margin: -4px; }
But making a slight change to it will cause it to work even when the font size changes or when the browser zooms in
li{ margin-right: -0.25em; }
That should fix that white space problem completely. However, if you are using a poorly designed font-face that doesn't follow correct letter-height standards then it may cause a problem. However those are harder to find and most of the fonts google hosts don't have that issue.
I'm fighting with CSS and can't figure out how to remove bullets. Yeah, I know this sounds easy, but hear me out. I have another external CSS file from our corporate office that has styles that are getting in the way and I can't for the life of me figure out how to override them. I've tried the !important token and it doesn't work either. I'm using chrome and the inspector hasn't yet helped me figure out what's causing it. Anyway, here's my code which works great stand-alone, but once I put the corporate CSS file in there, the stupid bullets come back. Ugh!
<ul style="list-style-type:none;">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
This sounds like more of an issue with CSS specificity. You can't "override" the other styles, per se, you can merely create additional styles which are more specific. Without knowing what the other CSS looks like, there are generally three ways to do this:
Inline styles
Exactly like you have in your example. These are most specific, so they're guaranteed to work, but they're also guaranteed to be a pain in the neck to work with. Generally, if you're using these, something needs to be fixed.
Add an id attribute to the unordered list,
Then use the id as a selector in your CSS. Using an id as a selector is more specific than using a class or an element type. It's a useful tool for cutting through a bunch of styling that you might be inheriting from somewhere else.
<ul id="the-one">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
ul#the-one {
list-style-type: none;
}
Wrap all of your HTML in a div with the id attribute set.
This is what I usually do. It allows me to use that div with it's id in my CSS styles to make sure my styles always take precedence. Plus, it means I only have to choose one meaningful id name, then I can just style the rest of my HTML as I normally would. Here's an example:
<div id="wrapper">
<ul>
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
<p>Some text goes here</p>
</div>
div#wrapper ul {
list-style-type: none;
}
div#wrapper p {
text-align: center;
}
Using that technique is a pretty good way to make sure that you spend most of your time working on your own styles and not trying to debug somebody else's. Of course, you have to put div#wrapper at the beginning of each of your styles, but that's what SASS is for.
I had the same problem, I was trying to change the CSS for a joomla website, and finally found that the li had a background image that was a bullet... (the template was JAT3). This is the code:
.column ul li {
background: url(../images/bullet.gif) no-repeat 20px 7px;
...
}
Hope it helps someone.
Ensure the rule you're trying to override is on the UL, rather than the LI. I've seen that rule applied to LIs, and overriding the UL as you have above would have no effect.
My situation is similar to the one described by #fankoil: my inherited css had
main-divname ul li{
background-image:url('some-image.png');
}
to get rid of this for a specific ul, I gave the ul an id
<ul id="foo">
...
and in the css, turned off background image for this particular ul
ul#foo li {
background-image: none !important;
}
So to add some clarification to some previous answers:
list-style-type is on ul
background-image in on li
It's better if instead of having the style inline you call it using a class:
<ul class="noBullets">
.noBullets {
list-style-type:none !important;
}
If you can't find the style that's overwriting yours, you can use the !important property. It's better to first inspect your code online using chrome or firefox's Inspect element (or firebug).
EDIT:
Accordnig to your comment, the style comes from div#wrapper ul. Did you try:
div#wrapper ul {
list-style-type:none !important;
}
The Trick is very simple:
HTML get that:
<ul id="the-one">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Style get that:
ul#the-one {list-style-type: none;}
But, the next two options will blow your mind:
li {width: 190px; margin-left: -40px;} // Width here is 190px for the example.
We limit the width and force the li paragraph to move left!
See a Awesome example here: http://jsfiddle.net/467ovt69/
Good question; it's odd how the bullets show in IE even with the list-style:none;
This is the code that removed the bullets:
/* media query only applies style to IE10 and IE11 */
#media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
/* removes bullets in list items for IE11*/
li {
list-style-position: outside;
overflow: hidden;
}
}
check for the following line of code in your css:
.targeted-class-name>ul>li>a:before {
content: "•";
}
That was the culprit in my case
i think you could solve also your problem by wrapping text in your list-item with span then used something like this:
ul>li:nth-child(odd) > span:before {
display:none;
}
ul>li:nth-child(even) > span:before {
display:none;
}
Odd and even are keywords that can be used to match child elements whose index is odd or even, and display=none will do the trick to by not displaying element before the span element.
I'm in the process in coding a web design and i've spent the grandeur of my time thinking how will i be coding this navigation bar, where the <li> have dynamic widths where the background image adjusts to the width of the element.
My idea was to use <span> and slice the background image into three parts.
<li>
<span class="libefore"></span>
MOVIES
<span class="liafter"></span>
</li>
What's the best way of coding this?
Normally this is achieved with a technique called 'sliding doors' have a read over this:
http://www.alistapart.com/articles/slidingdoors/
If you are willing to go with CSS 2.1 :before and :after selectors (See here for supported browsers: http://www.quirksmode.org/css/contents.html), you could try something like this:
HTML:
<li>
Movies
</li>
CSS:
li:before {
background-color: #F00;
content: '\00A0\00A0';
}
li a {
background-color: #0F0;
text-transform: uppercase;
}
li:after {
background-color: #00F;
content: '\00A0\00A0';
}
This keeps your HTML clean without introducing any presentational elements. (ie. No span elements that have no content or hierarchical purpose) Also, it's not a bad practice to use text-transform to take care of any uppercase transformations, just in case you want to change the style one day without having to modify the content.
Here is a fiddle which should give a bit of a starting point to tweak from: http://jsfiddle.net/6Keaa/
Hope this sets you in the right direction...