DEV Community

Discussion on: CSS :has(.parent-selectors) 👪

Collapse
 
ingosteinke profile image
Ingo Steinke

Here is an example (similar markup from a demo shop, with h2 headings. The top-level cms-section.cms-section-default only differ by their pos-n position classes which have no benefit compared to nth-child.

Any other distinction, even the content id's, can only be made on a descendent level.

The structure is as follows:

<div class="cms-sections">
    <div class="cms-section pos-0 cms-section-default">
        <div class="cms-block-container" style="/* some inline style */">
            <div class="cms-block-container-row row cms-row">
                <div class="col-12" data-cms-element-id="somecrypticidstring">
                    <div class="cms-element-text">
                        <h2>Headline (not every CMS content type has a headline</h2>
                        <p>Lorem ipsum...</p>
                    </div> 
                </div>
            </div>
        </div> 
    </div>
</div>
Enter fullscreen mode Exit fullscreen mode

Here is a screenshot as well

screenshot of shopware CMS markup with a lot of nested divs having generic class names

Collapse
 
iainsimmons profile image
Iain Simmons

Thanks, but sorry I still don't see the value here.

Your CSS only applied width: 100% in the :has selector, which a div would have by default as a block level element.

Otherwise, if targeting the h2 or p, you could do that with descendent selectors or the :not([class]) as I suggested in my previous comment.

Perhaps a better example could be for forms or something, where you could combine with the :invalid pseudo-class or similar to change the parent div styles:

.form-control:has(:invalid) {
  background-color: rgb(220 53 69 / 0.25);
}
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
ingosteinke profile image
Ingo Steinke

Thanks for the form example!

Still don't see how you would have done it with not when all the div elements are undistinguishable by their class names. Of course, a div should be a block level element by default. You are lucky you didn't have to deal with the existing CSS. Using descendant selectors was what I did in the end, still didn't find it elegant or robust, probably it will break after the next framework update.

Better way would be if the customers content editors would choose different types of block templates which could then be given distinct class names.
Complex code should always arise suspicion that something might be conceptually wrong by design and could be solved at the problem's root cause. That's what I meant by "hotfixing a hotfix" in CSS (oh, and don't even start to count the number of !important in the existing style sheets).

Thread Thread
 
iainsimmons profile image
Iain Simmons

Sorry, I didn't make that clear. The :not([class]) would be for targeting the paragraphs or headings that come from the CMS or whatever, where you don't have the ability to add or target classes.

e.g.

body {
  color: #000;
}

p:not([class]) {
  font-size: 1rem;
  color: #222;
}

.lead {
  font-size: 1.25rem;
}
Enter fullscreen mode Exit fullscreen mode
<main>
  <p class="lead">Lorem ipsum...</p>
  <!-- other content not generated by the CMS -->

<div class="cms-sections">
    <div class="cms-section pos-0 cms-section-default">
        <div class="cms-block-container" style="/* some inline style */">
            <div class="cms-block-container-row row cms-row">
                <div class="col-12" data-cms-element-id="somecrypticidstring">
                    <div class="cms-element-text">
                        <h2>Headline</h2>
                        <p>CMS Content. Lorem ipsum...</p>
                    </div> 
                </div>
            </div>
        </div> 
    </div>
</div>
Enter fullscreen mode Exit fullscreen mode

The lead paragraph would be black, inheriting the color from the body.

So the not selector makes them act like global element styles that you opt out of by simply adding a class to the HTML element (even a blank string).

The assumption is that anything you want custom styling for that isn't regular body copy content (from a CMS or similar), you probably have control over the HTML and would normally be adding classes to style them anyways.

But anyways, this is obviously a whole other conversation! 🙂