htmlcsstailwind-csswcagparent-selector

Automatically repair bad contrast in Tailwind


I have a problem I need to solve with CSS selectors. I am trying to make automatic color overrides for Tailwind to have our site always comply to WCAG guidelines.

I have a tailwind plugin I've written which automatically fixes this problem - but I've realized the way I'm targeting the CSS selectors is off.

Assume there is a color, white. And another color - light grey. When light-grey is imposed on white, I want to automatically correct the color to black.

I am doing this currently with the following selectors

.bg-white .text-light-grey {
  color: black;
}

However, this introduces problems! It works fine on this HTML structure:

<div class="bg-white">
    <span class="text-light-grey">This is now black.</span>
</div>

But it will ruin this structure

<div class="bg-white">
    <span class="text-light-grey">This is now black.</span>

    <div class="bg-black">
        <span class="text-light-grey">This is also now black, but it shouldn't be - It's inside a black container!.</span>
    </div>
</div>

How can I modify the CSS selectors, so that when there is another background specified between them, the color is not corrupted.

Something like this

.bg-white :not(some fancy way to make sure there are no other bgs inbetween bg white and the text color) .text-light-grey {
  color: black;
}

This has got to be possible right? Maybe something with class~= or something?

Edit: Does anyone with knowledge of the :has() selector know if this could be solved using it?


Solution

  • Consider leveraging the cascade. Use CSS variables that automatically cascade down on the bg-* classes. This has the advantage that it would work for an infinite amount of nesting:

    tailwind.config = {
      theme: {
        extend: {
          colors: {
            'light-gray': 'rgb(var(--light-gray) / <alpha-value>)',
          }
        },
      },
    };
    .bg-white {
      --light-gray: 0 0 0;
    }
    
    .bg-black {
      --light-gray: 255 255 255;
    }
    <script src="https://cdn.tailwindcss.com"></script>
    
    <div class="bg-white">
      <span class="text-light-gray">This is now black.</span>
    
      <div class="bg-black">
        <span class="text-light-gray">This is also now black, but it shouldn't be - It's inside a black container!.</span>
    
        <div class="bg-white">
          <span class="text-light-gray">This is now black.</span>
    
          <div class="bg-black">
            <span class="text-light-gray">This is also now black, but it shouldn't be - It's inside a black container!.</span>
          </div>
    
          <div class="bg-white">
            <span class="text-light-gray">This is now black.</span>
    
            <div class="bg-black">
              <span class="text-light-gray">This is also now black, but it shouldn't be - It's inside a black container!.</span>
            </div>
          </div>
        </div>
      </div>
    </div>