Prevent CSS inheritance to children of the selected element - css

I have a menu consisting of nested ULs and LIs, eg:
.wrapper > ul:first-child > li:last-child {
color: red;
}
<div class="wrapper">
<ul>
<li>Lorem</li>
<li>Ipsum</li>
<li>Dolar</li>
<li>Style me!
<ul>
<li>Lorem</li>
<li>Don't style me!</li>
</ul>
</li>
</ul>
</div>
I want to add a style to the last <li> of the first <ul>, but not have it's children (the nested <ul>) inherit it.
I have tried:
.wrapper > ul:first-child > li:last-child {/*styles*/}
but this still styles the last element.
Would anyone know how I can target just that 1 element (with just CSS)?

Some CSS properties are inherited and you can't prevent that.
Inheritance propagates property values from parent elements to their children.
Some properties are inherited properties, as defined in their
property definition table. This means that, unless the cascade results
in a value, the value will be determined by inheritance.
However, you can override that by selecting the children and restoring the desired value.
.wrapper > ul:first-child > li:last-child {
color: red;
}
.wrapper > ul:first-child > li:last-child > * {
color: initial;
}
<div class="wrapper">
<ul>
<li>Lorem</li>
<li>Ipsum</li>
<li>Dolar</li>
<li>Style me!
<ul>
<li>Lorem</li>
<li>Don't style me!</li>
</ul>
</li>
</ul>
</div>

Related

Add dropdown arrow indicators to menu items that have submenus only?

I am currently trying to add arrow indicators on my navigation menu for items which have submenu options.
Currently I am using this CSS:
.mainNav li > a:after {
color: #444;
content: ' ▾';
}
But this adds a dropdown arrow to every <li> regardless of if there is a submenu or not. Is there a way with just CSS to only add this arrow to items that have sub-items?
Thanks!
No. CSS has no contains child selector. You'd probably be better to just add a class to the li element. For example:
<li class="has-child">
The Link
<ul class="child">
<li>Child 1</li>
</ul>
</li>
Your CSS selector would in turn look like:
.mainNav li.has-child > a:after {
color: #444;
content: ' ▾';
}
You could have jQuery add the class for you, if that's an option:
$('.mainNav li:has(ul)').addClass('has-child');
jsFiddle Demo
CSS has no contains child selector.
However it has various sibling selectors, only-child and not(:only-child)
Since you add indicator to the anchor, use following CSS
.mainNav li>a:not(:only-child):after {
color: #444;
content: ' ▾';
}
<div class="mainNav">
<li>
The item with child
<ul class="child">
<li>Child 1</li>
</ul>
</li>
<li>
No child item
</li>
</div>
Yes you can without any jQuery : https://css-tricks.com/targetting-menu-elements-submenus-navigation-bar/

How to select a very last <li> in unknownd multi level <ul>

is there a possibility to select just a single last <li> in each multi-level list?
<ul class="root">
<li>no</li>
<li>no</li>
<li>yes</li>
</ul>
<ul class="root">
<li>no</li>
<li>no</li>
<li>
<ul>
<li>no</li>
<li>yes</li>
</ul>
</li>
</ul>
​
Free playground on jsfiddle:
http://jsfiddle.net/dizzyn/KMY3U/
Yes you can, use :last-child CSS selector..
My fiddle
CSS
ul li:last-child {
color: #ff0000;
}​
li {
color: #000000;
}​
You can also use this :
CSS
ul li:nth-last-child(1) {
color: #ff0000;
}
li {
color: #000000;
}​
:last-child selector selects every element that is the last child of its parent.
Note : This was a CSS3 implementation, so some browser's will ignore this but wont spoil anything cuz you are just changing the color..

Selecting an adjacent's child... how?

trying to select an adjacent's child element with CSS... not really sure how to
This is the HTML structure
<ul>
<li>
<a href="#">
<span class="icon"></span>
First level
</a>
<ul>
<li>
Second level
</li>
</ul>
</li>
</ul>
I want to say that there is a menu with multiple levels. When theres a UL existing within a LI then the needs to have a dropdown/expand icon... so I thought if I use the adjacent selector I can determine if this level has kids to expand and this is what I thought would work but didn't:
ul li a ~ ul .icon {
// doesnt work
}
ul li a .icon ~ ul {
// doesnt work
}
This works but I need to target the .icon
ul li a ~ ul {
// works
}
Cheers, Dom
Building upon my comment on your question. If you have control over how the HTML for the menu is generated, a workaround would be to add an extra class to each li-element that has a sub-menu. Like this:
<ul>
<li class="has-submenu">
<a href="#">
<span class="icon"></span>
First level
</a>
<ul>
<li>
Second level
</li>
</ul>
</li>
</ul>
Then you could use a selector like this:
.has-submenu .icon {
/* Do your stuff here */
}
ul is a child of li, not the anchor. So ul li ul .
If you want to select it as a sibling, then ul li a + ul

css3 last-child not working as expected

I have match listings dynamically generated. After each member I display a li that displays VS within it. However the very last ul li in the div match shouldnt be visible. Any ideas how I can do that?
HTML
<style>
.match {
}
.match ul {
}
.match ul li {
float: left;
margin-right: 50px;
}
.match ul li:last-child {
display: none;
}
</style>
<div class="content">
<div class="match">
<ul>
<li>Wade Barrett</li>
<li style="">VS</li>
</ul>
<ul>
<li>Shaemus</li>
<li style="">VS</li>
</ul>
<ul>
<li>Randy Orton</li>
<li style="">VS</li>
</ul>
<ul>
<li>John Cena</li>
<li style="">VS</li>
</ul>
<ul>
<li>Edge</li>
<li style="">VS</li>
</ul>
<ul>
<li>Chris Jericho</li>
<li style="">VS</li>
</ul>
<p class="clear"></p>
</div>
</div>
The :last-child pseudo-class should apply to the ul, not li, because you want VS text of the last ul of the list to be hidden. By applying the pseudo-class to li, you're applying styles to the last li of every ul, which is incorrect.
You should also apply a class attribute to the li elements with the VS text so that it's more convenient to match with a class selector.
Change
<li style="">VS</li>
to
<li class="vs">VS</li>
And use this instead of your current :last-child selector:
.match ul:last-child li.vs {
display: none;
}
What browser are you using, IE does not support it. The latest version of the other browsers do, but I would recommend placing a class on it to make it 100%.

CSS Positioning and Display Order

I have a block of HTML:
<ul>
<li>a</li>
<li>b</li>
<li class="nav">c</li>
<li class="nav">d</li>
</ul>
and a CSS ruleset:
ul li {
display: inline;
}
li.nav {
float: right;
}
which are not behaving to my intentions: I want it displayed like so:
ab cd
but instead it's
ab dc
the difference being the displayed order of elements. How do I have the list items of class "nav" be displayed in their syntactical order?
Well, the obvious quick fix is to just reverse the order of the elements in the list:
<ul>
<li>a</li>
<li>b</li>
<li class="nav">d</li>
<li class="nav">c</li>
</ul>
I'm guessing what happens is that whenever the rendering engine encounters an element with float:right it pushes that element as far to the right as possible. So it first encounters the "c" and pushes that all the way over to the right, then it encounters the "d" and pushes that as far right as possible - but the "c" is already occupying the rightmost spot, so "d" stays to its left. Essentially, the elements are laid out in right-to-left order rather than left-to-right order.
Another option, I think, would be to divide the elements into two lists and just apply the float: right style to the second list as a whole (i.e. to the <ul> element).
<ul>
<li>a</li>
<li>b</li>
</ul>
<ul class="nav">
<li>c</li>
<li>d</li>
</ul>
and
ul li {
display: inline;
}
ul.nav {
float: right;
}
That way the list itself would float to the right margin but the order of the elements in it wouldn't be reversed.
I fixed this issue by separating the list into two and floating them to their respective positions. I wrapped the two lists with a div and applied overflow: auto to it. My final CSS code looked like this:
ul li {
display: inline
}
div.post-info-wrap {
overflow: auto
}
ul.post-info {
float: left
}
ul.nav {
float: right
}
and my markup like:
<div class="post-info-wrap">
<ul class="post-info">
<li/>
</ul>
<ul class="nav">
<li/>
</ul>
</div>
If you want c & d to be displayed in a block at the right, you'll have to put them inside one block element, not setting the float attribute on both.
I don't think that list elements like <li> are the right choice for your intention. You don't want to display a single list, so you may try using two lists (where one of them has the float attribute) or just simple <div> elements.
So actually you want a nav list and some other list? Why not use 2 lists?
<ul class="other">
<li>a</li>
<li>b</li>
</ul>
<ul class="nav">
<li>c</li>
<li>d</li>
</ul>
And css:
ul li {
display: inline;
}
.other{
float:left;
}
.nav {
float: right;
}
Float the ul where you want the content/container situated and float the li in the order you want it displayed.
<div id="myblock">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div>
CSS
#myblock ul {
display:inline;
float:right;
}
#myblock li {
float:left;
}
The opposite (float to the left but in reverse order)
#myblock ul {
display:inline;
float:left;
}
#myblock li {
float:right;
}
Try this:
ul {
text-align: right;
}
ul li {
display: inline;
}
ul li.default {
float: left;
}
li.nav {
float: auto;
}
<ul>
<li class="default">a</li>
<li class="default">b</li>
<li class="nav">c</li>
<li class="nav">d</li>
</ul>

Categories

Resources