2

I have HTML headings and paragraphs that look like this:

<h2><br></h2>
<p><br></p>

How would I remove these paragraphs and headings using purely CSS? To make it more difficult I want to remove the parent that contains only <br> tags.

For example <p>foo<br></p>would not be removed.

I would prefer to not use JavaScript/jQuery if possible.

EDIT: Screw it I'm going to use JS to solve this one. (I like the idea of using CSS over JS to solve styling issues, but I can see that this is sometimes not possible).

  • Why in the name of all that's holy would you want to do this? – Conor Thompson Oct 04 '17 at 13:24
  • It's quite a bizarre request. Can you not solve it at source by not outputting said tags if there is no content? – Stuart Oct 04 '17 at 13:25
  • 1
    Unfortunately I have no control over the HTML source. – Alex Douglas Oct 04 '17 at 13:38
  • I've had the exact same problem, and its a good question. Using the froala editor and wkhtmltopdf would add these stupid things all the time. Unfortunately as stated below, this can't be done with pure CSS. Not until a parent selector is added to the spec. (which can't be soon enough imo). – sn3ll Oct 04 '17 at 13:43

4 Answers4

1

You can't, you can only hide it.

br.hide {display: none}

I don't know why you would want to do this in purely css, but you can hide things when the CSS is loaded, or called on.

Conor Thompson
  • 198
  • 1
  • 15
1

This is not possible the only way I could see this working is with a combination of a sibling and parent css selector.

You can do sibling selectors see: css-tricks

Unfortunately its not currently possible to do parent selectors see: stack overflow question

An alternative would be to use JavaScript but you stated you wanted to do it in CSS.

Oliver Orchard
  • 562
  • 1
  • 4
  • 15
1

The biggest problem is that you cannot target a parent according to its children in CSS, so that would be out of the question...

Since you edited your post and allow us to provide JS answers, I'd go with that:

var br = document.getElementsByTagName('br');
for (var i = 0; i < br.length; i++) {
  var parent = br[i].parentNode;
  if (parent.childNodes.length == 1) {
    parent.parentNode.removeChild(parent);
  }
}
<p>Hello</p>
<p><br/></p>
<p>My name is slim<br/>shady</p>

Pretty simple stuff, get all the <br> elements, count the amount of children their parents have (should be only 1, the <br> itself). Remove the parent from the DOM.

You could use the same logic to add a certain class if you prefer hiding it with CSS instead, but I think just removing it will be better.

Look out though, it can get pretty heavy if there are a lot of <br> tags in the body.

Salketer
  • 14,263
  • 2
  • 30
  • 58
1

Generalise the rule and allow just what you need.
Add a scope to this behavior so you can limit this functionality.

.scope br{
  display: none;
}

.scope p br {
  display: initial;
}
<div class="scope">
  <h2>Text inside h2 <br> without <br>  breaking  <br>  line</h2>
  <p>Text in p <br> with new line</p>
</div>
Jose Paredes
  • 3,882
  • 3
  • 26
  • 50