Trouble understanding the not:(:last-child) selector [duplicate] - html

This question already has answers here:
Can I combine :nth-child() or :nth-of-type() with an arbitrary selector?
(8 answers)
Closed 2 years ago.
I’m new to HTML/CSS and I’m having a bit of trouble understanding how the :not(:last-child) selector works. I’ve read the explanation on MDN and it’s a bit over my head so I was hoping for a simpler explanation. I’ve written this code to better illustrate my issue:
<html>
<head>
<style>
.paragraph:not(:last-child) {
background: #ff0000;
}
</style>
</head>
<body>
<p class="paragraph">The first paragraph.</p>
<p class="paragraph">The second paragraph.</p>
<ul class="list">
<li class="list_item">List 1</li>
<li class="list_item">List 1</li>
<li class="list_item">List 1</li>
<li class="list_item">List 1</li>
</ul>
<div class="new_div">
<p class="test123">Hello World!</p>
</div>
</body>
</html>
The way I understand it the line, .paragraph:not(:last-child) { background: #ff0000; } should tell CSS to apply a red background to every element with the class “paragraph” except the last one. The behaviour I should see is a red background applied to the first paragraph and nothing else.
However, CSS applies a red background to both paragraphs. It’s almost as if CSS is classing the unordered list as a paragraph and treating that as the last child or something. But I can’t see any reason why it would do that.
If anyone could explain how this behaviour makes sense I’d be very appreciative. Please bear in mind I’m very much a beginner so ELI5 if possible 😊
Thanks.

You are very close! Last child pseudo requires the count of items within a context, in your code you are saying all paragraphs but not limiting the set so the browser doesn't know which to style.
I've updated your code to contain the paragraphs in a div and now the last paragraph is not styled with a red background. I had not thought to put a pseudo in a not pseudo so I learned something too. :)
For example if you want to do the same with the unordered list you can do all unordered list li's or use the list class to isolate lists with that class for this style. This is because li's are counted intrinsically, which means the browser knows how many there are already.
.container .paragraph:not(:last-child),
ul.list li:not(:last-child),
.new_div p:not(:last-child) {
background: #ff0000;
}
<div class="container">
<p class="paragraph">The first paragraph.</p>
<p class="paragraph">The second paragraph.</p>
</div>
<ul class="list">
<li class="list_item">List 1</li>
<li class="list_item">List 1</li>
<li class="list_item">List 1</li>
<li class="list_item">List 1</li>
</ul>
<div class="new_div">
<p class="test123">Hello World!</p>
<p class="test123">Hello World!</p>
</div>

Related

What priority are CSS styles applied? Example provided that is confusing me

I know this should be a stupidly easy topic, but I'm confused and I spent way longer than I should trying to understand this example that my professor gave us.
From what I understand, the rules are supposed to be that you go first for inline css, then document css, then external css, and then priority. The priority was from what I thought 100*IDs+10*Class+1*Element reference.
Here is the code that's really confusing me below:
<div id="id1">
<ul>
<li class="c1" id="id2">Item 1</li>
<li class="c2 c3">Item 2</li>
<li class="c3">Sublist:
<ul>
<li class="c1">Subitem 1</li>
<li class="c2">Subitem 2</li>
<li class="c2" id=”id3”>Subitem 3</li>
</ul></li>
<li>Item 4</li>
</ul>
<div id="id4">
<ul>
<li id="id5">One thing</li>
<li id="id6" class="c2">And another thing</li>
<li id="id7" class="c1">A third thing.</li>
</ul>
</div>
</div>
<style>
div > li
{
color: yellow;
}
.c2
{
color: red;
}
ul li+li+li
{
color: green;
}
#id1, #id4
{
color: orange;
}
#id7
{
color: blue;
}
</style>
In the above code though, item 2 is red, sublist(+subitem1) are green, etc. How is that possible? Why isn't everything coming out orange? Shouldn't the #id1 style be applied to everything automatically since it is the only one with an ID specifier(and everything is a child of div with id="id1"?
The priority formula you wrote is ok if you have two rules to same element.
In css child element inherits from parents the colors, like in your example.
If new rules, despite having a lower specificity number, is applied to child, this override the inheritance.
Anyway read this: https://css-tricks.com/specifics-on-css-specificity/
An element's style overrides it's inheritance.In cases when a style was not defined we will prefer inherited value over default.
There is misunderstanding.
It did orange at first place to all tags .but later as some of the tags are defined different according to css, then it changes to specified color that you mentioned in css.
For CSS types:
http://webdesign.about.com/od/css/qt/aatypesofcss.htm
edited.

Collapsable menu CSS only

I am trying to create this layout in CSS3
The image on top-left should collapse the vertical menu and show only the images. This should be animated, so it smoothly collapses. I want to do a CSS only solution, no JS/JQuery, no Bootstrap if at all possible. When collapses, the green and yellow boxes should move left as well. Both blue and green boxes should be fixed and the yellow one scrollable.
This has some potential features I want. This is not exactly what I want, and it does not work in my browser.
I am not sure how I can make, with CSS only, the top-left image link to resize the vertical menu, hide only the text of the links (which is not under a span, since I dislike to use it for presentation only), and change its own image. Of course, by clicking again on the new top-right image it should "de-collapse".
One problem I have is that I used padding for the green and yellow boxes as this Website does, and this seems incorrect to me. They should automatically be readapted to the new layout, without having to toggle the padding.
I have created a JSfiddle.
<body>
<header>
<nav>
<a href="#">
<img src="logo.png" alt="logo">
</a>
<ul>
<li><img src="option1.jpg">Option 1</li>
<li><img src="option2.jpg">Option 2</li>
<li><img src="option3.jpg">Option 3</li>
</ul>
</nav>
</header>
<main>
<nav>
<ul>
<li>LINK</li>
<li>LINK</li>
<li>LINK</li>
</ul>
</nav>
<h1>Main title</h1>
TEXT TEXT TEXT
</main>
</body>
Any help is appreciated.
EDIT:
Browser support - I would like to address mainly modern browsers, so I will not care much about old IE tricks.
It seems that it is not possible to do it with only CSS (I kind of felt that from my old CSS experience, but was not sure if recent improvements had gone so far to allow it). If JS/JQuery is required, I guess the solution is to capture the click on the image and change the DOM. Not sure how the animation can be done though. And what about the basic layout? Is there a way to keep green&yellow on the left side, close to the blue box, without padding them differently depending on collapse?
The most common way to achieve a toggle without JS is using the checkbox hack. Here is a simple example to get you started (clicking menu will toggle the list style):
.main_nav__checkbox {
position: absolute;
top: -1000em;
}
.main_nav__checkbox:checked ~ ul {
background: red;
}
<nav>
<input type="checkbox" name="togglenav" id="togglenav" class="main_nav__checkbox" aria-label="Toggle Menu" />
<label class="main_nav__toggle" for="togglenav">Menu</label>
<ul>
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
</ul>
</nav>
Note that there are reasons that this isn't used often:
It is 'hacky'
It relies on the :checked attribute ( IE9+ )
It relies on the label checking the checkbox ( a firefox bug made this difficult in the past)
ya, as mentioned in above answer i've edited your fiddle made it work with that 'hacky' checkbox :checked css selector. but i'm unable to animate it though
try modifying the fiddle or i'll update the answer if i can get the animation to work!!!
FIDDLE

Is there any way I can change an div element in an outside div with css

I have this list
<nav>
<ul>
<li>list el</li>
<li>list el</li>
<li>list el
<ul>
<li>inside</li>
<li>inside2</li>
</ul>
</li>
</ul>
</nav>
<section>
<img src="#">
<h1>Some Title</h1>
</section
And I am using :focus to display the dropdown list on click, without using JS. Everything is ok for now. But I would like to,change the color of the entire section when the dropdown list is active (through :focus).
Is there any way I could do that entirely with css? I am trying to use as little JS as possible (definetly no jQuery)
Yes you can, without the slightest bit of JS, using the Radio Hack. Basically, use a label as your "focused" element. This label should have its for attribute refer to an input type="radio" that is hierarchically above the elements that you want affected. Then just use the following css selector #myradio:checked ~ #mysection{ }.
More details here: https://stackoverflow.com/a/21939282/2306481
If you are open to changing from using :focus to using :target then yes you can.
It is not clear from your question how you are implementing your drop-down behaviour, but this is a simple example, that should explain how you can approach it. (only the third item has a drop down, but all three links should change the background colour).
The behaviour of :target is a little different to :focus however, so things that you need to be aware of are:
target will change the URL, creating a history point.
target will retain the "focus" even if the user clicks on a different element, the only time a target is lost is when another target is targeted.
li ul {display: none;}
#dd1:target { background: gold; }
#dd2:target { background: green; }
#dd3:target { background: red; }
#dd3:target .dd3 {display: block;}
<div id="dd1">
<div id="dd2">
<div id="dd3">
<nav>
<ul>
<li>list el</li>
<li>list el</li>
<li>list el
<ul class="dd3">
<li>inside</li>
<li>inside2</li>
</ul>
</li>
</ul>
</nav>
</div>
</div>
</div>

CSS Menu Drop down expanding Div Container

Having problems with my CSS menu drop-down as instead of overlapping the containers its expanding them. Probably very simple oversight but can't find the answer (closest match was Div within li not expanding but the suggestion of putting an absolute position to the submenu class didn't work). Also there is no JS.
Here is the JSFiddle Link : http://jsfiddle.net/KNBLC/
HTML
<body>
<div class="secondary-content-6col">
<h1><span class="white">Headline</span></h1>
<ul class="yellow-call-to-action">
<li>1. Select a Product <img src="../img/arrow-small.png" alt="arrow"/>
<ul>
<li>Item 1
</li>
<li>Item 2
</li>
<li>Item 3
</li>
</ul>
<!--- 1st column Footer -->
</li>
</ul>
</div>
<p> </p>
Change this in your css
.secondary-content-6col {height:150px;}
You need to set a height to that div, else it wil see the height as
height:auto;

Why don't UL bullets stay within their containing DIV?

I have a really simple set up:
<div class="container">
<ul>
<li>Item one</li>
<li>Item two</li>
</ul>
</div>
I had assumed that all contents and the bullets of the UL would be within the div, but currently this is not the case.
The bullet points for the UL appear outside of the div and effectively disappear when overflow is hidden.
To me this is somewhat broken and cross browser compatible, and I've scanned the HTML spec but couldn't find anything saying this should happen.
Is there a CSS fix for it or other layout fix?
You'll want to use list-style-position:
ul {
list-style-position: inside;
}
list-style-position: inside works great unless your bullet points will need multiple lines on small screens as your text will align with the bullet point rather than where the text begins.
Keeping the default text-align: outside, allowing for a small margin and aligning the text to the left to override any centered containers gets around the bullet point alignment problem.
ul, ol {
margin-left: 0.75em;
text-align: left;
}
You usually lose the list decorations to the overflow of a div when your UL/OL and LI don't have enough padding, or you are floating elements or display: inline.
Try adding some padding/margins to your list items (LI element).
Are you floating your List items to the left or right? If so then the following will solve your problem.
<div class="container">
<ul>
<li>Item one</li>
<li>Item two</li>
</ul>
<div style="clear:both;"></div>
</div>
For some cases, using two divs can help.
<div class="container">
<div style="margin: 3%">
<ul>
<li>Item one</li>
<li>Item two</li>
</ul>
</div>
</div>
This kind of problems can usually be fixed using a good reset.css and re-writing all the information such as list-style and so on.
if using float property on list make sure you only add the style the the selected list and not all list elements on the page.