Reputation: 744
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.
Upvotes: 4
Views: 1387
Reputation: 15213
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.
$('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>
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>
Upvotes: 3
Reputation: 166
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: '"';
}
Upvotes: 0
Reputation: 272648
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>
Upvotes: 3
Reputation: 1053
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: '"';
}
Upvotes: 0