Raikish
Raikish

Reputation: 744

How to not apply styles to a particular element in CSS?

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

Answers (4)

s.kuznetsov
s.kuznetsov

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.

  • 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>

Upvotes: 3

Etsh
Etsh

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

Temani Afif
Temani Afif

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

TimonNetherlands
TimonNetherlands

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

Related Questions