2

I’m working with a HTML file where empty lines are made using: <p><br/></p>. How do I target paragraph elements after this empty lines? I have tried br + p with no result.

[Note: It is not evident for everybody that this is a parent’s selector problem, for it is not about targeting the (parent) paragraph element that contain the line break, but the one following it.]

VorganHaze
  • 1,887
  • 1
  • 12
  • 35
  • 4
    With CSS alone you can't. There's no way to start at the paragraph, look into it for the break, and then get back up to the paragraph to get to the paragraph after it. – j08691 Jan 19 '18 at 19:51
  • 3
    Possible duplicate of [Is there a CSS parent selector?](https://stackoverflow.com/questions/1014861/is-there-a-css-parent-selector). Btw, it's really time for a pseudo selector `:closest(String selector)`. – connexo Jan 19 '18 at 19:52
  • 2
    You should post your full code so we can see the actual problem. I could be wrong, but paragraph elements with a break inside sounds like a hack. Are they meant to create space between paragraphs? Are you asking about your attempted solution or the actual problem? Just saying.. Maybe there's a better way. – Michael Benjamin Jan 19 '18 at 19:53
  • I cannot edit the HTML (it is no mine). But the user want to preserve the empty line when copy and pasting the code. This is way he is using the
    element. But I need to style every paragraph after the empty lines, and since I cannot edit the HTML code, I cannot add a class to these paragraphs.
    – VorganHaze Jan 19 '18 at 19:57
  • 1
    @connexo: Judging by the name, it wouldn't really make sense as a pseudo, since it would be written as descendant:closest(ancestor), which would match descendants with that ancestor, which is exactly the same as ancestor descendant. If you want to match an ancestor that has a descendant, :has() is still waiting for implementations. – BoltClock Jan 20 '18 at 04:26
  • 1
    @BoltClock Well it could also be `descendant :closest(ancestor)` (notice the descendant selector in between) and as such, introduce a new type of `:pseudoselector`. – connexo Jan 20 '18 at 08:19
  • 1
    @connexo: Or it could be :has() as I already mentioned without having to completely break the selector syntax (you do realize that the descendant combinator makes absolutely no sense in your example, right?). – BoltClock Jan 20 '18 at 08:22
  • 1
    Well, what is the problem with a true "upwards" selector? If jQuery can do it, it shouldn't be too hard to implement in CSS as well. – connexo Jan 20 '18 at 08:24
  • @connexo The spec writers think `:has()` is "too expensive". Compared to other selectors, it is expensive. However, it is not a concern for 99.99% of web developers. And honestly, if it is that bad, the ecosystem will control for it in people not visiting sites that use that selector. As for a true "upward" selector (no s), that's not how CSS works; it would have to be something other than *Cascading* Style Sheets. – TylerH Jan 20 '18 at 18:26
  • 2
    @Vorgan That is not immediately evident this question is about going up (selecting a parent) is actually the most important reason to mark this as a duplicate; the real question (and real answer) already exist. This is a good signpost to point users toward the information they need if they find themselves asking this question. – TylerH Jan 20 '18 at 18:35

2 Answers2

3

Note: I generally do not support javascript solutions to CSS questions. However, a pure CSS solution would probably require a relational pseudo class. Currently (as per january 2018) :has() is a part of the CSS Selectors Level 4 Working Draft, but unfortunately it's not (yet?) supported by any browsers.


What you are asking can be achieved with a combination of javascript and CSS. You may use javascript to find paragraphs that contain only linebreaks, and then add a class to these paragraphs (e.g. a class named linebreak). Then use CSS to style the paragraphs immediately following the ones containing line breaks using the CSS adjacent sibling selector (+).

// Find all <br> elements that are children of a <p> element
for(let br of document.querySelectorAll('p > br')) {
  
  // Climb one level up the DOM to select the parent <p>
  let p = br.parentNode
  
  // Use regex to check if the <p> contains only linebreaks
  if( p.innerHTML.match(/^(<br\s?\/?>)+$/gi)) {
  
    // If so, add the class 'linebreak'
    p.classList.add('linebreak')
  }
}
/* Select the <p> following the one containing linebreaks */
p.linebreak + p {
  color: red
}
<p>Paragraph</p>
<p>Paragraph</p>
<p><br></p>
<p>Paragraph after linebreak (Should be red)</p>
<p>Paragraph</p>
<p><br><br></p>
<p>Paragraph after double linebreak (Should be red)</p>
<p>Paragraph</p>
<p>Paragraph</p>
agrm
  • 3,735
  • 4
  • 26
  • 36
2

I do not know a way in CSS, but using jQuery, you can do that. This is the HTML file:

 <!DOCTYPE html>
<html>
<head>
    <title></title>
    <link rel="stylesheet" type="text/css" href="s.css">
    <script type="text/javascript" src="jquery-3.2.1.min.js"></script>
    <script type="text/javascript" src="sh.js"> </script>
</head>
<body>
<p>LILI</p>
<br>
<p>Dina</p>
<p>ADEM</p>
</body>
</html>

Just use this jQuery:

$( document ).ready(function() {
  $( "br" ).nextAll().css( "font-size", "35px" );
});

So it will apply to all paragraph elements after this empty line.

Using that, Dina and ADEM will have font-weight: 35px, while LiLi still normal. If you want to use more than one style you can do:

$("br").nextAll().css({"color":“beige","font-size":“35px",....});

If you want to only target one paragraph after <br> use the jQuery closest() method.

TylerH
  • 20,799
  • 66
  • 75
  • 101
DINA TAKLIT
  • 7,074
  • 10
  • 69
  • 74
  • 1
    The question asks how to select a paragraph after another paragraph that's containing a line break (`


    This is to be selected

    `). The basis of this answer seems to be a bit off, finding paragraphs following a _sibling_ linebreak `

    These...

    ...are selected

    `. Maybe one could make use of CSS style selectors that are not (yet?) parts of the CSS specs, but still valid selectors in jQuery?
    – agrm Jan 21 '18 at 09:39
  • 1
    Sorry for the the misundrstood and thank you for sharing the right Answer.Allah bless you.Should i ommit it that people will not confused which is the right one? and thank u again for correcting the mistake. – DINA TAKLIT Jan 22 '18 at 18:02
  • You don’t have to apologize for helping people out! And your answer even got two upvotes, so you’ve clearly done something right :o) Unless your answer is straight up wrong, I would leave it as it is! – agrm Jan 22 '18 at 18:18