I'm trying to create a dropdown menu using CSS, it's centered around using the following:
#submenu_div {
display: none;
}
#li_id:hover + #submenu_div {
display: block;
}
EDIT:
Here's the fixed HTML for the entire thing.
<ul id="main_nav">
<li id="li_id">Home</li>
<ul id="sub_who">
<li>Foo</li>
</ul>
</ul>
The #submenu_div is outside the parent div for the ul in which the li the previous code refers to resides. As far as I know, this should work. But I'm obviously doing something wrong, any ideas?
The #submenu_div is outside the parent div for the ul in which the li the previous code refers to resides.
The + combinator looks only for a true sibling element, i.e. an element with the same parent as whatever matched the left-hand side of the +. You cannot make it match anything else. You will need to change either your HTML (so that #submenu_div is a true sibling of #li_id) or your CSS (so the thing on the LHS of the + is a true sibling of #submenu_div) or both.
Without seeing the structure of your HTML I cannot give more precise advice.
Related
I have tried both nth-of-child and nth-of-type a few times and read documentation on w3schools, css-tricks and mdn but can't figure this out.
It has worked for me in the past but now either nothing happens or all the spans get the css rule applied to them.
I'm just trying to add extra bottom padding to the first, second and eighth with this following markup (repeated 8 times and all lis enclosed in parent ul:
<li class="campaign-links__list-item">
<a class="campaign-links__link " href="/feast-on-london-under-25" id="104014" data-analytics="Category|£25 and Under|offpage">
<img class="campaign-links__image opt-new--campaign-image" src="//img.static-bookatable.com/images/batweb/bat/sub-themes/feast-on-london/feast-on-london-under-25/hero.jpg?width=451&height=150&quality=80&mode=crop" alt="£25 and Under" width="94" height="94">
<span class="campaign-links__text opt-new--campaign-text" style="padding-bottom: 29px;">£25 and Under</span>
</a>
</li>
This is the CSS I've tried:
.opt-new--campaign-text:nth-of-child(1), .opt-new--campaign-text:nth-of-child(2), .opt-new--campaign-text:nth-of-child(8) {
padding-bottom: 29px;
}
.opt-new--campaign-text:nth-of-type(1), .opt-new--campaign-text:nth-of-type(2), .opt-new--campaign-text:nth-of-type(8) {
padding-bottom: 29px;
}
Many thanks in advance!
There's no such thing as nth-of-child, use nth-child. However you are selecting for the opt-new--campaign-text class which is a span. This span is the first child of type span, and second child of an a element.
What you're probably looking for is:
.campaign-links__list-item:nth-child(1) .opt-new--campaign-text {
padding-bottom: 29px;
}
and so on. This selects the first (in this case li) child of the ul element, finds the .opt-new--campaign-text descendant, and adds padding to it.
If I'm understanding you correctly, you're repeating the li.campaign-links__list-item block here? nth-child looks at child elements of the parent element, but .opt-new--campaign-text isn't repeated within it's immediate parent.
Something like this should work:
.campaign-links__list-item:nth-child(1) .opt-new--campaign-text, .campaign-links__list-item:nth-child(2) .opt-new--campaign-text, etc...
So I have a question about the css selectors in reference to my design.
I'm trying to fiddle around with how you can manipulate check-boxes through css by using multiple selectors such as "+", "~", etc to perform an event when the checkbox is either checked or unchecked.
I'm confused as to why this doesn't work, or by using "~" instead since from my understanding "+" selects elements matching it directly after the first element while "~" selects every element that comes after the prior element. This is my first time playing around with it so I'm not the best...but I'm trying to wrap my head around it. Does "element":checked not count as a reference point when stringing multiple selectors? I left two tried on the jsfiddle.
While this is intended to be a navigation menu later, I just, for the time being, left it like this to get a hang of selectors first.
HTML
<div id="container">
<header>
<input type="checkbox" id="navigation_drawer">
<label for="navigation_drawer" id="drawer_open"></label>
<label for="navigation_drawer" id="drawer_close"></label>
<nav id="navigation">
<ul>
<li id="home_page">Home</li>
<li id="about_page">About</li>
</ul>
</nav>
</header>
</div>
CSS
label#drawer_open{
position: absolute;
top: 2;
right: 0;
margin-right: 1rem;
background-image: url('http://i.imgur.com/Nxafddw.png');
background-image: no-repeat;
width: 35px;
height: 23px;
}
#navigation{
background-color:blue;
}
#navigation_drawer:checked + #container #navigation{
background-color:red;
}
#navigation_drawer:checked + container #navigation{
background-color:red;
}
Thanks!
Edit: Man you guys are harsh xD Yes, I did make some mistakes copying and pasting this into here and in my code itself when I was changing it around. My fault. Here is an updated fiddle of the original problem for reference. I updated the HTML/CSS here as well. Thank you Pete for the updated fiddle. I would give it to you but since it's a comment instead of a reply I'll accept the other person's since it's another way as well. Thanks :D
https://jsfiddle.net/y9x8accc/6/
Your code doesn't work because the + (Adjacent Sibling Selector) selects the element that immediately follows it. In this case, the immediate element after your checkbox is your #drawer_open label, not the nav.
Adjacent Sibling Selector This is referred to as an adjacent selector or next-sibling selector. It will select only the specified element that immediately follows the former specified element.
You seem to have incorrect indentation for your labels, so perhaps that made you think the nav is the direct sibling. In any event, you'd need to use the General Sibling Selector (~).
The correct code to achieve what you want would be:
#navigation_drawer:checked ~ #navigation{
background-color: red;
}
Fixed fiddle
I have the following html structure:
<div class="nav-collapse">
<ul class="nav">
</ul>
<ul id="registerCart" class="nav pull-right">
</ul>
</div>
and I wanted to apply the following rule only to the first nav, so I did:
.nav-collapse > .nav {
left: 135px;
}
however this is applying to the registerCart as well. How do I apply this only to the first nav?
Use the first child selector:
.nav-collapse .nav:first-child {}
You can combine it with the direct child selector if you have more nested .nav elements.
.nav-collapse > .nav:first-child {}
The > operator means that it will select only the matching children that are a direct child (thus one level deep) of the defined parent, instead of matching all children on all levels from the defined parent.
Using :first-child is perfectly ok but some problems could arise in IE7 and IE8 when dynamic content is involved. See http://www.quirksmode.org/css/selectors for known issues. When in doubt, select the first child by it's class or id attribute.
If you change the class 'nav' to 'nave' it works as is! I suspect 'nav' is a reserved word.
we have a partial html:
<ul>
<li class="class1">AFFECTED</li>
<li class="class1 class2">NOT</li>
<li class="class1">NOT</li>
</ul>
<ul>
<li class="class1 class2">NOT</li>
<li class="class1">AFFECTED</li>
<li class="class1">NOT</li>
</ul>
<ul>
<li>NOT</li>
<li class="class1">AFFECTED</li>
<li class="class1">NOT</li>
</ul>
I need a universal css-selector for the first li's of any list with only class1.
li's with extra classes (class2) MUST NOT be affected.
only first li with class1 should be selected (to change the
appearance of A.
no JS/jQuery.
li's are float, so no hard coded nth-child.
code is generated automatically, so no way add/remove custom classes.
I've tried to use :not(class2), [class2] :first-child & :first-of-type but with no avail.
Thanks!
Solution: http://jsfiddle.net/6hxZa/3/
You should be able to capture only the elements with .class1 and no other using this selector:
li[class="class1"]
You won't be able to match only the first out of these elements because there isn't a selector to do that. :first-child only selects the very first child within the ul regardless of what classes it has, and :first-of-type selects the first li, also regardless of its classes (effectively making it the same as :first-child for li elements). You'll have to use the technique given here (where it also explains why these two pseudo-classes don't work) to apply the rule to all such elements then undo it for subsequent ones:
li[class="class1"] {
/* Apply styles... */
}
li[class="class1"] ~ li[class="class1"] {
/* ... and remove them after the first */
}
Note that the same selector is used so both classless elements and elements with .class2 are completely unaffected.
This jsFiddle demonstrates the desired effect with the provided HTML: http://jsfiddle.net/Cmypc/4/
If you want to specifically exclude class2 from the selector, use:
li.class1:first-child:not(.class2) { }
If you want to exclude any additional classes other than class1 use:
li[class=class1]:first-child { }
I would recommend the first if you know which class(es) you're excluding as it will interfere less with other/future styles.
jsFiddle of #1: http://jsfiddle.net/Cmypc/
jsFiddle of #2: http://jsfiddle.net/Cmypc/1/
EDIT If you're looking for a :first-of-class selector, there isn't one (see this thread). A future solution may be the :nth-match selector but you'll have to wait for CSS4. Alternatively, you can use a more elaborate clearing selector to undo the styles applied (see BoltClock's answer) as a workaround.
Try this
li:first-child
{
...
}
this is only for class 1
li.class1:first-child
{
color:#ff0000;
}
and here is a fiddle
and if you dont want the list with class2 to be affected
maybe this can work for you
li.class1.class2:first-child
{
...
code that will reset
}
Given a list of elements like this:
<ul>
<li class="favourite"></li>
<li class="favourite"></li>
<li class="favourite"></li>
<li></li>
<li></li>
<li></li>
</ul>
I would like to create a gap between the list elements which have .favourite and those which don't.
Is there a way I can do this with CSS?
Edit
Assume that elements with the class .favourite are always forced to the top of the list.
You can apply a margin to a li that's not .favourite, that comes right after a li.favourite. You will need to use :not() in conjunction with an adjacent sibling selector, like this:
li.favourite + li:not(.favourite) {
margin-top: 1em;
}
If it's not known in your actual markup whether classless elements come first or li.favourite elements come first, and you want to create a gap regardless of the order, extend the selector like this to cover both cases:
li.favourite + li:not(.favourite), li:not(.favourite) + li.favourite {
margin-top: 1em;
}
Use a left margin instead of a top margin if your list flows horizontally from left to right.