I have several NAV Bars. Each NAV Bar is of the pattern;
a | a
such that where the literal "|" occurs, it's always has a sibling a on the left.
where a is an html anchor element and "|" is a literal separator of interest.
What css can I use to capture that literal "|"? The idea is that I want to set it display:None for print media.
Thanks for any help.
My recommendation would be to use an unordered list
<ul class="myNav">
<li><a>My Nav</a>
<li class="last"><a>Another nav</a>
</ul>
And then float the list items left, and then put a border on one side of each list item. Now the CSS below isn't exact, but it gives the general idea
.myNav li {float:left;border-right:1px solid black;}
.myNav li.last {border-right:0}
That should look similar, and be 100% css for seperators.
CSS selects html elements. | is not an html element, it's a text node, you can't access it. However, you can probably use background images on the anchors instead, and make them the divider. That or wrap spans around the divider and target them.
<span class="divider">|</span>
or
#nav a { background:url(/images/divider.gif) no-repeat top left; }
#nav li.last a { background-image:none; }
I didn't mention borders because they would rely on the height of the element being applied to and assumed you wanted more control, more customized but you could of course use those.
You need hooks to select anything with CSS. If the "|" characters aren't marked up in some way, you can't select them. Put them in span elements, or, better yet, replace them with background images, and define your navigation as a real list.
Yeah, you'd have to surround them, with say a span element. Then give those spans a class of "pipe" or something. Then use the CSS class "pipe" to set the display to none for printing.
You could position the parent element outside but the a elements inside the viewport. Something like this:
div {
position: relative;
top: -10em;
}
div a {
position: relative;
top: 10em;
}
But you should better use a list for your navigation and format that:
<ul id="nav">
<li>first</li>
<li>second</li>
<li>third</li>
</ul>
#nav, #nav li {
list-style: none;
margin: 0;
padding: 0;
}
#nav li {
float: left;
}
If you just need a simple text divider, using the content property is a fast, semantic way to achieve this.
<div id="nav">
Nav1
Nav2
</div>
#nav a + a:before { content: '|'; }
Note that content and adjacent sibling selectors (the + in the selector above) don't work in older browsers like IE6, but since this is just a divider, it shouldn't be a huge concern.
Edit: Note that this will make the | appear inside the link, so you should use a list instead (that is also the correct way to mark this up anyway).
Related
I have floated articles side by side that are 25% wide. I'm adding a clear:both after every fourth element. However I need to insert a graphical section-break inbetween the elements. And it has to be inside the <ul>. To be valid I wrapped the "section-break" (the first li item in the sample underneath) into a <li> as well.
<ul>
<li class="year"><h1>THIS IS A SECTION Break and 100% wide</h1></li>
<li>This is a article and only 25% wide</li>
<li>This is a article and only 25% wide</li>
<li>This is a article and only 25% wide</li>
<li>This is a article and only 25% wide</li>
</ul>
I want every fourth element to be a line break so I use …
ul li:nth-of-type(4n+1) { clear: both; }
However I want the li.year not to be affected by this behaviour so I tried this
ul li:not(.year):nth-of-type(4n+1) { clear: both; }
Right now the last <li> in my sample code above is floated into the next line but that shouldn't happen since the first <li> isn't one of the floated articles but contains a headline.
Is it possible to stack the :not and nth-of-type() selector onto each other?
The selector you have --
ul li:not(.year):nth-of-type(4n+1) { background: yellow; }
-- is perfectly correct (as shown by highlighting the selector).
The issue is with how you're using clear. It works if you use clear:right, and then clear:left on the following element:
ul li:not(.year):nth-of-type(4n+1) { clear: right; }
ul li:not(.year):nth-of-type(4n+2) { clear: left; }
Edit per comments The stricken-out text is nonsense. The real issue, as per BoltClock's answer, is that the :not pseudo-class doesn't affect nth-of-type. Adjusting the selector offset works in this case by coincidence, but would not work if the :not pattern was different.
ul li:not(.year):nth-of-type(4n+2) { clear: left; }
http://jsfiddle.net/8MuCU/
The reason your :not() doesn't appear to work is because the li.year is of the same element type as the rest of your li elements (naturally), so :nth-of-type(4n+1) matches the same elements regardless of the .year class.
It's not possible to stack selectors sequentially either. That's just not how they work.
Since you can't change your li elements to something else because of HTML markup rules, and :nth-match() is in a future spec and hasn't been implemented yet, you have to make do with changing your :nth-of-type() formula to accommodate the structure instead:
ul li:not(.year):nth-of-type(4n+2) { clear: both; }
Very often, it's natural to need to specify a CSS style for all elements except the first (or the last). For example, when styling paragraphs, you wish to add a bottom margin to every element except the last one (or similarly, a top margin to every element except the first one).
Is there any way to do that that's :
more concise than defining p {...} and then p:first-child {...}?
more straightforward and intuitive than p:nth-child(-n+1)?
If there is not, do you know of any attempt at adding it?
For all p elements except the first child, use either one of these (the second one is better-supported):
p:not(:first-child)
p:first-child ~ p
For all p elements except the last child:
p:not(:last-child)
For all p elements except the first and the last children:
p:not(:first-child):not(:last-child)
As usual, CSS3's :not() and :last-child aren't supported until IE9+ and relatively new versions of other browsers. You're not going to reach very far in terms of browser support (IE8 and older) unless you add classes to your first and last children, using JavaScript or otherwise.
Remember that vertical margins collapse between in-flow paragraphs and their ancestor(s), so unless you want to zero out the margins of the container element for these paragraphs as well, you shouldn't need to zero out the margins of the first and last p elements specifically. Here's a fiddle to illustrate.
If IE7-8 support is not needed you can use the :not() CSS selector, like:
p:not(:first-child) {
...
}
But if you need to support IE7+, which may still be the case there is a little trick you can use and usually gets you fairly far. A lesser known fact is that the :first-child psuedo selector actually works in IE7+ (not :last-child though) as are some other css selectors and this makes stuff like adding vertical margins in a horizontally floated layout possible.
Imagine this html:
<ul>
<li>Item #1</li>
<li>Item #2</li>
<li>Item #3</li>
<li>Item #4</li>
</ul>
And this as some CSS:
/* General reset */
ul, li { list-type: none; margin: 0; padding: 0; }
/* Make horizontal */
ul > li { float: left; }
So now all list items are horizontally next to each other, and now we want to add a margin in BETWEEN all items but not on the right or left side, we can do this in css:
/* General reset */
ul, li { list-type: none; margin: 0; padding: 0; }
/* Make horizontal */
ul > li { float: left; margin-left: 10px; }
ul > li:first-child { margin-left: 0; }
This usually covers 95% of the cases where I want something unique, then the rest of the 'forgotten' selectors cover another few percent, after that you need to add some classes which usually isn't much of a bottleneck anyway in the backend of the page.
Well, you could do:
p:not(:first-child) {...}
But only the most recent browsers support the :not psuedo-class.
Other than that, no. Your best option is to specify a style for all and then override it for the first/last.
I would suggest to use first-of-type:
p:not(:first-of-type) { ... }
Browser support (caniuse)
<style>
ul{margin:0px;padding:0px;}
ul li{margin:0px 5px 5px 0px;padding:0px;list-style-type:none;float:left;}
</style>
<ul class="clearfix">
<li> </li>
<li> </li>
<li> </li>
<li> </li>
<li> </li>
<li> </li>
</ul>
The first li contains more content than the rest.
So, I have the following problem:
problem http://img830.imageshack.us/img830/240/problemc.png
But how do I move the next row down, so it looks like that:
want this http://img440.imageshack.us/img440/9750/solutionm.png
I tried using display:inline-block; instead of float:left; for the lis, which works, but I'd still rather use float:left; over inline-block.
Any ideas on how to do this?
Solution for IE:
http://blog.mozilla.com/webdev/2009/02/20/cross-browser-inline-block/
The best solution is to use a little-known display style called table-cell.
I've had to do this a few times. Here's how you do it:
/* -*- CSS -*- */
ul li .wrapper
{
display:table-cell;
width:100px; /*replace here*/
min-height:100px;/* " " */
}
ul li
{
float:left;
display:inline-block;
}
ul
{
display:table;
}
...
<!-- HTML -->
<ul>
<li><div class="wrapper">my-content</div></li>
<li><div class="wrapper">my-content</div></li>
<li><div class="wrapper">my-content</div></li>
<li><div class="wrapper">my-content</div></li>
</ul>
How this works:
When the parser sees that there's a UL object, it treats it like a table instead of a list. This gives you the distinct advantage that you're beginning to /act/ like you're working with tables (but you're not!)
The rule then runs against the wrapper class -- this creates a "Table cell". We don't want to put it in the li because OTHERWISE the li will act as the table cell. This is kinda bad. the work around is that your li is actually aligned left. There's some argument whether or not is a good idea to do it this way -- this is the "Most Effective" because it forces the box model to comply. Its fugly, I know.
the REASON its bad for the li to be treated like a table-cell is that it won't wrap. The reason it wont wrap is that table-cells aren't supposed to wrap.
There is ONE other solution that might work, however I haven't tested it.
/* -*- CSS -*- */
ul li { display: inline-block; float:left; min-height:200px;width:200px; }
Its not as ugly, but it should work by making the box model force the alignment as well.
First of all: Are you sure you're using the right markup? A list generally doesn't end up to look like that.
Second. Do you know how many items you will have on a row? In your image they seem to have the same width. If you know that you can add clear:both; to the forth li (and other you may need) and force it down. This would be the only way to do it with left floating lis.
You can't do this using only float:left; the blocks just fall into place where they fit as your first example shows. If you intend for your content to always display in three columns, you could programmatically clear the float on the first item in each row.
Let's say a have the following code:
<nav id="main-navigation">
<ul>
<li>Link 1 Level 1</li>
<li>Link 1 Level 1</li>
<ul>
<li>Link 1 Level 2
</ul>
</ul>
</nav>
And now I want to to set first ul's height to 100px and second ul should be 300px.
When I try
nav ul {
height: 100px
}
Second ul also inherits this value.
I was trying "~", "+", ">", first-childs etc. but don't know how to do that, even with documentation.
Is there a good explained (preferably with demos/screens) guide to new css3 selectors? W3 Table is too nerdy for me.
Thanks!!!
Just select any ul that is a descendant of ul and give it that style, if you will only have 2 layers of <ul>s. No need for any special CSS2/CSS3 combinators since <ul> cannot directly contain <ul>, plus you don't have to worry about IE either.
nav ul {
height: 100px;
}
nav ul ul {
height: 300px;
}
To select direct children of an element, and not any descendant, you should use the > syntax. In your case (after you put the second ul inside a li) you need:
nav > ul {
height: 100px;
}
nav > ul > li > ul {
height: 300px;
}
Extra: It doesn't really make sense to have a 300px item inside a 100px item. Why do you want that?
Another extra: Try to read the w3c docs, it will save you some time in the long run. What you don't understand you can always ask on SO.
Firstly, how imporant is browser compatibility to you? All of those selectors you mentioned have issues in various versions of IE (IE8 is obviously better than IE7, but even IE8 is missing a lot of CSS selectors)
Simple nested selectors (ie just a space between the CSS names) will work for you - although as you say, setting nav li {height:100px;} sets it for all the LIs, you can override that with nav li li {height:300px;} to set the inner one back the way you want it.
If you want to use the 'correct' selectors, the one you want is >.
nav>ul>li {
height:100px;
}
This will only affect the outer LI elements, not the inner one. However as I say, it won't work in older versions of IE (fortunately it does work in IE7 and up, so it's only an issue if you want to support IE6).
You say that you've found the various selectors quite hard to grasp. I recommend you visit Quirksmode. For a start, it's got a very handy compatibility chart showing which browsers support which selectors, but it's also got excellent examples of how each selector works, which should help you understand them a bit better.
I have a simple list I am using for a horizontal menu:
<ul>
<h1>Menu</h1>
<li>
Home
</li>
<li>
Forum
</li>
</ul>
When I add a background color to the selected class, only the text gets the color, I want it to stretch the entire distance of the section.
Hope this makes sense.
The a element is an inline element, meaning it only applies to the text it encloses. If you want the background color to stretch across horizontally, apply the selected class to a block level element. Applying the class to the li element should work fine.
Alternatively, you could add this to the selected class' CSS:
display: block;
Which will make the a element display like a block element.
Everyone is correct that your problem is that anchors are inline elements, but I thought it is also worth mentioning that you have an H1 inside of your list as well. The H1 isn't allowed there and should be pulled out of the UL or placed into an LI tag.
Would something like this work?
.selected {
display: block;
width: 100%;
background: #BEBEBE;
}
Put the selected class on the <li> and not the <a>
<a> elements are inline by default. This means that they don't establish their own block, they are just part of the text. You want them to establish their own block, so you should use a { display: block; } with an appropriate context. This also enables you to add padding to the <a> elements rather than the <li> elements, making their clickable area larger, and thus easier to use.