How to style parent when parent contains specific child? - css

I have some html that looks like this:
<div id="parent">
<div id="child"></div>
</div>
I want to apply a default background color to #parent except for when it contains a #child.
So the CSS should end up looking something like this:
#parent {
background: red
}
#parent:contains(#child) {
background: none
}
However, I can't get the :contains pseudo selector to work that way. Is there a way to achieve this?

:contains() was only intended to match elements containing certain text, not elements containing certain other elements. It is because of the complications associated with matching elements by text that there were almost no browser implementations, leading to :contains() being dropped from the spec.
Since there is no parent selector in CSS, and :has() (which does look at elements) only exists in jQuery, you won't be able to achieve this with CSS yet.
For the record, jQuery implements :contains() as well, but it does so according to the old spec, so it uses the name :has() for elements instead.

With jquery
if($("#child").length>0) $("#parent").css("backgroundColor","#fff");
Its not possible with pure css.

Related

What's the name of this CSS3 syntax?

I'm asking this question because I'm trying to understand the CSS3 style changes that make this code work: Javascript CSS3: Move div container
Quick question because I don't know where else to ask...what's the below called? I want to learn more about it but not sure what it's called.
Is the "state" part of className some sort of CSS3 state...or something?
<style>
#className {
position: relative;
display: inline-block;
height: 100px;
transition: height 1s ease;
}
#className.state {
height: 25px;
}
</style>
This is called CSS Selectors and there is nothing specific with CSS3 in this code.
Dot (.) is class selector. You can have multiple elements with same styles, and this is where you use class names.
Hash (#) is id selector. This selector only applies to a single element. In most cases you should be avoiding to use ids for CSS selectors unless you really need it. This is just a suggestion.
One selector after another, without comma (,) selects the element inside the particular element.
In this case
#className.state
Selects all classes with name state inside the id className.
Edit
Given the HTML:
<div id="mobileMenuWrapper">
<div class="hide">
Content of the element
</div>
</div>
And the following CSS selector:
#mobileMenuWrapper.hide{
margin-top:0px;
}
Element with the class name hide will be selected. It will take the style. Its margin from top will be 0.
However, something like this is applying multiple classes to a signle element. And it is another story.
<div class="mobileMenuWrapper hide"></div>
Anyways, so get a better understanding of all there, you still need to read something like this or this one. At least a quick scan.
It must be a class name.For example you can have an item with an Id to style only an item but you want to have some common styles with other elements
Yes, it's called a class. Classes are rules that apply to multiple elements, while ids apply only to specific elements.
A class selector looks like: .
A id selector looks like: #
An input element could have a specific Id: <input type"text" id="monthly_cost"/>
Note that no other elements can have the same id. It causes an HTML error.
For multiple elements, you use the class selector: <h1 class="blue_heading">
Hope this helps!
Its called CSS Selector.
You can read about it here: http://www.w3schools.com/cssref/css_selectors.asp

Is the CSS :not() selector supposed to work with distant descendants?

Here is the official documentation for the CSS3 :not() pseudo-class:
http://www.w3.org/TR/css3-selectors/#negation
and the proposed CSS Selectors Level 4 enhancement:
http://dev.w3.org/csswg/selectors4/#negation
I've been searching the implementation and browser support for :not(), but the only examples I found were with a single element or with a direct child of an element, e.g.:
div *:not(p) { color: red; }
The example above works when <p> is a direct child of <div>, but it does not work when <p> is a more distant descendant of <div>.
div :not(p) {
color: red;
}
<div>
<ul>
<li>This is red</li>
</ul>
<p>This is NOT</p>
<blockquote><p>This is red but is not supposed to be!</p></blockquote>
</div>
If the answer is in the official documentation above, then I didn't find/understand it. As I said, I have searched this site and the web but couldn't find any discussion about the support or lack thereof of :not() as grand-children of another element.
Is this supposed to work like I think it should?
Is this supposed to work like I think it should?
No, the behavior you're seeing is correct.
In your last example, although the <blockquote> contains a <p>, it's the <blockquote> itself that's matching *:not(p), as well as the condition that it must be a descendant of the <div>, which it is. The style is applied only to the <blockquote>, but it is then inherited by the <p> inside it.
The <p> element itself still counts against the negation, so the <p> itself is still being excluded from your selector. It's just inheriting the text color from its parent, the <blockquote> element.
Even if none of its relatively close ancestors matched the selector, you have elements like html and body to worry about as well — although you could probably just tack on a body selector in the very beginning:
body div...
This is why I often strongly advise against using the :not() selector for filtering descendants, especially when not qualified with a type selector (like div in your example). It doesn't work the way most people expect it to, and the use of inherited properties like color only serves to compound the problem, on top of making it even more confusing for authors. See my answers to these other questions for more examples:
Why doesn't this CSS :not() declaration filter down?
CSS negation pseudo-class :not() for parent/ancestor elements
The solution to the problem described is to simply apply a different color to <p> elements. You won't be able to simply exclude them with a selector because of inheritance:
/* Apply to div and let all its descendants inherit */
div {
color: red;
}
/* Remove it from div p */
div p {
color: black;
}
On Selectors Level 4: yes, :not() has indeed been enhanced to accept full complex selectors that contain combinators. Essentially, this means (once browsers begin implementing it) you will be able to write the following selector and have it do exactly what you want:
p:not(div p) {
color: red;
}
In case anyone is interested, this works in jQuery today.
The color is assigned to the blockquote, and is then inherited by the p.
:not(p) just makes it so that the styles are not directly applied. They are still inherited though.

CSS Selector nth-child

I am facing issues writing a slightly complex CSS selector.
I want to select a div with "class" containing 'btn-group', but not 'open'
So I have something like;
div[class*='btn-group']:not([class='open'])
Now the issue is that there are around 5-6 elements that match the above condition. But I want to select the first out of that. How do I do the same?
Would prefer doing using nth-child..
What about: div[class*='btn-group']:not(.open):first-of-type?
[Edit]: This trick does not work if you have <div class="btn-group open"></div> as the first child... (as explained by #Jukka below) a JS-based trick will work, tho:
$("div[class*='btn-group']").not(".open").first()
.css({...});
// OR add a class
// .addClass("class");
http://jsfiddle.net/teddyrised/LdDCH/
try like this
div [class*='btn-group']:not([class='open']):nth-child(1) {
color:Red;
}
Using this you can select first child
Working Fiddle
You cannot. CSS selectors can’t be used that way. But if you provide a more specific HTML context (including containers for the div elements and a description of a pattern that the markup follows), there might be a way that works under some assumptions.
In particular, :nth-child and :nth-of-type only test whether the element is the *n*th child, or the *n*th child of its kind, of its parent. It does not take e.g. classes into account; the is no “nth of a class” selector.

CSS Rules affecting other Objects

is it possible for a css rule (such as #testobject1:hover {}) to have an effect on another object #testobject2?
Nope.
The only way this could work is if #testobject2 was a descendant of #testobject1:
<div id="testobject1">
<div id="testobject2">
Hello.
</div>
</div>
The CSS would then be:
#testobject1:hover #testobject2 {
...
}
Yes, if you write something like:
#testobject1:hover, #testobject2:hover {}
or if #testobject2 is a children of the #testobject1 element and it inherits the properties declared in that CSS piece.
Otherwise, no.
It is possible if the 2nd element is a descendant of the first:
#testobject1:hover #testobject2 {}
This will cause the css of this rule to be applied to #testobject2 only when #testobject1 is hovered.
EDIT: An Interesting use of this involves absolutely positioned elements. You can have an element which is a descendant of another but visually does not appear within the other element at all. The hover will still work.
http://jsfiddle.net/F2psw/
With CSS, the only way to apply the same style to two different objects like you said is construct your style with more than one selectors. Like this:
#testobject1:hover, #testobject2 {
[...]
}

What is the simplest way to implement pure css show/hide?

I discovered the <details> element for html5, and that made me want to determine whether it was possible to implement a simple and reusable show/hide via css alone.
I have created a show/hide mechanism in the past for showing and hiding content by giving two elements relative positioning and one a negative z-index, and then decreasing the z-index of the front element on hover (and increasing the z-index of the back element on hover).
However, that method only works for elements that are in the same location. Are there other techniques for simulating show/hide on non-overlapping elements? e.g. a title that causes a section of descriptive text to display.
Trivial example code that I would like to be able to apply a show/hide to:
<div id='container'>
<h3 id='show-hide-trigger'>summary</h3>
<p id='show-hide-text'>Paragraph of detail text paragraph Paragraph of detail text paragraph Paragraph of detail text paragraph Paragraph of detail text paragraph</p>
</div>
And yes, I do know that jQuery exists.
there is a plethora of options based on the structure (for modern browsers).
Have a look at the
selector + selector adjacent sibling selector
selector ~ selector general sibling selector
selector selector descendant selector
selector > selector child selector
These can be combined with classes / ids / pseudo-selectors like :hover etc, and create a big list of options.
here is a small demo i made to showcase them : http://jsfiddle.net/gaby/8v9Yz/
Try this using nested divs and targets.
I'm not a CSS guru, so there may be all kinds of flaws with this, but it seems to work.
http://jsfiddle.net/NmdxC/6/
#show {display:none ; }
#hide {display:block;}
#show:target {display: block; }
#hide:target {display: none; }
CSS without the exact code is hard to visualize, but what is wrong with changing the display or visibility declarations dangling from a :hover?
a #myelement{display:none;}
a:hover #myelement{display:block;}
I problably misunderstood the question...care to add code?
First thing that springs to mind is something like:
<a class="blah" href="#">Hello<span>Test</span></a>
a.blah {position:relative}
a.blah span {position:absolute;top:50px;left:50px;display:none;}
a.blah:hover span {display:block;}

Resources