Search code examples
javascripttextcolorsbackground

Automatically change text color to assure readability


Users can set the background-color of a button through a textbox that accept RGB hexadecimal notation: ff00ff, ccaa22, etc. So I need to set the text color to the opposite. Not sure about the terminology (opposite color) but the idea is assure readability.


Solution

  • You can invert the background color and use it as foreground color. The following algorithm produces results identical to the "Image > Adjustments > Invert" color command in Photoshop:

    function invertColor(hexTripletColor) {
        var color = hexTripletColor;
        color = color.substring(1);           // remove #
        color = parseInt(color, 16);          // convert to integer
        color = 0xFFFFFF ^ color;             // invert three bytes
        color = color.toString(16);           // convert to hex
        color = ("000000" + color).slice(-6); // pad with leading zeros
        color = "#" + color;                  // prepend #
        return color;
    }
    /*
     * Demonstration
     */
    function randomColor() {
        var color;
        color = Math.floor(Math.random() * 0x1000000); // integer between 0x0 and 0xFFFFFF
        color = color.toString(16);                    // convert to hex
        color = ("000000" + color).slice(-6);          // pad with leading zeros
        color = "#" + color;                           // prepend #
        return color;
    }
    $(function() {
        $(".demolist li").each(function() {
            var c1 = randomColor();
            var c2 = invertColor(c1);
            $(this).text(c1 + " " + c2).css({
                "color": c1,
                "background-color": c2
            });
        });
    });
    body { font: bold medium monospace; }
    .demolist { margin: 0; padding: 0; list-style-type: none; overflow: hidden; }
    .demolist li { float: left; width: 5em; height: 5em; text-align: center; }
    <ul class="demolist">
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
    </ul>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

    Note that this is not a bullet-proof solution. Colors that are close to 50% brightness and/or saturation will not produce sufficient contrast.

    Demo on jsFiddle