Fixing poor contrast in Tailwind using automation

Seeking a solution with CSS selectors, I am faced with the challenge of creating automatic color overrides for Tailwind to ensure our site meets WCAG guidelines consistently.

A tailwind plugin I developed can fix this issue automatically, but I have realized that my current approach to targeting CSS selectors is incorrect.

For instance, when the color light-grey is applied to white, I intend to automatically adjust it to black.

My current method involves using the following selectors:

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

However, this approach presents complications. It works well in this HTML structure:

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

But it disrupts 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, which is unintended as it resides within a black container!</span>
    </div>
</div>

I need guidance on how to adjust the CSS selectors so that if another background is specified in between them, the text color remains intact without corruption.

Perhaps something like this:

.bg-white :not(some fancy way to ensure no other backgrounds come between bg-white and the text color) .text-light-grey {
  color: black;
}

Is there a solution utilizing class~= or possibly the :has() selector?

Answer №1

Utilize the power of cascading effects by implementing CSS variables that cascade down through the bg-* classes. This approach offers the benefit of applying styles to an unlimited depth 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>

Answer №2

I have a suggestion that involves using two selectors. One will target the immediate child, while the other will check all intermediary elements with classes for background color. Do you think this approach would work in your situation?

.bg-white {
  background: white;
}

.bg-black {
  background: black;
}

.text-light-grey {
  color: lightgrey;
}

.bg-white>.text-light-grey,
.bg-white :not([class^="bg-"]) .text-light-grey {
  color: black;
}
<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 not black!</span>
  </div>

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

UPDATE: If you don't have many classes that need their color adjusted, you might want to consider this alternative method:

.bg-white {
  background: white;
}

.bg-black {
  background: black;
}

.text-light-grey {
  color: lightgrey;
}

.bg-blue {
  background: blue;
}


/* Similar to what you wrote in the comment */

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

[class*="bg-"]:not(.bg-white) .text-light-grey {
  color: lightgrey;
}
<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 not black!</span>
  </div>

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

  <div>
    <div class="bg-blue">
      <div>
        <span class="text-light-grey">This is nested and not black!.</span>
      </div>
    </div>
  </div>
</div>

Answer №3

I experimented with the use of currentcolor. I'm not certain how this would impact the overall outcome of your project, but I wanted to share it in case it proves helpful. This approach is reminiscent of @Wongjn's solution.

.bg-white {
  color: black;
}

.bg-black {
  color: white;
}

.text-light-gray {
  color: currentcolor;
}

https://play.tailwindcss.com/hQ4VW1RysN?file=css

Here's another variation that closely resembles @Wongjn's solution. I'm sharing it just in case it may be useful.

.bg-white {
  --text: black;
}

.bg-black {
  --text: white;
}

.text-light-gray {
  color: var(--text);
}

https://play.tailwindcss.com/CdT0KVvQga?file=css

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to position the main and aside elements next to each other?

Can anyone help me with positioning my main class next to the aside class instead of below it? I'm having trouble figuring it out. Here is the code snippet: aside { height: 100vh; width: 350px; justify-content: space-between; flex-directio ...

Exploring the Beauty of Trees through Twitter Bootstrap

I've been exploring the creation of a tree structure (similar to a directory tree) using mainly CSS and minimal JS for things like states. I'm wondering if there are any reliable tree plugins available that work well with bootstrap or jquery-ui b ...

Increase the spacing within div columns containing rows of uniform height

Is there a way to add some extra space between the H3-1 div and the H3-2 div? Ideally, I would like to achieve this without using custom CSS, but if necessary, that's okay too. I'd prefer to stick with the col-sm-6 class instead of using col-sm ...

How to align text to the right in an Android TextView using HTML

I need to display some HTML content in a TextView. I am aware that certain HTML tags are not compatible with Android, so I have turned to a third-party library to incorporate bulletpoints and numbered lists. However, I also require support for right alignm ...

The card-footer in Bootstrap 4 is not correctly aligned at the bottom of the page

I am currently encountering an issue with the alignment of the 'card-footer' class in Bootstrap 4 cards, as it is not aligning properly at the bottom of the page. If you would like to see the problem for yourself, here is the link to the JS Fidd ...

Unveiling the search bar as it expands horizontally from the center, causing the submit button to slide to adjust

Wishes and Aspirations My goal is to design an .input-group with one input[type=text] and one button[type=button]. Initially, the text box should be hidden, leaving only the button visible at the center of the page. Upon activation, the text box should ...

Creating a Div element to occupy an entire row is a simple task that can be achieved

Seeking a solution to automatically generate a DIV when our products do not fill up the entire row, using the MixItUp jQuery filter and sort plugin. Is there a JavaScript code that can detect the empty space in a row and create the necessary div to mainta ...

Substitute the <body> tag with a different tag

I am attempting to use the following code to replace the <body> tag on a page with <body id="khanqah"> echo str_replace("%body%", "khanqah", "<body id='%body%'>"); Although it adds <body id="khanqah"> to the page, the or ...

"Fixing the position of a div on the Samsung Galaxy S8 navigation bar to

Here is the HTML code I am working with: <div class="app-bar"> <a href="#'>icon</a> <a href="#'>icon</a> <a href="#'>icon</a> <a href="#'>icon</a> </div>' ...

I am encountering an issue with the `/deep/` selector while using sass-loader in my VueJS project

I'm currently working on implementing SASS in our Vue 2.6.10 webpack application as our team is looking to transition from LESS to SCSS for our legacy application. In my package.json, I've added the following dependencies under devDependencies ba ...

I am trying to utilize a cookie to retrieve the current month, date, and time. Unfortunately, the information is not displaying properly and the date is showing up as

I'm facing an issue with the code snippet below. I keep receiving an undefined error in this specific line of code: `var datemsg = nameOfMonths[date.getMonth()] + " " + date.getDate();`. When I simply use var date = new Date();, the values are succes ...

What is the best way to replicate the orange outline when focused?

I am in the process of creating a series of divs that can be navigated by the user using the tab key. I would like to incorporate the standard orange focus outline for these elements. Is there anyone who can provide guidance on how to achieve this? I unde ...

What is the meaning of this CSS acronym?

div[id^=picture]:target{ /*applying various styles here*/ } I stumbled upon the snippet of code shown above on a website discussing CSS image galleries. Can anyone clarify what this code accomplishes? Appreciate it. ...

Sending data to a Node.js server via an HTML email

Currently, I am developing a straightforward mailing application and exploring the possibilities of HTML editing in email communication. I want to offer the website administrator the option to approve or reject a reservation by providing them with a summa ...

Animate a CSS3 button to shift from the right to the left upon hover

I'm attempting to recreate the button effect seen on the right side of this website. Starting position : https://i.sstatic.net/TON94.jpg End position after animation : https://i.sstatic.net/UhrZ3.jpg Here is my HTML code : <div id="btnFeedbac ...

Ensure that the width of the container holding two "text" input boxes is appropriately set when utilizing the display flex property

MRE: .outer-container { width: 80%; } .form-container { display: flex; } .form-container input[type=text] { width: 50%; height: 40px; } .form-container label { margin-right: 10px; } <p>Type in your text (let an AI finish it):</p ...

Revise the design of the bootstrap-multiselect interface

I am currently utilizing the bootstrap-multiselect plugin for filtering options, which can be found at https://github.com/davidstutz/bootstrap-multiselect. Everything is functioning correctly except for one issue. My dropdown menu contains approximately 80 ...

Adding an active class to a menu when its submenu is clicked in JavaScript

Is it possible to add an active class to a parent menu when clicking on its sub-menu in Bootstrap? Below is the Bootstrap menu code: // Active navigation const currentLocation = location.href; const menuItem = document.querySelectorAll('.nav-link&ap ...

Switch the designation to Hover Class

I am working with nested divs and have assigned a CSS class to one of the inner divs. How can I trigger the hover effect of the class (class.hover) when the user hovers over the outer div, even if they are not directly over the inner div? I believe this m ...

What is the best method to ensure that a span element's width is maximized through CSS

Here is an example to consider: (live demo) Sample HTML: <div> <p> <strong>Stack</strong> <span>Overflow</span> </p> </div> CSS: p { background-color: #aaa; } span { backgr ...