CSS to effect "li" only if a child of a specific "ul" - html

I have a unordered list as so:
<ul id="vertical_menu">
<li>Home</li>
<li>Subitem 1</li>
<li>Subitem 2</li>
</ul>
Now, I need to add borders to the "list item" li elements only if it is a child of the ul with the id vertical_menu.
Any ideas on how to do this?

ul#vertical_menu > li
{
/* apply li styles here as needed */
border: 1px solid #000;
}
ul#vertical_menu describes a ul element with ID 'vertical_menu'. > li describes a direct child element of type li. Any styles you list here will apply directly to the li elements as you wanted.
If you require support for IE6, the child selector > will be an issue. One work around to this is to apply styling to single level li, and "reset" it on further nested li, such as:
ul#vertical_menu li
{
border: 1px solid #000;
}
ul#vertical_menu li li
{
border: none;
}
This will add border to the first level list items within the vertical_menu, and will remove the border from any further nested items. Again not necessary to consider with modern browsers - depends on requirements.
In HTML markup, element IDs should be unique, so realistically you also don't need to select by ul and can simply use #vertical_menu > li or #vertical_menu li. Including ul in the selector is very strict. To each his own..

This selector translates exactly to what you're asking:
ul#vertical_menu > li
If your markup is always going to have one level of li elements under that ul, and/or only the ID is only going to be assigned to ul and not some other type of element (which it should be, for site consistency), there are a number of other ways to select the same elements, for example:
ul#vertical_menu li /* Assumes only one level of <li> */
#vertical_menu > li /* Assumes only this <ul> has the ID */
#vertical_menu li /* Assumes both of the above */
These alternatives are useful if IE6 support is a requirement, as it doesn't support the > combinator, but they all depend one way or another on the structure of your HTML.

Try this:
ul#vertical_menu > li{
border:1px;
}
It's worth noting that using the > selector doesn't work in older versions of Internet Explorer (IE6, I believe), so if you're looking also to support that,
ul#vertical_menu li
will also work (but it will apply the border to every list item under #vertical_menu even if its a submenu.

just make
ul#vertical_menu li{
border:1px solid #CCC;
Remember to use ul as it will make the css specificity more clear and it will style only the li items which are under the ul.
hope it will work for you.

#vertical_menu > li { border: 1px solid black; }
Should work, but IE6 will need
#vertical_menu li { border: 1px solid black; }

Both answers are correct. While ul#vertical_menu li targets all lis from ul#vertical_menu, ul#vertical_menu > li targets only first line li descendents.
For example, using the last selector only the id=one li will be targeted:
<ul id="vertical_menu">
<li id="one"></li>
<another-element>
<li id="two"></li>
</another-element>
</ul>

Related

Why is a second-child affected by my first-child color property?

I was finishing up selectors and testing my knowledge and encountered a problem that makes no sense.
In theory, the code below should color all first children that are li red, yet, a first and second child are being colored red.
Why is the second child colored red here?
li:first-child{
color: red;
}
<ul>
<li>Peter
<ol>
<li>Juan</li>
<li>Samuel</li>
</ol>
</li>
<li>John
<ol>
<li>Patrick</li>
<li>Spongebob</li>
</ol>
</li>
<li>Sara
<ol>
<li>Jonathan</li>
<li>Kragie</li>
</ol>
</li>
</ul>
color is inherited from the parent element....in this case the li:first-child
So when you tell the li to be a red color this is inherited by all its children.
You have no rule to override this for the children so they are colored by inheritance/
It happens because the color is inherited from the parent element, try to add this to your CSS to override it:
li {
color:initial;
}
This is because you have nested lis.
The second inner li is being coloured red because it's inheriting that rule from the style applied to the first child outer li, ie its parent.
li:first-child { color: red; }
li:not(:first-child) { color: black; }
That will override the inheritance and result in the text of the first outer and inner lis being red. Fiddle
Alternatively, if you want to colour only the inner lis:
li li:first-child { color: red; }
The li:first-child selector will also select the first li element in your parent list. You can target your selector using direct descendents or you can use classes.
Option 1: class selector on parent list
This is the preferred option as it will automatically namespace your css. All your selectors will start with .menu when targeting child elements.
<ul class="menu">
<li>Peter<ol>
<li>Juan</li>
<li>Samuel</li>
</ol></li>
</ul>
.menu ol li:first-child{
color: red;
}
If you want to override the style of a menu, you can use an extra class on the menu element and for example target it with the following selector. .menu.horizontal
Option 2: class selector on list item
This option has the same benefits of the first option, but now .menuItem is namespaced on its own.
<ul>
<li class="menuItem">Peter<ol>
<li>Juan</li>
<li>Samuel</li>
</ol></li>
</ul>
.menuItem ol li:first-child{
color: red;
}
Option 3: direct descendent selector
ol>li:first-child{
color: red;
}
It is always better to use classes because if you use ol elements in other places, the selector would still apply there.

CSS Inheritance Issue Trying to Highlight active tag

I am trying to highlight the active <a> however, my CSS is being overwritten.
#portfolio-filter li a {
color: black;
text-decoration: none;
padding:3px 8px 3px 8px;
background:#8d8d8d;
}
#portfolio-filter li:hover, a.filter.active {
background: white;
}
<ul id="portfolio-filter">
<li>
All
</li>
<li> etc... </li>
</ul>
The #portfolio-filter li a style is overwritting the #portfolio-filter li:hover, a.filter.active style and not sure what I need to do to fix this.
Link: http://velnikolic.com/ramova3/?page_id=25
The problem is that #portfolio-filter li a is more specific than a.filter.active. Since the background is on that a element, not the li element, your a background won't change even if #portfolio-filter li:hover is more specific.
To fix it, use something like #portfolio-filter li a.filter.active, which is more specific and will correctly take precedence.
As a general rule of thumb, when working with active classes, always use a similar selector as the original (non-active) definition. Otherwise, you may run into specificity issues like this one.
Here's a useful specificity calculator when in doubt.
The comma makes your "second" style two separate styles, remove the command and you should be fine.
ref: http://webdesign.about.com/od/cssselectors/f/comma-in-css-selectors.htm
Here was my solution.
portfolio-filter li a:hover, #portfolio-filter > li a.active{ background: white; }

Nesting child selectors in CSS

I have this HTML:
<div class="navbar">
<ul>
<li>Foo
<ul>
<li>Bar</li>
</ul>
</li>
</ul>
</div>
I want to apply CSS only to item "Foo." I do not want to tag every top-level <li> with a special class. My limited knowledge tells me I should be able to do this:
.navbar > ul > li {
text-transform: uppercase;
}
But the style gets applied to "Bar" as well when I do it like this. I thought that '>' specifies only immediate children, does it not work the same way when it's nested? Is what I'm trying to do even possible?
I thought that '>' specifies only immediate children, does it not work the same way when it's nested?
It does work the same way. Since you're anchoring the ul directly to .navbar with .navbar > ul, your selector does apply to li elements directly that particular ul only.
The problem is not with the selector; it's the fact that text-transform, like most text properties, is inherited by default. So even though you're applying the style only to immediate li elements, the nested ones receive it by inheritance.
You will need to reverse this manually on the nested elements:
.navbar > ul > li li {
text-transform: none;
}

difference between #navlist li #current and #navlist li .current

I'm trying to understand CSS mechanism but tutorials so far haven't been a great source. They only scratch the surface.
I need to understand the fundamental differences between using #navlist li #current and #navlist li .current.
The names are not generic in order to be a very practical example.
What I think the different is:
#navlist li #current
if applied to an li element inside a parent element #navlist will bypass any inherited format to display #navlist li #current format.
On the other hand:
#navlist li .current
will apply its format but also inherit from other format.
In this example:
#navlist li a:hover
{
color: #FFFFFF;
background: #3364BB;
border-color: #0F3974;
}
#navlist li .current
{
color: #000;
background: #FFFFFF;
border-bottom: 1px solid #FFFFFF;
}
<ul id="navlist">
<li>Home</li>
<li>Profile</li>
<li>Destinations</li>
<li>Discuss</li>
</ul>
The tab will be white with a black font but hover will be applied.
With this other example:
#navlist li a:hover
{
color: #FFFFFF;
background: #3364BB;
border-color: #0F3974;
}
#navlist li #current
{
color: #000;
background: #FFFFFF;
border-bottom: 1px solid #FFFFFF;
}
<ul id="navlist">
<li>Home</li>
<li>Profile</li>
<li>Destinations</li>
<li>Discuss</li>
</ul>
#current is applied and nothing else, leaving the tab white even if the mouse hover over it.
Is that right?
Is that right?
Yup. This is because a:hover is more specific than .current, but less than #current. So your hover styles will override your class styles, but your ID styles are untouched.
a:hover is more specific than .current because it combines a type selector and a pseudo-class selector. That beats out a class selector (although :hover and .current are equally specific), because of the a.
#current is more specific than a:hover because IDs are always the most specific, even if you combine a multitude of non-IDs in the hover style rule's selector.
Yes. (And seems specificity is the reason as BoltClock said)
This page will tell you how the browser read your css selector: http://www.css-101.org/descendant-selector/go_fetch_yourself.php
remember: id is unique, can be used for 1 element only; but class can be used to more than 1 element and tag
note: actually both rule select the same element and applied. If you write more in #navlist li a:hover, those non-overlapping prosperities will appear when mouse over #current (so call 'cascading')
more: Some keyword/concept you need to know: inheritance/cascading, css selector, css specificity, pseudo class
p.s. try jsbin / jsfiddle / cssdesk for your css test - learn from practice :D
I think you've got some syntax errors in your question. This style:
#navlist li .current
will target a child element of your LI, like this:
<ul id="navlist">
<li>
Foo
</li>
</ul>
I'm assuming you intend to put a class or ID of "current" on the LI itself. If so, your rule should look something like:
#navlist li.current // no space in between 'li' and '.current'
Also remember that ID's are "weighted" more than Classes in CSS. So if you have two equally structured rules, but one uses and ID and the other uses a class, then the ID rule will trump the class rule. They BOTH will appy, but the ID rule will apply LAST. This is important to note if you are doing font-sizing and such, where rules are cumulative instead of just overriding each other.

list-style-type: none when list items are links and show bullets when the list items aren't links? CSS

If I have a couple of bullet lits on a page and some lists contains normal text (no paragraph elements) and some contains links, is it possible to have no bullets on the links but bullets on the text items?
To remove all bullets I do:
#WebPartWPQ1 li ,#WebPartWPQ2 li ,#WebPartWPQ3 li ,
#WebPartWPQ4 li,#WebPartWPQ5 li,#WebPartWPQ6 li,
#WebPartWPQ6 li {margin-left: -25px; list-style-type: none}
But if the item is a link I want to show the bullets. I tried with:
#WebPartWPQ1 li ,#WebPartWPQ2 li ,#WebPartWPQ3 li ,
#WebPartWPQ4 li,#WebPartWPQ5 li,#WebPartWPQ6 li,
#WebPartWPQ6 li {margin-left: -25px;}
#WebPartWPQ1 li a ,#WebPartWPQ2 li a ,#WebPartWPQ3 li a ,
#WebPartWPQ4 li a,#WebPartWPQ5 li a,#WebPartWPQ6 li a,
#WebPartWPQ6 li a {margin-left: -25px; li ast-style-type: none}
Without success, any ideas?
You would have to resort to server-side preprocessing or Javascript. There is no way in CSS to style an element based on what its children elements are, or to change a parent's style from a child element's style declaration. Here's the W3 CSS2 Selector Reference and the CSS3 working draft Selector reference, and neither of them mention parent selectors.
While you can not change the styling of a list element based whatever element(s) it contains, there is a pure CSS workaround that achieves more or less the same result :
Set block as the display property of all of your list elements
Set list-item as the display property of your link elements, along with a valid value for list-style-position and list-style-type.
So instead of making your list items look like a list item when they contain a link, you're just making the links inside your list items behave like a list item.
Your bullet will have the same color as your link, but that's about the only difference between this approach and the approach you had in mind (which is impossible).
EXAMPLE CODE :
#WebPartWPQ1 li {
margin-left: -25px;
display: block;
}
#WebPartWPQ1 li a {
display: list-item;
list-style-position: inside;
list-style-type: disk;
}
<ul id="WebPartWPQ1">
<li>Item 1 (ordinary item)</li>
<li><span>Item 2 (wrapped in a "span" tag)</span></li>
<li>Item 2 (wrapped in an "a" tag)</li>
</ul>
THE FIDDLE :
http://jsfiddle.net/6kt8jhfo/5/