Change text color based on brightness of the covered background area?

前端 未结 8 1560
悲哀的现实
悲哀的现实 2020-11-27 09:53

I\'ve thought about the following for a while already, so now I want to know your opinions, possible solutions, and so on.

I am looking for a plugin or technique tha

相关标签:
8条回答
  • 2020-11-27 09:58

    If you are using ES6, convert hex to RGB then can use this:

    const hexToRgb = hex => {
        // turn hex val to RGB
        const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
        return result
            ? {
                  r: parseInt(result[1], 16),
                  g: parseInt(result[2], 16),
                  b: parseInt(result[3], 16)
              }
            : null
    }
    
    // calc to work out if it will match on black or white better
    const setContrast = rgb =>
        (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000 > 125 ? 'black' : 'white'
    
    const getCorrectColor = setContrast(hexToRgb(#ffffff))
    
    0 讨论(0)
  • 2020-11-27 10:05

    By combining the answers [ @alex-ball , @jeremyharris ] I found this to be the best way for me:

            $('.elzahaby-bg').each(function () {
                var rgb = $(this).css('backgroundColor');
                var colors = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
    
                var r = colors[1];
                var g = colors[2];
                var b = colors[3];
    
                var o = Math.round(((parseInt(r) * 299) + (parseInt(g) * 587) + (parseInt(b) * 114)) /1000);
    
                if(o > 125) {
                    $(this).css('color', 'black');
                }else{
                    $(this).css('color', 'white');
                }
            });
    *{
        padding: 9px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
    <div class='elzahaby-bg' style='background-color:#000'>color is white</div>
    
    <div class='elzahaby-bg' style='background-color:#fff'>color is black</div>
    <div class='elzahaby-bg' style='background-color:yellow'>color is black</div>
    <div class='elzahaby-bg' style='background-color:red'>color is white</div>

    0 讨论(0)
  • 2020-11-27 10:07

    This article on 24 ways about Calculating Color Contrast might be of interest to you. Ignore the first set of functions because they're wrong, but the YIQ formula will help you determine whether or not to use a light or dark foreground color.

    Once you obtain the element's (or ancestor's) background color, you can use this function from the article to determine a suitable foreground color:

    function getContrastYIQ(hexcolor){
        hexcolor = hexcolor.replace("#", "");
        var r = parseInt(hexcolor.substr(0,2),16);
        var g = parseInt(hexcolor.substr(2,2),16);
        var b = parseInt(hexcolor.substr(4,2),16);
        var yiq = ((r*299)+(g*587)+(b*114))/1000;
        return (yiq >= 128) ? 'black' : 'white';
    }
    
    0 讨论(0)
  • 2020-11-27 10:08

    mix-blend-mode does the trick:

    header {
      overflow: hidden;
      height: 100vh;
      background: url(https://www.w3schools.com/html/pic_mountain.jpg) 50%/cover;
    }
    
    h2 {
      color: white;
      font: 900 35vmin/50vh arial;
      text-align: center;
      mix-blend-mode: difference;
      filter: drop-shadow(0.05em 0.05em orange);
    }
    <header>
      <h2 contentEditable role='textbox' aria-multiline='true' >Edit me here</h2>
    </header>

    Addition (March 2018): Following, a nice tutorial explaining all different types of modes/implementations: https://css-tricks.com/css-techniques-and-effects-for-knockout-text/

    0 讨论(0)
  • 2020-11-27 10:09

    Interesting resources for this:

    • W3C - Ensure that foreground and background color combinations provide sufficient contrast
    • Calculating the Perceived Brightness of a Color

    Here's the W3C algorithm (with JSFiddle demo too):

    const rgb = [255, 0, 0];
    
    // Randomly change to showcase updates
    setInterval(setContrast, 1000);
    
    function setContrast() {
      // Randomly update colours
      rgb[0] = Math.round(Math.random() * 255);
      rgb[1] = Math.round(Math.random() * 255);
      rgb[2] = Math.round(Math.random() * 255);
    
      // http://www.w3.org/TR/AERT#color-contrast
      const brightness = Math.round(((parseInt(rgb[0]) * 299) +
                          (parseInt(rgb[1]) * 587) +
                          (parseInt(rgb[2]) * 114)) / 1000);
      const textColour = (brightness > 125) ? 'black' : 'white';
      const backgroundColour = 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')';
      $('#bg').css('color', textColour); 
      $('#bg').css('background-color', backgroundColour);
    }
    #bg {
      width: 200px;
      height: 50px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <div id="bg">Text Example</div>

    0 讨论(0)
  • 2020-11-27 10:13

    I've found the BackgroundCheck script to be very useful.

    It detects the overal brightness of the background (be it a background image or a color), and applies a class to the assigned text-element (background--light or background--dark), dependent on the brightness of the background.

    It can be applied to still and moving elements.

    (Source)

    0 讨论(0)
提交回复
热议问题