Visually combine neighbouring CSS blocks without javascript - html

I have a site which has editable content via a WYSIWYG inline editor, and users who are very unlikely to understand the need to put containing DIV around similar blocks of code for formatting, resulting in html similar to:
<div class="borderBlock">Content...</div>
<div class="borderBlock">Content...</div>
<div>Other content</div>
<div class="borderBlock">Content...</div>
with current CSS along the lines of:
.borderBlock {
margin: 8px 0;
border: 1px solid;
border-radius: 4px;
}
This gives each div it's own separate border - not quite what is wanted, ideally the first two div's would share a border and background colour!
I know that I can use css such as:
:not(.borderBlock) + .borderBlock { }
to select the first block of class borderBlock - applying formatting for the start of a block, and similarly:
.borderBlock + :not(.borderBlock)
would select the first none borderBlock element... but I can't find a way to select the last borderBlock element in a block that isn't specifically surrounded by another div - in the above html using :last-child or :last-child-of-type would both select only the fourth div, and not style the second div as the end of a borderBlock. Similarly :first-child(-of-kind) would not style the second bordered block.
Is there a CSS solution to this that doesn't use JavaScript, and doesn't involve putting a containing div around each required bordered block? Something equivalent to a CSS look-ahead regular expression rather than the standard CSS look-behind style.

Currently, you cannot do this with CSS selectors, without using JavaScript or modifying your HTML, since there's no preceding sibling selector.

What about something like this?:
http://jsfiddle.net/Hegxc/4/
using :first-of-type and :last-of-type
Is that what you're trying to achieve or have I misunderstood what you're looking for??

Related

Using CSS to grab a specified class and a number of lines after it

I'm trying to write a CSS snippet to hide ads on a website. The problem is that the content I need to hide is a line after the div with the class tag, and is completely identical to other, useful content on the page. Is it possible to grab the div with the class AND a line after it with CSS? Right now I'm just starting with
.ad-indicator {
display: none ;
}
It's hard to give you an exact answer without seeing an example of you HTML but the following could get you moving in the right direction.
The ::first-line pseudo element selector selects the first line of a block element. Using this in combination with the adjacent sibling combinator will select the first line of a following block element.
.ad-indicator,
.ad-indicator+ ::first-line {
color: red;
}
.ad-indicator {
background-color: #CCC;
}
<div>Something Random</div>
<div class="ad-indicator">
Our Target
<p>With Some additional content</p>
</div>
<div>
Something else <br> With Multiple lines.
</div>
You may need to adjust this based on the HTML structure.

CSS indent everything except headers

I have an html-document that is generated by an application. I want to indent everything in this document except the h2 headers. I've been playing around with the css :not selector but I can't quite get it to work the way I want.
Here is the css that I came up with and the jsfiddle that I've been using for testing: http://jsfiddle.net/xm71wr2a/
body :not(h2){
margin-left: 20px
}
As you can see in the jsfiddle the p and the div are properly indented but the text between them is not. Is it possible to apply the indentation to that as well, or do I have to modify the html to achieve this? I have access to the application's source code so I can edit the output that it generates but I'd rather solve this using css if possible.
Well you should give the not indented text a tag. It doesn't matter what tag, just not an H2-tag. CSS style will not apply without the text having a tag.
<h2>Not indented</h2>
<p>THIS SHOULD BE INDENTED</p>
<p>THIS SHOULD BE INDENTED</p>
<div>THIS SHOULD BE INDENTED</div>
<h2>Not indented</h2>
http://jsfiddle.net/xm71wr2a/1/
easy mistake to make, you just added an extra space between body: and not
it should be:
body:not(h2){
margin-left: 20px;
}
to elaborate on the previous answer, html text content like yours without at least a <p> tag will be very limited in its mutability from your css file especially when that is your only resource to manipulate that content.
wrapping the content you want indented in a <p> tag and leaving the <h2> tags around the content you don't want to indent will create the separation between the two, and allow you to manipulate them individually with css.
alternatively, a way to select ALL elements of a html page and apply the same css effect to them would be using the * selector:
*:not(h2){
margin-left: 20px
}
* = all html DOM elements

I would like to hide my outer div if inner div is empty

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>

Using CSS to hide <span> elements when they are empty

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

CSS Rule: Give style to all with children [duplicate]

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.