CSS first GENERATION div but not second selector - css

I want to match the first generation division elements (all of them) but NOT any of THEIR children. So if I used the selector to apply a border 1 (as below visually) would gain the container however 2 (as below visually) would NOT gain the container. How do I construct that selector please?
<div id="container">
<div>1<div>2</div></div>
<div>1<div>2</div></div>
<div>1<div>2</div></div>
</div>

#container > div {
border: 1px solid #f0f;
}

The best way is using the immediate child selector (>):
#container > div {
border: 1px solid red;
}
(IE6 does not support this)

The selector for that is:
div#container > div
or just
#container > div
I really like the SelectORacle to help understand CSS selectors. More on Child Selectors from Eric Meyer.
UPDATE FOR Microsoft Internet Explorer 6
If support for > is a concern, as in the case of MSIE6, the traditional way I used to handle it was to set the styles for the first generation, then unset them for every other descendent generation. So, like this:
#container div { border: 1px solid #000; }
#container div div { border: none; }
#container div div div { border: none; }
#container div div div div { border: none; }
You do that with as many generations down as you need to do. In the above I allow 3 more levels of nesting (enough?) It is not pretty, but it is reliable.

Since one browser in particular (IE6) does not support the child selector >, you could use descendent selectors instead to add a border to the first descendant and remove it from the descendent's descendent.
HTML
<div id="container">
<div>1
<div>2</div>
</div>
<div>1
<div>2</div>
</div>
<div>1
<div>2</div>
</div>
</div>
CSS
#container div {
border:1px dashed grey;
}
#container div div {
border:none;
}
If IE6 is a browser you do need to support then the > selector as already answered is the simplest way to style the child.

Related

Create pseudo elements, but exclude specific elements (with not:nth-child)

I want to set a pseudo element border on some containers, but exclude the third one. I thought I could combine the pseudo selector with :not , like: div:before:not(nth-child(3)), but it doesn't seem to work.
So is the :not selector incompatible with pseudo selectors? In that case, how can I make it work putting pseudo elements and exclude some specific elements?
(By the way, the idea with pseudo element borders is to control the borders so that they stay on top regardless if there are any overlays on top (haven't seen if it works though)
Here is a fiddle: (there are no visible borders because of the not:(nth-child(3)) selector)
Fiddle
Here is the code from the fiddle:
HTML:
<div class="ctr">
<div>
<div></div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
</div>
</div>
CSS:
.ctr > div div{
float:left;
width:100px;
height:100px;
background:black;
/*border:green 3px solid; */
}
.ctr > div:after{
content:"";
display:block;
clear:both;
}
.ctr > div div{
position:relative;
}
/* only if I remove ":not(:nth-child(3))" , the pseudo selector will appear: */
.ctr > div div:before:not(:nth-child(3)){
content: "";
display: block;
z-index: 2;
position: absolute;
left:0;
right:0;
bottom:0;
top:0;
height: 100%;
width: 100%;
border-right: 0.35em red solid;
border-bottom: 0.35em red solid;
}
Are you trying to create a ::before pseudo-element for all but the third child?
If so, the :not() pseudo-class needs to come first, since pseudo-elements can only appear at the very end of a selector (and this is why the made-up term "pseudo-selector" is dangerous to use, because you can't group pseudo-classes and pseudo-elements into a single umbrella term given their syntactic differences):
.ctr > div div:not(:nth-child(3))::before
Since you're using CSS3 pseudo-classes anyway, pseudo-elements should be indicated with double colons to further cement the difference between the two.
See also: How to write :hover condition for a:before and a:after?
I hope this will work for you
.ctr > div div:nth-child(3).before{
/*remove properties you don't need on third element*/
}
or you can even hide the pseudo element like below
.ctr > div div:nth-child(3).before{
display: none;
}

setting padding depending on number of child elements

I have a DIV element which may contain 1 or 2 Child DIVs
Is there a way to say of there is 1 Child element then the padding should be 15px otherwise 5px
It may like
<div class="container">
<div><strike>7.00</strike></div>
<div>5.00</div>
</div>
or
<div class="container">
<div>7.00</div>
</div>
You can do a trick using margin in the children to get the same effect:
.container div:only-child {
margin: 15px;
}
div {
border: solid 1px red;
}
div div {
margin: 0 5px;
border-color: green;
background: #ccc;
}
div div:first-child {
margin-top: 5px
}
div div:last-child {
margin-bottom: 5px
}
<div class="container">
<div><del>7.00</del></div>
<div>5.00</div>
</div>
<div class="container">
<div>7.00</div>
</div>
PS Use del tag instead strike that is deprecated
No, there is not.
CSS does have some complex quantity queries but these will only style the children based on their number.
It is not (currently) possible to style the parent based on the number of children as there is no Parent Selector
Based on how old this original thread is I'm not providing exact solutions, however, CSS Tricks put a great article together covering Logical CSS styling. You can find the article here.

first-child not affecting the first element as expected [duplicate]

This question already has answers here:
:first-child not working as expected
(5 answers)
Closed 7 years ago.
Why does the rule not affect the first div? (with the "update 1" text)
.update div {
width:100%;
height:25%;
border-top:1px dashed {color:background title};
padding: 5px;
color:{color:links nav};
cursor:pointer;
}
.update div:first-child{
border:none;
}
.update div:hover{
color:{color:links nav hover};
}
.update div:hover > .symbol{
color:{color:links nav};
}
<div class="nav update">
<a><div><div class="symbol">×</div> update 1</div></a>
<a><div><div class="symbol">×</div> update 2</div></a>
<a><div><div class="symbol">×</div> update 3</div></a>
<a><div><div class="symbol">×</div> update 4</div></a>
</div>
There are no divs in your code that are the first child of the .update div. You'd need to do something like this:
.update a:first-child > div {
border:none;
}
Although HTML5 allows block elements like divs inside inline elements, I wouldn't do it myself. Perhaps consider spans instead.
To explain the "first child" concept a little more: in your code, each a element is a child of the .update div. The divs within those a elements are not children of the .update div; rather, they are children of the a elements. Each a element in your code only has one child div, though; and each of those child divs has another child div. So for an element to be a child, it must sit directly inside the parent element—one level down, as it were.
UPDATE
There are some mistakes:
The value of color is a name, 6 or 3 hexadecimal number, or RGB/RGBa, or HSL/HSLa
I've never seen {color:links nav} as a value before... is this actually working?
As #torazaburo and #Ralph.M pointed out, your divs qualify as first-childas well as first-of-type of a only, so your .update is not the direct ancestor (i.e. parent) of any div. Therefore you need more specificity by going through each level of the hierarchy.
div.update.nav
a
div
Try this:
.update a:first-child div:first-of-type
Note: In your circumstance first-child and first-of-type works the same, the difference I can think that might be of concern is if you use first-child and nth-child the n-th variable counts differently than nth-type-of.
The :first-of-type selector in CSS allows you to target the first occurrence of an element within its container.
.update div {
width: 100%;
height: 25%;
border-top: 2px dashed red; /* this is a color name */
padding: 5px;
background-color: rgb(0,0,0); /* this is RGB */
cursor: pointer;
color: rgba(250,250,250,.7); /* this is RGBa */
}
.update a:first-of-type div:first-of-type {
border: none;
}
.update div:hover {
color: hsl(240, 60%, 50%); /* this is HSL */
}
.update div:hover > .symbol {
color: hsla(324, 100%, 50%, .8); /* this is HSLa */
}
<div class="nav update">
<a>
<div>
<div class="symbol">×</div>update 1
</div>
</a>
<a>
<div>
<div class="symbol">×</div>update 2
</div>
</a>
<a>
<div>
<div class="symbol">×</div>update 3
</div>
</a>
<a>
<div>
<div class="symbol">×</div>update 4
</div>
</a>
</div>
See ARTICLE

not selector not assigning to img inside child div

I have some general style rules applied to the images on my website, for example:
border: 5px solid red;
I then want to style some of the <img> tags differently,
However inside a div in the page I don't want the <img> tags to pick up this extra styling, I'm trying to use the not selector like so:
HTML
<div class="no-overflow">
<img src="https://s3.amazonaws.com/uifaces/faces/twitter/rem/128.jpg">
<div class="comment-ctrl">
<img src="https://s3.amazonaws.com/uifaces/faces/twitter/rem/128.jpg">
</div>
</div>
LESS
.no-overflow:not(.comment-ctrl) {
img { border: 5px solid green; }
}
This styling just ends up being applied to all <img> tags, the not selector seems to be ignored. I have been testing in this codepen:
http://codepen.io/JoeHastings/pen/MYrVWK
Is there some CSS syntax that would make this work without changing the DOM itself?
It would probably be easier to use this
.no-overflow > img {
border: 5px solid green;
}
That way it only selects images that are a direct descendant of the class name and won't select images inside other elements.

Using ::after to self clear divs. Is this working right?

I have the following HTML:
<div class="selfClear" style="float: left; border: 1px solid black;">
...floated stuff in here...
</div>
<span style="margin-top: 10px; border: 1px solid purple;">hello world</span>
I'd like there to be a 10px gap between the div and span, per the margin-top. But, since the div above is floated, it won't render that way. The fix to make sure something clear's the DIV. To do that via pure CSS, it appears one should use the '::after' method of inserting content that is then set to clear:
.selfClear::after {
content: ".";
display: block;
height: 0px;
clear: both;
visibility: hidden;
}
.selfClear {
display: inline-block;
}
However, this doesn't quite do what I think it should be doing. If I don't include the height/visibility styles so that I can actually see the period as it is inserted, I see that it's actually rendering inside the div (the black border encloses it), rather than after the div (so it's between the div and span). Am I misunderstanding how this should be working?
EDIT:
Here's a simpler example:
CSS:
#theDiv {
border: 1px solid green;
}
#theDiv::after {
content: ".";
}
#theOtherDiv {
border: 1px solid orange;
}
HTML:
<div id="theDiv">
Hello
</div>
<div id="theOtherDiv">
World
</div>
That ends up placing a period after 'Hello' rather than after the div.
It appears that ::after and ::before are actually appended to the CONTENTS of the element, not the element itself. Is that correct?
Yes, it appends to the content of the selected element. You could try wrapping the div then appending after the wrapper div, but that defeats the whole purpose of using :after in the first place.
You could also try setting the enclosing div to 'overflow: auto'. That works everywhere.
I would suggest using clearfix - it's a lot simpler, you just set up a surronding with a class of clearfix.
See this example.

Resources