4

I have the next scenario

<blockquote>
    <p>text text text</p>
    <p>text text text</p>
    <p><cite>author cite</cite></p>
</blockquote>

I am trying to select just the p elements that are inside of blockquote but not contain child cite elements to add a " before and after every p element

my approach is

blockquote p:not(:has(> cite))::before,
blockquote p:not(:has(> cite))::after
{
  content: '"';
}

but it is not working as it still has no support yet, anyone can give me a hand? Thank you in advance

EDIT:
I want to point, It is not possible to modify the HTML by adding some class to p elements because the HTML is provided from a remote server.

5
  • i think is impossible, why don't use js? Commented Dec 18, 2020 at 11:50
  • If its from a remote server , you should be probably using an iframe . And You can not change the styles of the page that resides within the iframe. Or are you doing a webscrap in your server of other websites and forwarding to your your site by appending some stylesheets ? Commented Dec 18, 2020 at 13:26
  • @sandrin joy The server parses a txt file and extracts the data, then it converts to HTML and it stores to a DB and after that is provided to the client app through API that resides in a server. I don't need an iframe, I have access to the HTML code in the client but it shouldn't be modified, anyway, this is not the scope of the question. Commented Dec 18, 2020 at 13:44
  • "I have access to the HTML code in the client but it shouldn't be modified" - but isn't this (changing css) a part of modifying html. ? Commented Dec 18, 2020 at 14:01
  • @SandrinJoy Maybe I am wrong but IMO, modify the CSS it is not understood as modify the HTML Commented Dec 18, 2020 at 14:50

4 Answers 4

3

A hacky idea to hide the content with the cite element

blockquote p::before,
blockquote p::after {
  content: '"';
}

blockquote p cite {
  background: #fff; /* this need to match the main background */
  margin: 0 -6px; /* a trial and error value, you need to adjust it based on your font*/
  display: inline-block;
  position: relative;
}
<blockquote>
  <p>text text text</p>
  <p>text text text</p>
  <p><cite>author cite</cite></p>
</blockquote>

Sign up to request clarification or add additional context in comments.

6 Comments

He doesn't want to hide the cite element. This doesn't solve it.
@TimonNetherlands where did you see that I am hiding the cite?
Yes. I took a look, I take it back. Nice one.
The problem is when he change child
@SimoneRossaini can you explain better what you mean by changing the child?
|
3

I have given two solutions for jquery and javascript. These decisions have the same principle.

In this code, the parent <p> is accessed from the assigned tag <cite>, with the subsequent assignment of class no-content with the missing content: parameter:

.no-content:before,
.no-content:after {
  content: none;
}

Default html structure.

  • jquery solution:

$('cite').closest('p').addClass('no-content');
blockquote p::before,
blockquote p::after
{
  content: '"';
}

.no-content:before,
.no-content:after {
  content: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<blockquote>
    <p>text text text</p>
    <p>text text text</p>
    <p><cite>author cite</cite></p>
</blockquote>

  • javascript solution:

document.querySelector('cite').closest('p').classList.add('no-content');
blockquote p::before,
blockquote p::after
{
  content: '"';
}

.no-content:before,
.no-content:after {
  content: none;
}
<blockquote>
    <p>text text text</p>
    <p>text text text</p>
    <p><cite>author cite</cite></p>
</blockquote>

2 Comments

As this question is about CSS I can not mark it as the correct solution, but it is a very good solution using javascript.
@Raikish, Thanks for your feedback. But you will not solve your problem correctly without css. If there is a solution for css, then this solution will be a "crutch". If you want the right solution, then use the javascript solution.
0

The closest option CSS offers is blockquote p *:not(cite). The problem is that the wildcar selector * selects anything but text nodes, so it doesn't help.

Unfortunately, the :empty select does exactly that, as in it does lookup text nodes so blockquote p:empty also won't work since it doesn't consider any of the p elements to lack children.

Luckily, a new selector is scheduled to appear, namely :has which will allow to perform selections like blockquote p:not(:has > cite). We're not there yet so until then adding a span to your p elements may be a solution:

  <blockquote>
    <p><span>text text text<span></p>
    <p><span>text text text</span></p>
    <p><cite>author cite</cite></p>
  </blockquote>

In CSS:

blockquote p *:not(cite)::before,
blockquote p *:not(cite)::after
{
  content: '"';
}

Or with the same result:

blockquote p span::before,
blockquote p span::after
{
  content: '"';
}

Comments

0

There are multiple ways you can achieve that. You can add CSS selectors, such as classes to the p tags you want to surround with the content.

HTML:

<blockquote>
  <p class="quote">text text text</p>
  <p class="quote">text text text</p>
  <p><cite>author cite</cite></p>
</blockquote>

CSS:

.quote::after,
.quote::before {
  content: '"';
}

or if you prefer just using elements as selectors, you can select the last p to remove it's quote:

CSS:

blockquote p::last-child:after,
blockquote p::last-child:before {
  content: none;
}

Or with the same result:

blockquote p span::before,
blockquote p span::after
{
  content: '"';
}

3 Comments

I can not modify the HTML because it is provided from some server, also in some situations the cite is not in the last p of the blockquote
Can you use javascript? Then some of us might be able to come with a solution in javscript. Look at sergey kuznetsov's response for example.
I did some digging and on MDN and CSS selectors and I found nothing that could help you. I am sorry :/. The closest I got was a selector called :has, but sadly it doesn't work but you can have a look.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.