Tips on accessing the value of a CSS style using the CSS function

When working with Javascript, I often find myself creating multiple divs dynamically. This can be achieved by inserting code similar to the following:

'<div style="background-color:' + bgColor + '</div>'

One common challenge I face is determining whether to set the text color to black or white based on the background's luminosity. There are two approaches to this problem - either handling it entirely through JavaScript or utilizing CSS exclusively. Personally, I lean towards the CSS solution, although I am unsure of how to extract the background color for use within a CSS function, such as the one shown below:

@function set-color($color) {
  @if (lightness($color) > 40) {
    @return #000;
  }
  @else {
    @return #FFF;
  }
}

How can I retrieve the background color in order to implement something like the snippet mentioned here?

div { color: set-color(???); }

Another aspect to consider could be using mix-blend-mode. How would that fit into this scenario?

Answer №1

There have been various suggestions in the discussion regarding choosing between black and white text color depending on the background.

Many of these ideas have already been addressed in the comments. Let's break down each suggestion:

Using CSS mix-blend-mode - not a feasible option, as there isn't a single setting that guarantees legibility on all backgrounds.

Utilizing CSS (the preferred approach) - unfortunately, this is not possible because the div requiring dynamic text color based on the background is generated by JavaScript at runtime.

Employing JS - yes, it can be done. Since the div is created by JS and has its background-color set dynamically, setting the text color alongside is efficient.

The JS code mentioned in the question now includes a color setting:

'<div style="background-color:' + bgColor + '; color: ' + textBlackOrWhite(bgColor) + ';"'

Below is a code snippet defining the function for determining whether to use black or white text color based roughly on the brightness of the background. Refer to the related discussions on Stack Overflow for insights into human color perception complexities.

//function retrieved from https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
function textBlackOrWhite(hex) {
  // Expanding shorthand form (e.g. "03F") to full form (e.g. "0033FF")
  var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
  hex = hex.replace(shorthandRegex, function(m, r, g, b) {
    return r + r + g + g + b + b;
  });

  let result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);//also checks we have a well-formed hex number

  //Function inspired by https://stackoverflow.com/questions/596216 provided by @FranciPenov for an approximation: (R+R+G+G+G+B)/6
  let itsbright = function () { return ((2*parseInt(result[1], 16) + 3*parseInt(result[2], 16) + parseInt(result[3], 16))/6)>127; }
  return result ? (itsbright()) ? '#000000' : '#ffffff' : '#000000';//defaults to black if bgColor wasn't a valid 3 or 6 digit hex color
}
<div id="div" style="font-family: monospace; box-sizing: border-box; margin: 0; padding: 40px 0; width: 100px; height: 100px; border-style: solid; border-radius: 50%; background-color: black; color: white;text-align:center;">#ffffff</div>
Click to select a background color: <input id="input" placeholder='#00000' type='color' value='#000000'/>
<button onclick="let d = document.getElementById('div'); let i = document.getElementById('input'); d.innerHTML = i.value; d.style.backgroundColor = i.value; d.style.color = textBlackOrWhite(i.value);">Submit</button>

Answer №2

I'm interested in automatically adjusting the text color based on the background's luminosity, switching between black and white.

Although it may not align exactly with your query, a CSS-only solution for ensuring universal text readability irrespective of the background-color is to implement text with a white fill and a black outline (or vice versa).

Achieve this effect using 4 text-shadows:

text-shadow: 1px 1px rgb(0, 0, 0), -1px 1px rgb(0, 0, 0), -1px -1px rgb(0, 0, 0), 1px -1px rgb(0, 0, 0);

Example in Action

const divs = [...document.getElementsByTagName('div')];

for (div of divs) {

  let redValue = Math.floor(Math.random() * 255);
  let greenValue = Math.floor(Math.random() * 255);
  let blueValue = Math.floor(Math.random() * 255);
  
  div.style.backgroundColor = `rgb(${redValue}, ${greenValue}, ${blueValue})`;
}
div {
  float: left;
  width: 180px;
  height: 40px;
  margin: 0 6px 6px 0;
  line-height: 40px;
  color: rgb(255, 255, 255);
  font-size: 32px;
  text-align: center;
  text-shadow: 1px 1px rgb(0, 0, 0), -1px 1px rgb(0, 0, 0), -1px -1px rgb(0, 0, 0), 1px -1px rgb(0, 0, 0);
  background-color: yellow;
}
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>

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

Once the <a> element is clicked, ensure that the function finishes executing before attempting to click/process it again

Utilizing jQuery.get for AJAX requests, I trigger a server request when the user clicks on the <a> element. The response is then used to update the content within the <div id='aaa'>. However, if the user clicks on the <a> rapid ...

What causes the scrollTop to appear erratic?

There is a simple issue that I find difficult to explain in text, so I have created a video demonstration instead. Please watch the video at this link: The functionality on my page works perfectly when scrolling down, as it replaces images with the next i ...

The favicon appears broken upon opening a new tab

Usually, I use a favicon PNG file for my website. It works perfectly and I can see my favicon on the browser tab. However, when I open a PDF document in a new page from my Angular app, I notice that there is a broken icon on the browser tab. Here is how I ...

Tips for Sending Request Parameters to Angular Application

My Angular app, created with Angular CLI, is hosted on Heroku using express. The setup looks like this: const express = require('express'); const app = express(); // Serve the static files in the dist directory app.use(express.static(__dirname + ...

The jQuery function $.fn.myfunction appears to be malfunctioning

Here's the code I'm working with: [[A]] // jquery.fn.code (function( $ ){ $.fn.flash = function(duration) { this.animate({opacity:0},duration); this.animate({opacity:0},duration); }; })( jQuery ); 1. $(document).ready ...

Is it possible to show a specific portion of an image based on its size using only CSS?

Is there a way to use CSS to display only a specific part of an image based on its width and height? If not possible with CSS alone, would TypeScript be a solution? For example, if I have an image that is 2,434px × 1,697px inside a div that is 700x700, h ...

Transferring HTML content through AJAX to a PHP script for database storage. The data gets saved correctly, up to "&nbsp;" limit

i have a javascript code that submits HTML form content: $.ajax({ url : 'include/speakers.php', type : 'POST', data : "htmlText="+htmlField", dataType : 'html', success : function ( ...

How can we prevent the continual overwriting of Object values?

I'm currently working on extracting data from the USDA Food Data Central API. Specifically, I'm interested in retrieving the "name" and "amount" values under the "nutrient" section. The excerpt below shows the information retrieved: Input- repor ...

Importing a JavaScript file into another JavaScript file as text in React Native can be a convenient way

In my project, I have a file named MyFirstPage.js that contains the following code snippet: renderCards() { let icon = this.state.icon; .... .... .... } This code is responsible for rendering cards within the main render function. However, as the ...

Safari showing white flash upon setting background-image src using Intersection Observer?

I've done extensive research but I'm still struggling to solve this issue. It only seems to be happening on Safari (Mac & iOS), while everything works smoothly on Chrome, Firefox, Edge, and other browsers. UPDATE: The flickering problem also per ...

Modify the placeholder HTML once a username has been submitted

In order to maximize efficiency, I have included an input box with a placeholder that reads: <input id="username-search" placeholder="explore another user's work"> Once the username is entered, I want to modify the placeholder text to somethin ...

What is the best way to retrieve the data response from an ajax request?

I am looking for help on how to preview the data received from my ajax request. I need to verify if the data is correct before proceeding. Below is the code snippet in question: <script type="text/javascript> var globalBase_Url = "{$ba ...

NextJS throwing an error: Unable to access property 'json' as it is undefined

In my NextJS environment, I have a code file in the pages folder that fetches data from an external API Rest. The code is functional as the console.log(response); line displays the JSON API response in the console. However, I encountered an error in the br ...

Generate a JSON Object array by collecting data from various elements to make it dynamic

Seeking assistance in creating a dynamic array of JSON objects from the values of various elements. Below are some examples of these elements. There are more elements contributing to the JSON values, but I don't want to repeat the same code three time ...

What is the method to create a polygon in its entirety by utilizing a for loop within Javascript?

After successfully using the Canvas of HTML to draw a convex polygon, I encountered an issue. In the provided code snippet, t2 represents an array of points with getX() and getY() methods. The drawing function performs as expected until it reaches the seg ...

What is the best way to assign a distinct index value to each object in an array

When I use the function below to add an index to each array object, all IDs end up with the same value when I check console.log: var foo = [...this.props.articleList]; foo.forEach(function(row, index) { row.id = index+1; }); console.log(foo); My des ...

Issue: Child Pages not found in Nuxt RoutingDescription: When navigating

Currently working on a Nuxt application that utilizes the WordPress REST API to fetch content. While my other routes are functioning correctly, I am facing challenges with nested pages. The structure I have implemented in my Nuxt app is as follows: pages ...

Removing files from the S3 bucket and database simultaneously. Execute each function sequentially

Struggling with an API call that should delete an image from both an S3 bucket and a MySQL database. However, encountering an issue where the S3 image cannot be found because it is being deleted from the database first. // Router code: //req.body is an ar ...

Acquire the "value" and utilize it within a different function

I am facing a minor issue with my JavaScript code. I have been working on creating a gallery page. In this page, there is an icon that triggers a function called "comment" when clicked. function comment() { var div = document.getElementById("commentdiv") ...

Combining the power of JavaScript with ASP.NET

My goal is to create a link that will change a session variable upon onclick event, like so: <a href="/Index" onclick="<% HttpContext.Current.Session["location"] = location;%>" > <%=location%> </a> However, as the page proces ...