I have this code:
<p class="alert-error">
<span></span>
<span></span>
<span></span>
</p>
I want to change the style of the CSS for "alert-error" when it shows <span></span>. The code is being generated by a system with limited backend customization. Sometimes the spans are filled with error messages.
The :empty selector doesn't seem to work cause I have to put it on the alert-error class.
Any help would be appreciated.
I'm guessing based on what I can surmise from your markup structure that you want to hide the entire .alert-error element, not the span elements as stated in the question title. It doesn't really make sense to display .alert-error itself if its children are empty, since that would just result in an empty box.
The problem is that :empty itself does not match an element if it has child elements, even when all the children themselves are :empty.
If CSS had a parent/has selector, you would theoretically be able to select .alert-error based on the fact that all its children are :empty. But since there doesn't exist such a selector in CSS yet, you will need to use JavaScript.
I made the css like this:
.alert-error span:empty {
background: green;
}
and it works, see jsfiddle
Related
I have two div a child and a parent. the child contains a contact number. If there is no contact number I want the parent div to display none. I am trying to use the :empty CSS statement but I think I am using the wrong logic.
#inter #inter-content:empty {
display:none;
}
<div id="inter" class="telephone">Intl: <div id="inter-content">{{contact_number_international}}</div></div>
I'm not sure if CSS is the right route either. I have tried using the bottom as well:
#inter + #inter-content:empty {
display:none;
}
You cant do this in the way you are approaching it due to how CSS works, and that you can only write selectors to isolate child/subsequent DOM nodes. :empty also works on selecting elements with no child nodes (elements or text).
The :empty pseudo-class represents any element that has no children at
all. Only element nodes and text (including whitespace) are
considered.
As such, you cannot select a parent element using CSS- and you cannot determine a node to be empty, if it contains another node (whether that node is empty or not).
One way to potentially get around this, is to apply the label in your code as a pseudo element, with its content conditionally sourced from a (data) attribute if the element is not empty. This will give the impression of the parent not displaying content if no number is present.
That said, if you actually dont want to display the parent at all- you will run into trouble using CSS alone. It looks like you are using angular (or similar), in which case you may want to use a logical check to toggle the parent's visibility.
.inter div:not(:empty):before {
display: block;
content: attr(data-label);
}
<div class="inter" class="telephone">
<div data-label="Intl: ">21342213</div>
</div>
<div class="inter" class="telephone">
<div data-label="Intl: "></div>
</div>
If you are using for example angular you could write
<div id="inter" class="telephone" ng-if="contact_number_international != null">
<div id="inter-content">Intl: {{contact_number_international}}</div>
</div>
Other frameworks should have such functions too. (I assume u use something because of "{{}}")
Fast forward a few years and CSS has a solution for this:
.outer-content:has(.inner-content:empty) { display: none; }
I was searching myself and none of the relevant answers were recently updated so I thought I'd write it down here.
The browser support :has to be considered of course
"Hide an empty container" questions are redirected here. So here's the simplest solution:
.hide-if-empty:empty { display: none !important; }
<div class="hide-if-empty">
<!-- if empty then hidden -->
</div>
I have a text input that is wrapped inside a div. I want to change a css attribute of the :after of the parent div when the input is focused. How can I do this in CSS?
<div class="dataInputTextContainer">
<input class="dataInputText" />
</div>
I tried this but it did not work:
.dataInputText:FOCUS ~ .dataInputTextContainer:after{
background-color: red;
}
Simply put, you cant
(sorry)
CSS works in terms of DOM decendancy, in that rules can only be constructed for elements which appear subsequently in the DOM. As such, you cannot select a parent, or even previous sibling.
What I would tend to suggest is that you sit down, take a step back and work out what you are trying to accomplish. 99% of the time either someone else out there has done it, or you can do it with a minor change to either your CSS or HTML.
Incidentally, a solution would not be to try and style :before or :after on the input, it is a replaced element so such elements do not apply. Why not simply add a label for the input and style it?
If you didn't apply style on :after of the parent but rather put a tag at the same level than the input, you could have used this syntax to apply style of the sibling tag.
I'm sorry if this question seems uninformed and lacking own research, but I've tried searching anything I could think of on google but still couldn't find anything about it anymore.
A while back, I recall reading something about styles relative to the stylesheet they were declared from. I am not entirely sure if this is indeed what was meant on the page I read it, but I have no idea where I read about it exactly, so I wouldn't know where to look to check it. Anyway, this is the impression I got from it:
What I am looking for is a way to make this only select the span inside the div that also has the style tag in it.
<div>
<span class="special">Not red</span>
</div>
<div>
<style>.special {color:red;}</style>
<span class="special">Red</span>
</div>
I know this doesn't work, but I have no idea how to do this, or if it is even possible to insert a style tag within the body and then to apply styles either relative to that style tag.
If anyone has any idea on how this might be possible (without JavaScript), or if you're absolutely sure this is impossible to do without assigning seperate classes to the affected span, please tell me.
PS: the order in which the elements occur may differ, so div + div .special {color:red;} or div:last-child .special {color:red;} won't work.
I believe you're looking for <style scoped>
Here are a few links
http://css-tricks.com/saving-the-day-with-scoped-css/
http://caniuse.com/style-scoped (you'll want to be sure the browsers you are targeting can use it.)
So you nearly have it correct in your example, just add the scoped attribute.
Normal CSS would be to apply different classes to these spans. They're fundamentally different.
If you want to work around that, you could apply classes to their enclosing divs:
<div>
<span class="special">Not red</span>
</div>
<div class="div-special">
<span class="special">Red</span>
</div
And the CSS:
.div-special .special { color: red; }
EDIT You could add a second class to the second span and apply the color there <span class="special colored-red">
This question already has answers here:
Complex CSS selector for parent of active child [duplicate]
(10 answers)
Closed 9 years ago.
I'm trying to give a style to all <div> with children and not to those with no children.
Or, give style to all, and give a different style to those with no children.
The structure is similar to this
<div>
<div>
<div>
<div>Don't style me</div>
<div>Don't style me</div>
</div>
<div>Don't style me</div>
<div>Don't style me</div>
<div>
<div>
<div>Don't style me</div>
</div>
</div>
</div>
</div>
CSS level 4 is being worked on, and will include selectors that can do what you're asking.
When it does become available, the syntax will look like this:
.myclass! div { ... }
This will select the .myclass element that has a div element as a child. It's basically a normal CSS selector, but with the exclamation mark to tell it which element to select. (although note that the preferred syntax has changed a couple of times during the drafting process, and they've not finalised it yet!)
If you're interested in following up about this, you can read the full spec in its current form here: http://dev.w3.org/csswg/selectors4/
However that's in the future. For current browsers, what you want to achieve isn't really possible with pure CSS.
So what options do you have?
The most obvious work-around is to use javascript to achieve the effect you want. jQuery is perfectly capable of selecting elements in the way you've described, like so:
$('.myclass:has(div)');
Also obvious would be adding a class to the elements you want to style, and just using that. This could be done in Javascript or in your server-side code. Probably the most obvious answer, really, in the absence of an actual CSS selector you can use.
Depending on what you're trying to do, you could try re-arranging you HTML structure; in some cases, a bit of lateral thinking can help you achieve results that appear to do this, even with the CSS selectors available today. In particular, hover effects can often be worked around this way.
Again, depending on what your code looks like and what you're trying to do with it, you could try making use of some of the more esoteric CSS selectors. For example, div:empty will select divs that have no content. This won't work for the examples you've given (as you have text in the 'empty' divs), but would work in other cases where they really are empty.
It can be done in 2 ways :-
1) Giving a specific class to the parent div and the child div will inherit the style.
2) Giving class to divs individually.
The better option would be implementing via the 1st option.
Use the ">" operator.
Some documentation
Like div > div {}
http://jsfiddle.net/9tLXP/
div {
padding: 10px;
background: red;
}
div > div {
padding: 10px;
background: blue;
}
div > div > div {
padding: 10px;
background: orange;
}
div > div > div > div {
padding: 10px;
background: green;
}
Edit: Obviously I went ahead and styled each one with a different background color to demonstrate the point. In your case you would delete some of the extra styling I provided.
If you are truly looking to use the structure you posted, one where no classes or id's are assigned to any elements, then you can not accurately detect the bottom element in a group with n amount of children.
Operators such as > can give you a direct descendant but they can not tell you if it has any further children without further loops as Michael has shown. The issue therefore with Michaels method is you could not detect a div at level 3, and a div at level 4 and style them the same, as all div's at level 3 now inherit this style.
Long and the short - without adding in a class or 2 you can't accurately detect the bottom most child of a nested structure without effecting it's siblings.
i'm using wordpress and i have an element i want to style... it's called...
<h2 class="widgettitle">
now, i know i can do,
h2.wigettitle {
whatever:css;
}
however, the problem i have is that i have multiple widgets with the same title and it effects all of them.
but, this h2.widget title is within another div called "headerarea".
so, in my file it's like...
<div id=headerarea">
<h2 class="widgettitle">
whatever title
</h2>
</div>
so is it possible to make this specific element do something like, #headerarea.h2.widgettitle or something in my element?
i tried styling the outer div independently, but the inner div is still grabbing styling from somewhere else, so i need to override all of them.
hope this makes sense... thanks for any help guys.
Use #headerarea h2.widgettitle. Including a space means to look in the children. If you include a > this means only look in direct children. Note that if your overrides do not work, add !important at the end to ensure they will override any other styles applied.
You can use the child or descendant selectors to accomplish this. Child selector > #headerarea > h2.widgettitle select h2 elements with class widgettitle that is a child of element with id headerarea. Descendant selector a space #headerarea h2.widgettitle select h2 elements with class widgettitle that is a descendant of element with id headerarea.
Also see http://www.w3.org/TR/css3-selectors/#selectors
#headerarea .widgettitle {
/* Put your styles here */
}