You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Checkbox标签背景色的jQuery文字颜色切换异常排查

Hey there, let's figure out why that blue checkbox isn't switching to white text!

The Root Cause

Your third checkbox uses the named color blue for its data-color attribute. When you fetch the background color with label.css("background-color"), browsers often return this as an RGBA value (like rgba(0, 0, 255, 1)) instead of plain RGB. But your original isDark function's regex only looks for rgb(...) formats—so it fails to match, throws an error when trying to access match[1], and the text color never updates.

On top of that, your initial brightness check just adds up the RGB values, which works for basic cases but isn't as accurate as the standard WCAG relative brightness formula.

The Fix

We'll make two key improvements, plus an optional upgrade for better reliability:

  1. Update the regex to support both RGB and RGBA color formats
  2. Add fallback logic to handle named colors that don't parse right away
  3. (Optional) Switch to the WCAG brightness formula for more accurate dark/light detection

Updated Full Code

JavaScript

$(document).ready(function() {
  // Improved isDark function that handles RGB/RGBA and named colors
  function isDark(color) {
    // Match RGB or RGBA, with or without spaces between values
    var match = /rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*\d+)?\)/.exec(color);
    
    if (!match) {
      // If we can't parse the color directly, use a temp element to convert it
      const tempElement = $("<div>").css("background-color", color).appendTo("body");
      const convertedColor = tempElement.css("background-color");
      tempElement.remove();
      
      // Try parsing the converted color
      match = /rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*\d+)?\)/.exec(convertedColor);
      if (!match) return false; // Fallback to non-dark if all else fails
    }
    
    // Convert RGB values to 0-1 range for WCAG calculation
    const r = parseInt(match[1], 10) / 255;
    const g = parseInt(match[2], 10) / 255;
    const b = parseInt(match[3], 10) / 255;
    
    // Calculate relative brightness per WCAG standards
    const sR = r <= 0.03928 ? r / 12.92 : Math.pow((r + 0.055) / 1.055, 2.4);
    const sG = g <= 0.03928 ? g / 12.92 : Math.pow((g + 0.055) / 1.055, 2.4);
    const sB = b <= 0.03928 ? b / 12.92 : Math.pow((b + 0.055) / 1.055, 2.4);
    const luminance = 0.2126 * sR + 0.7152 * sG + 0.0722 * sB;
    
    // Return true if the color is dark enough for white text
    return luminance < 0.5;
  }

  $(".item").each(function() {
    var item = $(this).find(".input");
    var color = $(this).find("label").attr("data-color");
    item.change(function() {
      var label = $(this).closest(".item");
      var dot = $(this).closest(".item").find(".dot");
      var cancel = $(this).closest(".item").find(".cancel");
      
      if ($(this).prop("checked")) {
        var val = 0;
        dot.css({
          "-webkit-transform": "scale(" + val + ")",
          "-moz-transform": "scale(" + val + ")",
          "-ms-transform": "scale(" + val + ")",
          "-o-transform": "scale(" + val + ")",
          transform: "scale(" + val + ")",
          width: "0px"
        });
        label.css("background-color", color);
        cancel.css("display", "flex");
        // Use our improved isDark function here
        label.css("color", isDark(label.css("background-color")) ? "white" : "black");
      } else {
        var val = 1;
        label.css("background-color", "");
        dot.css({
          "-webkit-transform": "scale(" + val + ")",
          "-moz-transform": "scale(" + val + ")",
          "-ms-transform": "scale(" + val + ")",
          "-o-transform": "scale(" + val + ")",
          transform: "scale(" + val + ")",
          width: "12px"
        });
        cancel.css("display", "none");
        label.css("color", "");
      }
    });
  });
});

CSS (No Changes Needed)

label {
 display: flex;
 align-items: center;
 margin-left: 6px;
 font-size: 12px;
 line-height: 16px;
 font-weight: 400;
 padding: 4px 0;
 font-family: Roboto Mono, arial, sans-serif;
 letter-spacing: -0.2px;
 user-select: none;
 cursor: pointer;
 transition: all 0.25s ease;
}
input {
 display: none;
 visibility: hidden;
}
.boxes {
 display: flex;
 padding: 3rem
}
.item {
 background-color: white;
 padding-left: 8px !important;
 padding-right: 8px !important;
 border: 1px solid #dadce0;
 border-radius: 6px;
 display: flex;
 align-items: center;
 margin: .3rem;
 transition-property: all;
 transition-duration: 0.1s;
 transition-timing-function: ease-in-out;
}
.cancel {
 padding: 0px 6px;
 display: none;
 transition: all 0.25s ease;
}
.dot {
 border-radius: 50%;
 width: 12px;
 height: 12px;
 transition: all 0.25s ease;
}
.item:nth-child(1) .dot {
 background: rgb(255, 64, 129);
}
.item:nth-child(2) .dot {
 background: rgb(49, 231, 182);
}
.item:nth-child(3) .dot {
 background: blue;
}

HTML (No Changes Needed)

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="boxes">
 <div class="item">
 <span class="dot"></span>
 <label data-color="rgb(255, 64, 129)" class="checkbox" for="one">
 <input class="input" id="one" type="checkbox">Lobster
 <i class="far fa-times cancel"></i>
 </label>
 </div>
 <div class="item">
 <span class="dot"></span>
 <label data-color="rgb(49, 231, 182)" class="checkbox" for="two">
 <input class="input" id="two" type="checkbox">Tuna
 <div class="cancel">x</div>
 </label>
 </div>
 <div class="item">
 <span class="dot"></span>
 <label data-color="blue" class="checkbox" for="three">
 <input class="input" id="three" type="checkbox">Pine
 <div class="cancel">x</div>
 </label>
 </div>
</div>

What Changed?

  • Flexible Regex: The new regex matches both rgb() and rgba() values, even if there are spaces between the numbers.
  • Fallback for Named Colors: If the initial regex fails (like with blue), we create a temporary hidden element to let the browser convert the named color to a parsable RGB/RGBA value.
  • Accurate Brightness Check: We now use the WCAG relative brightness formula, which accounts for how human eyes perceive different colors (we're more sensitive to green light, for example). This makes the dark/light decision much more reliable than just adding RGB values.

With these changes, your blue checkbox will correctly switch to white text when checked, and the code will handle all kinds of color formats (named colors, hex, RGB, RGBA) smoothly.

内容的提问来源于stack exchange,提问作者Kyle Underhill

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:06:11