Applying style to a parent block depending on the child's state - css

With the following block structure:
<div class="container">
<div class="title"></div>
<div class="subject"></div>
</div>
is it possible to hide (display:none) a .container if it's child .subject is empty?
Thanks!

well... you could try to fake it... make title position: absolute and for container set overflow: hidden; container itself will only be visible if you put something into .subject tag. Like this:
jsfiddle example

I believe you'll have to use javascript to do this. In jQuery:
$(".container").each( function() {
if ( $(this).children('.subject').html() == '' ) {
$(this).hide();
}
} );
Example at: http://jsfiddle.net/m5jjs/

Not currently possible in pure CSS in any browser I know of.
There is a jQuery plugin cssParentSelector polyfill for the upcoming parent selector in CSS Selectors Level 4 if you already have a jQuery dependency in the project.

:empty psuedo class can be used if element has no node but you have. Need JS though.
$(".container *") {
if($.trim($(this).html()).length == 0 && $.trim($(this).text()).length == 0 ) {
$(".container").css({ "display" : "none" });
}
});

Related

CSS shadow dom : is there alternative to /deep selector?

As far as I know, the /deep selector is deprecated to select shadow dom children. So I'm looking for another solution.
CSS scoping looks to provide solutions for ascending selector, but not for descending one.
Given this dom :
<script>
$('.child').addClass('reached');
</script>
<div id="parent">
#shadow-root
<div class="child"></div>
/shadow-root
</div>
How can I write the selector in the script to reach the .child element ?
Thank you for your help
How can I write the selector in the script to reach the .child element?
To reach an element in the Shadow DOM, you should use the shadowRoot property on the element.
var parent = document.querySelector( '#parent' )
var child = parent.shadowRoot.querySelector( '#child' )
child.classList.add( 'reached' )
Note : the Shadow DOM must have been created in the open mode.
var sh = parent.attachShadow( { mode: 'open' } )
var parent = document.querySelector( '#parent' )
var sh = parent.attachShadow( { mode: 'open' } )
sh.innerHTML = `<style>
div.reached { color: green }
</style>
<div id="child">Child</div>
`
var child = parent.shadowRoot.querySelector( '#child' )
child.classList.add( 'reached' )
<div id="parent">
</div>
Note: ::slotted is needed only if you have elements in the light DOM revealed with <slot>.
Is there alternative to /deep selector?
Short answer is no. Since Shadow DOM is aimed at isolating Shadom DOM from the main page, /deep was kind of an heresy.
A very new proposal, with ::part and ::theme pseudo-elements could give some control back, but it's not to be implemented soon.
Until then the main workaround is to use CSS custom properties.
However the 2 solutions must be implemented by the Web Component designer and cannot be overrided otherwise.

Is it possible to select body as a parent element?

I need to style body tag differently based on another element’s class that is set dynamically on load. Is it possible to select body as a parent element of another element without using JS?
Under condition #1 the page might look like this:
<body>
…
<div class=”first-version”>…</div>
…
</body>
Under condition #2 the page might look like this - different class on div:
<body>
…
<div class=”second-version”>…</div>
…
</body>
Pseudocode, this doesn’t work but gives you an idea what I’m trying to do (create a theme of sorts):
body[contains div.first-version] {
margin:100px;
}
body[contains div.second-version] {
margin:200px;
}
Use different classes for the body styling and you SHOULD use Javascript.
Try this template:
HTML
<body id="the_body">
<input id="template_1" value="Template 1" type="button"/>
<input id="template_2" value="Template 2" type="button"/>
</body>
CSS:
.template_1{
color:red;
}
.template_2{
color:blue;
}
JS (use jQuery):
$(function() {
$("#template_1").click( function()
{
$("#the_body").html("<p class='template_1'>template 1</p>");
}
);
$("#template_2").click( function()
{
$("#the_body").html("<p class='template_2'>template 2</p>");
}
);
});
DEMO
Ok, thanks everyone for your help. That was very fast, I didn't expect this. Sorry if question wasn't clear. (This is my first time posting a question Stack Overflow).
It looks like pure CSS solution is not possible in this case and I should just use jQuery. Michael Marr posted the link to the jQuery solution that I'm going to use:
Apply CSS styles to an element depending on its child elements

select elements which have a special css attribute with jquery

I have the following structure:
<div class="main">
<div class="submain">
.....
<div class="sub..submain">
</div>
.....
</div>
<div class="submain">
</div>
</div>
Some of the subelements have the css property float:right;, and I dont know how many levels there are.
How can I select all elements with this css property using the selector $('.main')?
I have an idea, but I am trying to find an easier way to do it:
var elemsArray=[];
function findNeededChildren(elem){
var hasChildren = elem.children().length>0?true:false;
if(hasChildren ){
$.each(elem.children(),function(){
if($(this).css('float')=='right')elemsArray.push($(this));
findNeededChildren($(this));
});
}
}
findNeededChildren($('.main'));
You can select elements by an attribute, so you could try
$('div[style="float:right"]')
This should select all the divs with that attribute. But I am not sure if it will also select something with more than this one style.
Edit:
I just remembered that some people here where I work use classes for this sort of thing. It makes maintainability easier. Make a css rule that says:
.floatRight {
float:right
}
Then just assign this class to everything that needs floating. These should be even easier to select.
You can do something like
$(document).ready(function(){
$(".main").find("div").each(function(){
if($(this).css("float") == "right") {
// This is the required div
}
});
})
And if you don't know that children of .main are divs or other tags then use
$(document).ready(function(){
$(".main").children().each(function(){
if($(this).css("float") == "right") {
// This is the required element with float: right property
}
});
})

Set the css property of a class based on its visibility property using CSS only

I have a set of div whose visibility is set to either hidden or visible. Based on this css visibility property i need to add the css property on those div, like
<div class="div-class" style="color:#ff0000; margin: 0px 10px; visibility:hidden;">
[Block of Code]
</div>
Now i need to define the following in style.css file.
.div-class:visible {top:10px;left:50px;}
.div-class:hidden {top:0px;left:0px;}
Is this possible???
yes with css attributre selectors you can do it
try the below css:
.div-class[style*="visible"] {
color: green;
}
.div-class[style*="hidden"] {
color: red;
}
What you are trying to do is not "really" possible.
I mean it's ill thought by design in the first place.
Even Vamsikrishna's solution might not work as expected.
If you set the overflow property to hidden via javascript or inline styles, the .div-class[style*="hidden"] rule will apply since the style attribute will contain the hidden string.
Moreover , setting inline styles on html elements is bad practice itself in most cases.
I suggest you try and learn css principles a little more.
I'd do the following:
HTML
<div class="div-class div-hidden">
[Block of Code]
</div>
CSS
.div-class {color:#ff0000; margin: 0px 10px; top:10px;left:50px;}
.div-hidden {visibility:hidden;}
.div-class.div-hidden {top:0px;left:0px;}
Then you can use javascript to toggle the "div-hidden" class.
You can do something using attrchange - a jQuery plugin ,
like this:
Add "attrchange" script into HTML page like
In Javascrip catch event
var email_ver_input = $("input#email_ver_input.verifyInput");
email_ver_input.attrchange({
trackValues: true,
callback: function (event) {
if (email_ver_input.is(":visible")){
$("#inputcode_wrap").show();
}
}
});

Is there a CSS "haschildren" selector? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is there a CSS parent selector?
Is there a css selector I can use only if a child element exists?
Consider:
<div> <ul> <li></li> </ul> </div>
I would like to apply display:none to div only if it doesn't have at least one child <li> element.
Any selector I can use do this?
Sort of, with :empty but it's limited.
Example: http://jsfiddle.net/Ky4dA/3/
Even text nodes will cause the parent to not be deemed empty, so a UL inside the DIV would keep the DIV from being matched.
<h1>Original</h1>
<div><ul><li>An item</li></ul></div>
<h1>No Children - Match</h1>
<div></div>
<h1>Has a Child - No Match</h1>
<div><ul></ul></div>
<h1>Has Text - No Match</h1>
<div>text</div>
DIV {
background-color: red;
height: 20px;
}
DIV:empty {
background-color: green;
}
Reference: http://www.w3.org/TR/selectors/#empty-pseudo
If you go the script route:
// pure JS solution
​var divs = document.getElementsByTagName("div");
for( var i = 0; i < divs.length; i++ ){
if( divs[i].childNodes.length == 0 ){ // or whatever condition makes sense
divs[i].style.display = "none";
}
}​
Of course, jQuery makes a task like this easier, but this one task isn't sufficient justification to include a whole libary.
Nope, unfortunately that's not possible with CSS selectors.
CSS does not (yet) have any parent rules unfortunately, the only way around it if you must apply it only parents that contain a specific child is with the Javascript, or more easily with a library of javascript called jQuery.
Javascript can be written in a similair way to CSS in someways, for your example we would do something like this at the bottom of our HTML page:
<script type="text/javascript">
$('div:has(ul li)').css("color","red");
</script>
(For this you would need to include the jQuery library in your document, simply by putting the following in your <head></head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
If you use jquery, you can try out this function
jQuery.fn.not_exists = function(){
return this.length <= 0;
}
if ($("div#ID > li").not_exists()) {
// Do something
}
There is another option
$('div ul').each(function(x,r) {
if ($(r).find('li').length < 1){
$(r).css('display','block'); // set display none
}
})

Resources