Conditional CSS: if sibling's child div is present, then - css

In the html fragment below, I want the "main" div to have a background image only if "menu" div is not present in the markup. Is this possible?
<div class="header">
<div class="siteTitle">site title</div>
<div class="tagline">site tagline</div>
<div class='menu'></div>
</div>
<div class="main"></div>

http://www.w3.org/TR/css3-selectors/
E + F Matches any F element immediately preceded by a sibling element E.
E:not(s) an E element that does not match simple selector s
edit :not uses a simple selector, so unfortunately you can't use it to filter by properties of children, only attributes of the element.
A simple selector is either a type selector, universal selector, attribute selector, class selector, ID selector, or pseudo-class.
You could however put a .empty class on the menu and still use it.
.header .menu:not(.empty) + .main {
background:pink;
}
This solution is the best of both worlds, javascript but using css as per normal.
javascript:
if ($('.menu').length == 0){
$('body').addClass('no_menu');
}
css :
body.no_menu .main{
background:pink;
}

The only pure css solution i see is only possible if you rearrange your html like so:
<div class="header">
<div class="siteTitle">site title</div>
<div class="tagline">site tagline</div>
</div>
<div class="menu"></div>
<div class="main"></div>
then you can use this css to only apply a property):
.menu { background: none }
.menu ~ .main{ background: url() } /* or .menu + .main if they are guaranteed to be adjacent to each other on the code */
in this example, you can see it at work: http://jsfiddle.net/tYhxr/
(test it by deleting the menu div and running it again)
check Keyo's asnwer for a link about how selectors work.
If you can't change the html, the javascript is the way to go.
I hope this helps.

You could add a second class to your main <div> that only serves to add the background you want. Then when you create the markup, you just add the second class specifier to the <div> if you need it, or omit it if you don't.
div.main {
//main stuff
}
div.mainbg {
background: *background-specifications*;
}
When your menu div is present, you use this:
<div class="main mainbg">
And when it's missing, you stick with:
<div class="main">

Related

Applying CSS3 to pseudo-class first-child

I have markup that goes something like this
<div class='wrap'>
<div class='container'>
Body Container content
</div>
<div class='container'>
Footer Container content
</div>
</div>
I want to display a header containing, amongst other things, a logo above the first, body, container. This I accomplished by defining
.container::before
{
background-image(url(path/to/image.jpg);
background-size:cover;
content:'';
}
The above works. The problem is that the logo ends up not onlyu above the body content but also above the footer content which is not quite the desired result. I have played around with various combinations of
.container::before:nth-of-child(1)
{
}
.container:nth-of-child(1)::before
{
}
but I haven't quite found the right syntax to target the ::before pseudo element for the first .container instance. I hope that someone here will be able to tell me how it should be done.
If the worst comes to the worst I can do it with a spot of jQuery but I would like to avoid that.
Would you consider using <main> W3 4.4.14 The main element and <footer> 4.4.9 The footer element per HTML5 elements with class of .container on each? That way you can reference/target those elements without psuedo elements
main::before
{
background-image(url(path/to/image.jpg);
background-size:cover;
content:'';
}
This way the header/logo you are looking for would only appear above the first container only. Then if you need to apply pseudo elements to <footer> you could do something like:
footer::before
{
background-image(url(path/to/image.jpg);
background-size:cover;
content:'';
}
OK so I'll add another answer because it doesn't appear that anyone has solved all of your issues.
First, there is a typo in your css: background-image(url(path/to/image.jpg) is missing the closing paren.
To do what you want, however, there is a simple css selector :). In your example, you try nth-to-child(), but the correct syntax for what you want is nth-child(). Look below for two options, with a working demo.
.container:first-child:before
{
display: block;
content: "Before Element";
/* other styling that you choose*/
}
/* the following selector will also work
.container:nth-child(1):before
{
display: block;
content: "Before Element";
}
*/
<div class='wrap'>
<div class='container'>
Body Container content
</div>
<div class='container'>
Footer Container content
</div>
</div>
Note that the display: block; part is so that the before content appears on it's own line, since :before elements by default are display: inline-block;.
I dont think that there is a way to making it work with nth-of-child, but it will definitely work with first-child (if you always need it only in the first element with class .container):
.container:first-child:before
{
background-image(url(path/to/image.jpg);
background-size:cover;
content:'';
}
My first thought here is that there should be an additional class for the header, or use the <header> and <footer> elements in place of divs. For example:
<div class="wrap">
<div class="container header">
Header
</div>
<div class="container footer">
Footer
</div>
</div>
and
.header::before {
// stuff to make your logo
}
However, if for some reason you can't change the html, then the :first-child selector should work for your needs, as others have answered.
If you want to use nth-child() you need to add it to the parent of the element that you want to select. In this case .wrap.
.wrap:nth-child(1):before
{
background-image(url(path/to/image.jpg);
background-size:cover;
content:'';
}

:first-child not being applied

On this page, I want to hide the incorrect HTML displayed above the logo. It is generated by an old plugin we are replacing soon.
To start with, I tried the CSS:
.vine-home-block-grapes:first-child {display: none;}
but this does not remove the highlighted block below:
Can you help me determine why please?
Use css :first-of-type selector
.vine-home-block-grapes:first-of-type{
display:none;
}
That selector won't work as the element you are attempting to select is not the :first-child of its parent.
One way to do what you want is select all elements with that class name, set their styles as you wish and then, using a new rule with the sibling selector, override those styles for any element of that class appearing later in the parent.
.vine-home-block-grapes{
display:none;
}
.vine-home-block-grapes~.vine-home-block-grapes{
display:block;
}
Add this script. It would work fine without any problem:
<script>
var fourthChild = document.body.getElementsByTagName("div")[0];
document.body.removeChild(fourthChild);
</script>
Thanks to #FelixKling
Try wrapping the child elements in a <div> so the element can BE the first child of its wrapping element. Right now, your element is not the first child of <body> See the experiment here to show how :first-child doesn't work as expected, because really it's not the first child of its parent.
p:first-child {
background-color: aqua;
}
.vino:first-child {
background-color: lightgreen;
}
WORKS
<p>First</p>
<p>Second</p>
<p>Third</p>
DOESN'T WORK (because none of these are the first child of its parent, in this case, <body>
<p class="vino">First</p>
<p class="vino">Second</p>
<p class="vino">Third</p>
Adding a wrapping div works.
<div>
<p class="vino">First</p>
<p class="vino">Second</p>
<p class="vino">Third</p>
</div>

hide a div by clicking a non-parent div

In my site there're two different div, but they have the same parent div (two child div). So, I want to do this: div.1:hover -> div.2{display:none}. How can I do it using CSS?
Depending on the way your HTML is laid out it can work. The divs need to be next to each other like so:
<div class="first">
First div
</div>
<div class="second">
Second div
</div>
Then use this CSS:
div.first:hover + div.second { display: none; }
Fiddle here: http://jsfiddle.net/CyT2N/
You can easily accomplish that with JQuery.
$(document).ready(function(){$("#first").hover(function(){$("#second").hide();}, function(){$("#second").show();});});
Explanation:
this code adds a "hover" handler for the first element on document.ready, when the mouse enters we hide the second element, and when the mouse leaves, we show it again.
This way, it will work no matter where the elements are within the layout.
See here: http://jsfiddle.net/avrahamcool/RenK2/
Edit
If you want the second div to hide when the first one is clicked, use $("#first").click(function(){$("#second").hide();}) instead of hover(..)
See here: http://jsfiddle.net/avrahamcool/RenK2/1/
Here is a simple way of doing it:
If you have HTML similar to this:
<div class="wrap">
<div class="first">First div</div>
<p>some other element...</p>
<div class="second">Second div</div>
</div>
your CSS would be:
.first:hover ~ .second {
display: none;
}
Demo at: http://jsfiddle.net/audetwebdesign/HQN6n/
The one limitation that .first and .second must be sibling elements within the same parent element, .wrap in this example.
The general sibling combinator ~ is supported for IE7+
Reference: https://developer.mozilla.org/en-US/docs/Web/CSS/General_sibling_selectors

Selecting an element that doesn't have a child with a certain class

The structure of my HTML is like so
<div>
<div>
<h1>Something</h1>
</div>
<div>
<h1 class='Handle'>Something</h1>
</div>
</div>
In the event that the div > div does not have a child with the class "Handle" I want the the div > div to have the style cursor:move;. How would I go about doing this in pure CSS, is it even possible?
:has()
Note: Limited support.
Using the :has() pseudo-class, the following example would work, but — as of February 2023 — browser support is limited.
div > div:not(:has(h1.Handle)) {
cursor: move;
}
*JSFiddle
Alternatively, jQuery supports the :has() selector.
There is no parent selector in CSS, so what you are asking is not possible. What you can do is put the cursor:move on every h1 that doesnt has the class "Handle" by using the attribute selector.
h1:not([class=Handle]) {
cursor:move;
}
http://jsfiddle.net/4HLGF/
Another option is to adjust your HTML, and move your h1 on the same level as the div.
<div>
<h1>Something</h1>
<div>
dragable content
</div>
<h1 class='Handle'>Something</h1>
<div>
non dragable content
</div>
</div>
Now you can do the same check on the h1, and target the div that comes after it.
h1:not([class=Handle]) + div {
cursor:move;
}
http://jsfiddle.net/4HLGF/2/
Try
div > div h1:not([class=Handle]) {
cursor:move;
}

Trying to edit link styles within a div

so I'm having a bit of a tough time figuring this out.
I want to edit some links within a specific div, seems simple enough right?
Just put
#mydiv a:link {color:#B40404}
However it does not seem to be working for me! Below is my code:
<div id="leftcontent"><div id="MYDIV">why this is no work</div>
CSS:
#MYDIV {
background-image: url(http://mypicture.com/mypic.jpg);
width:290px;
height:280px;
font-family:Tahoma,Geneva,sans-serif;
padding:25px;
background-repeat:no-repeat;
}
#MYDIV a:link {color:#B40404; }
I have no idea why this isn't working. Any help appreciated!
Thanks
HTML should be like below (a tag inside the div)
<div id="leftcontent">
<div id="MYDIV">why this is no work</div>
</div>
CSS
#MYDIV a{color:#B40404; text-decoration:none}
DEMO
In your case (div inside the a tag) you need not to write id name in css directly write style for a tag
a{color:#B40404; text-decoration:none }
or
#leftcontent a{color:#B40404; text-decoration:none }
DEMO 2
Your CSS is selecting an tag INSIDE a tag. You either need to do the following:
a #MYDIV { /* css code */ }
or
<div id="MYDIV"><a>My link here</a></div>
EDIT:
I just read your comment on the other page. In that case, you need to add either a class or an ID to the and then reference that.
<div id="leftcontent"><div id="MYDIV">why this is no work</div>
CSS
#myLink { /* add style here */ }
<div id="leftcontent"><div id="MYDIV">why this is no work</div>
in css
#MYDIV a:link {color:#B40404; }
i think you need not style the hyperlink in your case.
Since the styling would ultimately would be applied to your div is enclosed within the anchor tag. So give the color: #your_hex_code to the #MYDIV which would suffice your need. That is what you need.
If you made a mistake in the html, Sowmya answer is perfect.
Optional:
Moreover you can use jquery to style that, $("#your anchor").parent().css or use closest.
Thanks
this way is not a correct formating in coding html this will not validate in html validator
<div id="leftcontent">
<a href="http://google.de">
<div id="MYDIV">why this is no work</div>
</a>
</div>
instead of that do this
<div id="leftcontent">
<div id="MYDIV">
sample
</div>
</div>
if you want the whole div link add basic style in your div a
css
#MYDIV {
float:left;
}
#MYDIV a {
float:left;
width:100px;
height:100px;
}

Resources