CSS: select LI in multiple parent UL classes - css

I have defined two <ul> classes, px_p and px_s. Now I want to style all <li> elements that are contained within either <ul class="px_p"> or <ul class="px_s"> elements.
I had thought that ul.px_p, ul.px_s li {} would work, but no dice. I tried ul.px_p li, ul.px_s li {} as well.
The issue is that the <li> styling is
ul.px_p, ul.px_s li {
margin: 0.1em;
}
and .1em is being applied to the whole <ul> element, as well as the nested <li> elements. I just want the <li> elements, as the <ul> has a much larger bottom margin to graphically separate it from the following elements. The difference between px_p and px_s is _p is Primary, and has a bullet, while _s is secondary and has no bullet, it just indents more.

The selector should be like this:
ul.px_p > li,
ul.px_s > li {
...
}
Using the > selector will only match li elements whose parent elements are ul.px_p or ul.px_s.
This is important, given that ul.px_p li will match any descendednt li element ul.px_s. This will include nested elements which the style should not apply to.
As an side note, sometimes when working in browsers, a cached version of CSS is used and changes you have made may not be reflected. Force a full refresh of the browser page which should reload the full content using CTRL+F5.

Related

Styling nested UL with same class

I have a nested list and I'm having trouble styling the last level UL.
<ul class="same-class">
<li>
<ul class="same-class">
<li>
</li>
</ul>
</li>
</ul>
What I need is to display the first UL items inline, and below them show their children as blocks. The problem is both UL have the same class (I can't change the HTML output, nor add classes), and I can't find the proper selector to target the second UL.
In the example here I tried adding a diferent class to menu 3 and 4, and that does the trick, but since changing class isn't an option I need to find a workaround to make the children display as blocks.
Can someone take a look and advise?
ul ul li { display: block; } or .same-class .same-class li { display: block; } should do the trick - that'll select all li that are a child of two or more ul or .same-class
This might be useful (attribute selectors) depending on what your real code looks like (most likely useful if you're using AngularJS or something similar) or the nth-child might be good too because I'm not 100% sure what you mean.
Hope this helps!
If you try plugging this in, you should be able to target the various components as you like.
The first selector is targeting all list items that are direct children of the first menu.
The second one is targeting any lists inside of a list item which itself is a direct decendant of the menu class.
The third one is targeting just your list items in your nested lists. It gives a good degree of control for adjusting the layout.
ul.menu:first-of-type > li{
display:inline-block;
}
.menu > li ul {
display:block;
}
.menu:first-of-type > li > ul > li {
display:block;
}
If you was to use CSS parent selectors then try;
ul.same-class li {
display: inline-block;
}
li > ul.same-class li {
display: block;
}
The > in the second rule will select all ul.same-class li elements where it has a li as a parent.

selector in IE7

I'm using css2 to implement some fixes for IE7 on a website.
So I have to put margin-top:30px and margin-bottom:-30px a <h2> title but I dind't find right selector.
<div class="ui-content">
<h2>Text</h2>
<ul class="ui-listview">
List Items
</ul>
</div>
The fact is that Everytime there is a H2 followed by a UL, I must put those two properties, so I wanted to do a selector with h2 and ul, but I don't know wich ones...
Thanks to help me
You can't select h2s followed by uls but you can do it the other way round. E.g.
h2 + ul { /*your css to style the ul*/ }
So you could put fixes/negative margins or whatever on the ul?
This is a only-ie-7 selector:
IE 7 only
*:first-child+html h2 {}
Anyhow, I don't recommend it because almost no one uses this browser anymore, so neither should you program specially for it.
Everytime there is a H2 followed by a UL, I must put those two properties, so I wanted to do a selector with h2 and ul
As stated by #Spudley and #Coop, you can't select an element that is followed by another element (except rare cases with series of li or td or th and :nth-last-child() but it's more of a trick).
The closest thing you can do in pure CSS is testing if h2 is followed by (an)other element(s) or not, i.e. if it's not alone with :only-child pseudo.
From MDN:
The :only-child CSS pseudo-class represents any element which is the only child of its parent. This is the same as :first-child:last-child or :nth-child(1):nth-last-child(1), but with a lower specificity.
Support is IE9+ so if you want to style this element in IE7 and IE8 too (or in the precise case where it's followed by ul but not p or h3...), you'll need JavaScript or to add a class server-side and style this class.
.ui-content > h2:not(:only-child) {
margin-top: 30px;
margin-bottom: -30px;
}
EDIT:
You can also test if H2 is both the :first-child and the second-to-last child of its parent so it'll be styled if it's followed by whatever element but not if this second element has other siblings (third, fourth one, etc)
.ui-content > h2:first-child:nth-last-of-type(2) {
margin-top: 30px;
margin-bottom: -30px;
}
Simplest code would be ;)
<div class="ui-content">
<h2 class="followed-by-list">Text</h2>
<ul class="ui-listview">
List Items
</ul>
</div>
.followed-by-list {
margin-top: 30px;
margin-bottom: -30px;
}
Other trick that'd mean a complete overhaul of your project (say, for next project ;) ): never set a single margin-bottom to content elements (I mean h2, ul, p, etc. It's OK for div and below "blocks") and always set a margin-top to:
an element (general case) ex: p
if needed, an element coming after another like elt1 + p would have a certain margin-top, elt2 + p another one, etc

Is it possible to select only li element containing a element with class with CSS

I have a simple menu styled with css.
<ul>
<li> 1 </li>
<li> 2 </li>
<li> 3 </li>
<li> 4 </li>
</ul>
Is it possible to apply specific style to li element, containing a with active class.
I've tryed something like this:
#container > ul > li a.active < li {
custom: style;
}
Not possible with CSS. Though this can be achieved with scripting.
Similar question here.
Apply CSS styles to an element depending on its child elements
No, selectors can't match in reverse. In such circumstances the best approach is to simplify the matter.
A elements can be styled as block level elements, so simply push down whatever styles you had on the parent LI to the A elements. You already have your specific selector a.active, that should be distinct enough that you can style them appropriately.
#container ul li a.active{ yourstyle:styleproperties;}
or I think you may want to do like this
#container ul li a:active{ yourstyle:styleproperties;}
if you want dynamically add class to element you can use javascript and jquery
http://api.jquery.com/addClass/
$("#container ul li a").addClass("active");
and for parent(this class will be added for li element which is parent to a.active element)
$('#container ul li a.active').parent().addClass("active");
there is already similar topic Target outer div based on class of inner a
Try this:
ul li a.active{ color:green;}
http://jsfiddle.net/Vloxxity/VZgQx/
Edit:
i've read your comment,
this is only possible if you mark the li with a active class.

CSS selectors ul li a {...} vs ul > li > a {...}

What is the difference between ul > li > a {...} and ul li a {...} in CSS?
Which one is more efficient and why?
">" is the child selector
"" is the descendant selector
The difference is that a descendant can be a child of the element, or a child of a child of the element or a child of a child of a child ad inifinitum.
A child element is simply one that is directly contained within the parent element:
<foo> <!-- parent -->
<bar> <!-- child of foo, descendant of foo -->
<baz> <!-- descendant of foo -->
</baz>
</bar>
</foo>
for this example, foo * would match <bar> and <baz>, whereas foo > * would only match <bar>.
As for your second question:
Which one is more efficient and why?
I'm not actually going to answer this question as it's completely irrelevant to development. CSS rendering engines are so fast that there is almost never* a reason to optimize CSS selectors beyond making them as short as possible.
Instead of worrying about micro-optimizations, focus on writing selectors that make sense for the case at hand. I often use > selectors when styling nested lists, because it's important to distinguish which level of the list is being styled.
* if it genuinely is an issue in rendering the page, you've probably got too many elements on the page, or too much CSS. Then you'll have to run some tests to see what the actual issue is.
ul>li selects all li that are a direct child of ul whereas ul li selects all li that are anywhere within (descending as deep as you like) a ul
For HTML:
<ul>
<li><span><a href='#'>Something</a></span></li>
<li><a href='#'>or Other</a></li>
</ul>
And CSS:
li a{ color: green; }
li>a{ color: red; }
The colour of Something will remain green but or Other will be red
Part 2, you should write the rule to be appropriate to the situation, I think the speed difference would be incredibly small, and probably overshadowed by the extra characters involved in writing more code, and definitely overshadowed by the time taken by the developer to think about it.
However, as a rule of thumb, the more specific you are with your rules, the faster the CSS engines can locate the DOM elements you want to apply it to, so I expect li>a is faster than li a as the DOM search can be cut short earlier. It also means that nested anchors are not styled with that rule, is that what you want? <~~ much more pertinent question.
ul > li > a selects only the direct children. In this case only the first level <a> of the first level <li> inside the <ul> will be selected.
ul li a on the other hand will select ALL <a>-s in ALL <li>-s in the unordered list
Example of ul > li
ul > li.bg {
background: red;
}
<ul>
<li class="bg">affected</li>
<li class="bg">affected</li>
<li>
<ol>
<li class="bg">NOT affected</li>
<li class="bg">NOT affected</li>
</ol>
</li>
</ul>
if you'd be using ul li - ALL of the li-s would be affected
UPDATE The order of more to less efficient CSS selectors goes thus:
ID, e.g.#header
Class, e.g. .promo
Type, e.g. div
Adjacent sibling, e.g. h2 + p
Child, e.g. li > ul
Descendant, e.g. ul a
Universal, i.e. *
Attribute, e.g. [type="text"]
Pseudo-classes/-elements, e.g. a:hover
So your better bet is to use the children selector instead of just descendant. However the difference on a regular page (without tens of thousands elements to go through) might be absolutely negligible.
1) for example HTML code:
<ul>
<li>
firstlink
<span><a href="#">second link</a>
</li>
</ul>
and css rules:
1) ul li a {color:red;}
2) ul > li > a {color:blue;}
">" - symbol mean that that will be searching only child selector (parentTag > childTag)
so first css rule will apply to all links (first and second)
and second rule will apply anly to first link
2) As for efficiency - I think second will be more fast - as in case with JavaScript selectors. This rule read from right to left, this mean that when rule will parse by browser, it get all links on page:
- in first case it will find all parent elements for each link on page and filter all links where exist parent tags "ul" and "li"
- in second case it will check only parent node of link if it is "li" tag then -> check if parent tag of "li" is "ul"
some thing like this.
Hope I describe all properly for you
Here > a to specifiy the color for root of li.active.menu-item
#primary-menu > li.active.menu-item > a
#primary-menu>li.active.menu-item>a {
color: #c19b66;
}
<ul id="primary-menu">
<li class="active menu-item"><a>Coffee</a>
<ul id="sub-menu">
<li class="active menu-item"><a>aaa</a></li>
<li class="menu-item"><a>bbb</a></li>
<li class="menu-item"><a>ccc</a></li>
</ul>
</li>
<li class="menu-item"><a>Tea</a></li>
<li class="menu-item"><a>Coca Cola</a></li>
</ul>
to answer to your second question - performance IS affected - if you are using those selectors with a single (no nested) ul:
<ul>
<li>jjj</li>
<li>jjj</li>
<li>jjj</li>
</ul>
the child selector ul > li is more performant than ul li because it is more specific. the browser traverse the dom "right to left", so when it finds a li it then looks for a any ul as a parent in the case of a child selector, while it has to traverse the whole dom tree to find any ul ancestors in case of the descendant selector

Format li which contain links different from li which contains no links

i have list like that:
<ul>
<li><a...>...</a></li>
<li>...</li>
</ul>
where both type of listelements are there multiple times in arbitrary order.
Is there a way to format those li's differently? (different list-style-image) The only difference is that the one kind contains a link and the other one doesnt.
No, there is no way in CSS to specify a selector depending on the child elements.
You would have to add something to distinguish the li elements themselves, like a class on all li elements that contains links.
If you can use jQUery, you could add the class to the li elements that contains anchor tags:
$('li:has(a)').addClass('linkItem');
A non-jQuery solution could look like this:
var items = document.getElementsByTagName('LI');
for (var i=0; i<items.length; i++) {
if (items[i].getElementsByTagName('A').length > 0) {
items[i].className = 'linkItem';
}
}
sure. If you give each different li a class you can do it simple. Or you can always do this if you can't use classes.
ul li
{
styles....
}
ul li a
{
styles....
}
The styles in the first class will apply to all li elements and styles in the second class will apply to the < a > tags respectively.
You can't do this with CSS alone, you could use Javascript to accomplish this. Here's an example using jQuery:
$('ul li a').each(function() {
$(this).parent().css('list-style-image', 'url("/path/image.gif")');
});
This will set the style for the li tags, not the a tags. Technically, the list-style-image property is supposed to be set for ul tags, not li, but most (all?) browsers handle it the way you would expect when you style the li tags individually.
Hello there
I would add a <p></p> tag like this:
<ul>
<li><a...>...</a></li>
<li><p></p></li>
</ul>
And then apply 2 different styles like this:
ul a {display:block; padding:3em; background: #ccc;}
ul p {display:block; padding:3em; background: #aaa;}
I would not recommend using javascript for this, some people block javascript ect. but it depends. I would perfer css/html.
Edit:
For some reason you can write <p></p> without making it code - Fixed
Also I might have overlooked that you wanted to apply list-style-image, then this will not work.
This is what classes are for. In HTML:
<ul>
<li class="linked"><a...>...</a></li>
<li>...</li>
</ul>
and in CSS
ul li {...}
ul li.linked {...}

Resources