_______               __                   _______
       |   |   |.---.-..----.|  |--..-----..----. |    |  |.-----..--.--.--..-----.
       |       ||  _  ||  __||    < |  -__||   _| |       ||  -__||  |  |  ||__ --|
       |___|___||___._||____||__|__||_____||__|   |__|____||_____||________||_____|
                                                             on Gopher (inofficial)
   URI Visit Hacker News on the Web
       
       
       COMMENT PAGE FOR:
   URI   How to have the browser pick a contrasting color in CSS
       
       
        HocusLocus wrote 1 hour 19 min ago:
        TLDR: "This browser does not support contrast-color(). Try this demo in
        a browser that does, like Safari Technology Preview."
       
        lancekey wrote 1 hour 45 min ago:
        I remember doing something similar back in the day using YIQ value -
        
   URI  [1]: https://medium.com/@gkobilansky/a-color-changing-take-on-the-s...
       
        Hyperlisk wrote 1 hour 52 min ago:
        Here's one method for this that I have bookmarked:
        
   URI  [1]: https://miunau.com/posts/dynamic-text-contrast-in-css/
       
        rendaw wrote 2 hours 23 min ago:
        You choose all the colors in a color scheme, so why is this easier than
        just choosing a contrasting button text color in the first place? This
        is a feature to help teams so dysfunctional that individuals are free
        to choose an inconsistent background color yet at the same time aren't
        able to choose a contrasting foreground color?
        
        What really needs a fix is when you have text over an image or other
        diverse background (like, sticky/fixed text over a scrolling
        background) and need to have it always visible.  And... this doesn't
        help at all.
        
        So not only does this only (maybe) help in very questionable
        circumstances, they needed to come up with an entirely new verb for it,
        it has an anemic feature set (only selects black or white), and they
        did it with the worst possible contrast selection algorithm (doesn't
        select the choice with the most perceptual contrast). Way to go!
       
          ezfe wrote 1 hour 36 min ago:
          > and they did it with the worst possible contrast selection
          algorithm
          
          They specifically say they are following WCAG 2 algorithms, and that
          WCAG 3 may correct this issue. They say that they can easily adjust
          to use the better algorithm in the future when it's standardized.
       
          healsdata wrote 1 hour 36 min ago:
          Its limiting to dismiss a tool out of hand simply because you haven't
          encountered a situation where that tool would be useful.
          
          Plenty of web sites allow the end-user to select colors[1], or
          automatically derive colors from assets provided by the end-user. For
          those that care about accessibility, they typically calculate
          contrasting colors to prevent the user from creating a non-accessible
          experience. A built-in CSS tool like this will, hopefully, encourage
          more sites to provide a basic amount of accessibility while in no way
          hindering those who want to build an even better experience.
          
          It would be cool if this was more customizable like the npm
          contrast-color package but the blog post details why they started
          with white/black with intentions of changing the algorithm later. [1]
          Example:
          
   URI    [1]: https://coolors.co/8fbfe0-7c77b9-1d8a99-0bc9cd-14fff7
       
        akkartik wrote 3 hours 52 min ago:
        Recently I made a little hypertext browser in 500 lines. Then I added
        this sort of automatic contrasting color selector in another 200 lines.
        In the process I learned a lot about color spaces. [1] One difference
        in my approach is: it's an authoring-time tool. If no sufficiently
        contrasting color exists you get an error. And so you have to change
        the background until there is one.
        
   URI  [1]: https://akkartik.name/post/2025-04-04-devlog
       
        econ wrote 4 hours 54 min ago:
        Back when systeem colors were actually cool I made some system color
        styles. It looked really nice but you don't know how they contrast.
        That one is called [say] buttonFace and another buttonText turned out
        to to be meaningless. Someone wrote some js for me that took
        getComputedStyle and calculated the contrast. If it was unacceptable it
        either took a second candidate color or failed back on text-shadow to
        darken or lighten an aura around the text sufficiently. [1] I forget
        the calculation but thinking about it you can probably just take the
        average of the 3 rgb values and compare them(?) It would produce a low
        value for blue and give preference to white text.
        
   URI  [1]: https://i.sstatic.net/18bQt.png
       
        flysand7 wrote 5 hours 45 min ago:
        Sadly, doesn't work on firefox yet :(
       
        ZYbCRq22HbJ2y7 wrote 5 hours 49 min ago:
        Tentative future of this feature, that addresses many concerns in this
        thread:
        
   URI  [1]: https://drafts.csswg.org/css-color-6/#colorcontrast
       
        jjcm wrote 6 hours 58 min ago:
        This is a great overview of the pros/cons of this. For those creating
        just a simple site, this is a solid easy way to have proper contrast.
        
        For those making anything at a production scale where you need wcag
        compliance however, I'd avoid this and leverage a proper semantic token
        layer. Semantic tokens will help both accelerate your dev cycle, and
        they'll help guarantee proper contrast ratios in a way that looks
        visually better than just switching your foreground layer to black or
        white. The great thing about a semantic token layer is they're
        extremely easy to theme, which means you get light/dark theming for
        very little additional cost. You can also create separate WCAG2 / APCA
        accessible themes, should your brand color be one of the ones that
        WCAG2 has issues with - will get you compliance while still providing a
        better visual contrast option.
        
        This is kind of my niche domain specialty - I run the variables/tokens
        stream at Figma, and I've worked on the dark mode implentation for both
        Figma and Atlassian. Happy to answer any questions about
        tokens/themes/accessible color.
       
          hk1337 wrote 3 hours 37 min ago:
          I don’t disagree, in fact I absolutely agree but the last 2/3 just
          sounds like meaningless jibber jabber to make yourself look smart.
          I’m not saying it’s not true but it’s word vomit.
          
          I like the feature but in a corporate site/application, you don’t
          want to rely on this function because you cannot control what the
          result is going to be. For all I know, WebKit could fix some later
          bug or change something that changes the result color to something
          that I don’t want.
       
            throwaway290 wrote 13 min ago:
            If you don't understand something it doesn't always make that a
            word vomit:)
       
          charrondev wrote 6 hours 45 min ago:
          What do you mean by semantic tokens?
          
          This exact type of functionality has caused a major project a work on
          to use CSS in JS (for relative colors and contrast colors.
          
          I’m glad to see this type of thing coming around the corner and
          look forward to it being widely available in a couple years.
       
            jjcm wrote 6 hours 26 min ago:
            With regards to color on the web, semantic tokens refer to css
            variables that are named in a way that describes their use, ie:
            
            * bg-brand (this would be used whenever you need your brand color
            as a background)
            
            * text-danger (likely a red text color)
            
            * icon-warning-hover (likely a dark yellow-orange that's slightly
            different from icon-warning)
            
            Generally speaking, there are three "levels" of tokens: primitive,
            semantic, and component. Primitive tokens describe the value. In
            the case of color, this might be a color ramp. IE red/100, red/200,
            red/300. Semantic tokens reference primitive tokens. IE bg-brand
            might have its value set to blue/300. This layer is sometimes
            called a "reference" layer because of this, but I'm not a fan of
            that nomenclature since the component layer also references the
            semantic layer. The component layer is one that describes where in
            a component the token should be used, ie button-bg or button-text.
            I highly, HIGHLY recommend against using a component layer though
            in all but the most extreme multi-brand situation. If you aren't
            unilever, you should never use component tokens.
       
              ZYbCRq22HbJ2y7 wrote 5 hours 38 min ago:
              Aren't there many, many schemes for naming tokens in design
              systems? Aren't you being a bit forward in presenting this as a
              general practice?
              
   URI        [1]: https://medium.com/eightshapes-llc/naming-tokens-in-desi...
       
                ryanwhitney wrote 5 hours 7 min ago:
                Not parent, but the generalization is true. There’s usually a
                base layer (red/300, etc) and a more semantic layer
                (.text-danger).
                
                As your link covers, there’s then a million different ways to
                implement/extend that based on whatever theming and systems
                you’re implementing on top.
       
              recroad wrote 5 hours 47 min ago:
              This only works if you don’t let users theme your site. If you
              do, then OPs approach works better.
       
        andix wrote 7 hours 46 min ago:
        Is there a good alternative for this that is done at build time?
        Something that works on top of SASS, Tailwind, etc?
        
        It will take some time until this feature is broadly available, and I'm
        having some doubt that it will be implemented in the same (or correct)
        way on all platforms.
       
        atum47 wrote 9 hours 27 min ago:
        I made a video tutorial about a similar thing long time ago - choosing
        black or white for text color given a color background. My solution was
        very simplistic. I just transformed the color to gray scale and
        compared it between black and white. It was a fun project. I'm not good
        making videos though. [1] (warning: video is in Portuguese)
        
   URI  [1]: https://youtu.be/tUJvE4xfTgo?si=vFlegFA_7lzijfSR
       
          coolcase wrote 8 hours 27 min ago:
          Funny a sister comment gave a color space formula to do just that [1]
          Video seems fine. I don't speak Portuguese though so can't judge what
          you said but code looks good!
          
   URI    [1]: https://news.ycombinator.com/item?id=44015990
       
            atum47 wrote 50 min ago:
            Appreciate it
       
        dp-hackernews wrote 10 hours 6 min ago:
        Surely the relative colour theory colour wheel is the answer to this
        problem.
        
        "Color Wheel: The Basic Color Theory for Artists and Designers"
        
   URI  [1]: https://dessign.net/color-wheel-theory/
       
        jbritton wrote 10 hours 16 min ago:
        At a minimum it would be nice to know good colors for the pseudo
        classes active, focus, hover, link, visited and their various
        combinations for a light and dark theme. Additionally material UI adds
        disabled, before, after.
       
        politelemon wrote 10 hours 40 min ago:
        I'm still not convinced that the contrasting colour should be the
        browser vendor's decision, it won't always be right or predictable.
        Will this be a definitive deterministic standard across all browsers?
        Instead this function feels like a tool to help UX teams during design
        phase.
       
          mcfedr wrote 8 hours 10 min ago:
          Choose is a strange word here. There is an algorithm that calculates
          the color.
       
          MBCook wrote 9 hours 47 min ago:
          > Will this be a definitive deterministic standard across all
          browsers?
          
          The article says the standard specifies the calculation to use.
       
            andix wrote 7 hours 42 min ago:
            I'm already feeling some issues with HDR displays, embedded
            devices, and other special cases. The standard Safari on macOS/iOS
            and chrome on Windows/Linux/Android are probably going to handle it
            correctly. But I'm very happy if proven wrong :)
       
          refulgentis wrote 10 hours 11 min ago:
          c.f. [1] , when you cut out the incorrect stuff due to confusion re:
          APCA's button example, it's a bit clearer that it's 100% right.
          
          Consistent, it is not. Ex. we can imagine a background at L* 50 that
          is ~equally served with a white or black foreground - in that case,
          the aesthetic principles come into play.
          
          To also disambiguate that, and get to 100% reliable, if both a darker
          and lighter color are available given contrast K and background color
          C, look at C, if it's L* is >= 60, choose lighter.
          
          Then, it is 100% correct and consistent.
          
   URI    [1]: https://news.ycombinator.com/item?id=44015980
       
        qfr wrote 10 hours 46 min ago:
        there is a way to do something close to this using lch:
        
          --text: lch(from var(--bg) calc((49.44 - l) * infinity) 0 0);
        
        source:
        
   URI  [1]: https://til.jakelazaroff.com/css/swap-between-black-and-white-...
       
          LorenzA wrote 7 hours 50 min ago:
          there is a good article from lea verou [1] on a workaround like this
          
   URI    [1]: https://lea.verou.me/blog/2024/contrast-color/
       
          natemwilson wrote 8 hours 21 min ago:
          I’ve never seen any CSS function that has this call back style
          where you get parameters that you can modify. So interesting! Are
          there any other examples of this or is this unique to lch?
       
            KTibow wrote 5 hours 3 min ago:
            Some newer ones like calc-size are also like this.
       
            halflife wrote 8 hours 14 min ago:
            It may be confusing, but everything here is static param. The —-
            prefix is css variables, where inside a css declaration block you
            write: —bg: blue
       
              natemwilson wrote 3 hours 39 min ago:
              The `l` isn't!
       
            fireflies_ wrote 8 hours 15 min ago:
            This is "relative color" syntax, it works with a range of color
            spaces/color functions. The key is the "from" at the front. Here's
            the MDN documentation:
            
   URI      [1]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_color...
       
        refulgentis wrote 10 hours 49 min ago:
        The article is wrong:
        
        - Their work does ensure contrast.
        
        - The white on blue clearly has less contrast, not more. (squinting is
        a cheap way to test, or, walking backwards from your monitor)
        
        With APCA, backgrounds around L* 60 tend to still allow white
        foregrounds, which is aesthetically closer to what the eye wants.
        
        A black foreground would have more contrast regardless, even by APCA.
        
        To be fair, this is how APCA is almost always demonstrated as a win
        over the long-running standard, so people run with the premise that the
        demo image of APCA is more contrast, rather than "ours say you'll have
        enough contrast to be accessible with a white foreground, even if it
        also says the contrast would be higher with a black foreground".
        
        (source: in 2020 built color system around the same science, enabling
        latest iterations of Material theming)
       
          refulgentis wrote 9 hours 45 min ago:
          Voters, I'd be very happy for feedback, I'm quite surprised it is -3.
          
          EDIT:
          
          I get it, it is easily read as "the entire article is wrong" instead
          of "the article is wrong on these points"
          
          You're free to elaborate on your concerns. We could raise this to a
          conversation, I think that'll feel better for both of us than me
          taking that remark about me personally.
          
          For example, I agree that the primary container color shouldn't have
          been L* 90 and used for buttons, and they shouldnt have severely
          limited chroma. In fact, I left over it and the dysfunction between
          VPs wondering why we didn't have it day 1, approving fixes
          repeatedly, and Android dysfunction that kept the conversation at
          "What? Didn't hear nothing from nobody in engineering! Anyways, lock
          screen clocks!"
       
            troupo wrote 9 hours 18 min ago:
            I didn't vote, but "your article is wrong" take ignores literally
            the entire article, and the rather detailed explanation on why
            "bigger contrast by pure numbers is more contrast" does not work.
            
            > in 2020 built color system around the same science, enabling
            latest iterations of Material theming
            
            No wonder everything Google builds, including Material, always has
            issues with contrast.
       
        mediumsmart wrote 10 hours 50 min ago:
        >But, on a large project, with a large team, carefully managing such
        details can become a really hard task to get right. Suddenly a dark
        button has unreadable black text, and users can’t figure out what to
        do.
        
        Cant someone take a look at the buttons before the large project ships?
        Alternatively make it mandatory to never have black text on a dark
        button and tell every team member including the large ones.
        
        Interesting to read about the perceptual contrast vs mathematical - I
        did not know that. Going to integrate that into my workflow.
       
          johnisgood wrote 10 hours 24 min ago:
          You may want to read about APCA, as you can have perceptual contrast
          calculations using the APCA algorithm.
       
            refulgentis wrote 10 hours 10 min ago:
            You can have them with WCAG2, the stock APCA example hides the ball
            significantly and leads to a lot of incorrect conclusions in the
            article (tl;dr: black has more contrast by either measure, its just
            that APCA says you don't need as much contrast, so you can use
            white and have sufficient contrast)
       
              mediumsmart wrote 8 hours 32 min ago:
              I thought the white looks sharper but is not really. I would
              darken the blue a bit to be happy about it.
       
              johnisgood wrote 10 hours 6 min ago:
              I know about WCAG, too. You can also just implement a function
              that detects whether or not a color is dark or not. It is a
              general purpose function, e.g. my "isDark" function is: "func() <
              0.5" (func() is omitted, but it is an algorithm). You can have
              "isLight", too, by doing "> 0.5". There are many ways to do this.
              You can just simply convert a hex color to RGB, then compute the
              luminance of the color, and then compare the luminance to a
              threshold (e.g. 0.5) to classify it as dark or light. The
              luminance function (WCAG luminance formula) converts RGB values
              to the range 0-1, applies gamma correction, and calculates
              luminance using the weighted sum of the gamma-corrected RGB
              values.
              
              > APCA says you don't need as much contrast
              
              You can always specify the threshold if you want, e.g.
              "apcaContrast(color)) >= $targetContrast" after adjusting,
              depending on what you want to do.
              
              It really is easy, just make sure you have enough color space.
       
                refulgentis wrote 9 hours 47 min ago:
                The WCAG luminance formula (relative luminance in color science
                terms) has perceptual mid gray at 0.18, not 0.5.
                
                re: just change APCA contrast target, that's separate from the
                Not Even Wrong stuff in the article. I didn't mean to imply
                APCA is wrong to say you need less contrast, but rather, that
                the article is wrong to conclude white has more contrast.
       
                  johnisgood wrote 9 hours 0 min ago:
                  Well, I used 0.5 as a convenient and intuitive midpoint of
                  the 0-1 luminance range, but this of course is a
                  simplification and doesn't align with human perception (edit:
                  it is aligned), it was more of an example if anything.
                  
                  You are right, 0.18 is indeed perceptually closer to "middle
                  gray" because the eye responds more sensitively to darker
                  tones, so yeah, using a threshold closer to 0.18 makes more
                  sense if we want to identify whether a color "feels" light or
                  dark.
                  
                  That said, 0.5 is a mathematical midpoint, but as I said, not
                  aligned with how humans perceive brightness (edit: it is
                  aligned).
                  
                  Ultimately one could use 0.18-0.3 as threshold.
       
                    anoncareer0212 wrote 7 hours 55 min ago:
                    > midpoint of the 0-1 luminance range
                    
                    There are two physical quantities for luminance, relative,
                    and perceptual, so that passed along a nugget for those not
                    as wise as you who might not know that :) As you know and
                    have mentioned, using 0.5 with the luminance calculation
                    you mentioned, for relative luminance, would be in error (I
                    hate being pedantic, but it's important for some parties,
                    a11y is a de facto legal requirement for a lot of work, and
                    0.5 would be spot on for ensuring WCAG 2 text contrast as
                    long as used with perceptual luminance, L*)
                    
                    > doesn't align with human perception
                    
                    It is 100% aligned with how humans perceive brightness, in
                    fact, it's a stable work product dating back to the early
                    1900s.
                    
                    > Ultimately one could use 0.18-0.3 as threshold
                    
                    Perceptual luminance and relative luminance have precise
                    mathematical definitions, one can be calculated in terms of
                    the other.
                    
                    If you need to hit contrast K with background color C, you
                    won't be able to treat this as variable. What you pass
                    along about it being variable is valuable, of course, in
                    that, given K and C, output has a range, i.e. if contrast
                    algo says you need +40 L* for your text to hit APCA/WCAG
                    whatever, and your C has 50 L*, your palette is everything
                    from 90 L* to 100 L* and 0 L* to 10 L*.
       
                      johnisgood wrote 7 hours 15 min ago:
                      So 0.5 is correct after all?! I thought I was completely
                      off with 0.5 and I thought it does not align with human
                      perception because I thought I was wrong. Ouch. In my
                      defense, it has been a while. :D
                      
                      BTW, would this relatively simple way to determine if the
                      color is dark work?
                      
                        $luminance = 0.299 * $r + 0.587 * $g + 0.114 * $b;
                        return $luminance < $threshold;
                      
                      Where $threshold is 128, I think? IIRC 128 is a common
                      threshold from what I remember, in this case.
       
        crtasm wrote 11 hours 17 min ago:
        >This browser does not support contrast-color(). Try this demo in a
        browser that does, like Safari Technology Preview
       
          ctippett wrote 10 hours 33 min ago:
          You don't need the Technology Preview, it's available as a WebKit
          Feature Flag under the advanced settings of normal Safari. I just
          enabled it on my phone and was able to view the demos.
       
            mgkimsal wrote 8 hours 18 min ago:
            not available on desktop safari (version 18.2 (20620.1.16.11.8))
            under feature flags.
       
              JimDabell wrote 7 hours 47 min ago:
              It’s available in desktop Safari here, I’m using version 18.5
              (20621.2.5.11.8).
              
              Safari has had several security fixes since then, so you should
              update:
              
              18.3: [1] 18.3.1: [2] 18.4: [3] 18.5: [4] Also, 18.4 was a pretty
              big update for standards support and other features:
              
   URI        [1]: https://support.apple.com/en-us/122074
   URI        [2]: https://support.apple.com/en-us/122285
   URI        [3]: https://support.apple.com/en-us/122379
   URI        [4]: https://support.apple.com/en-us/122719
   URI        [5]: https://webkit.org/blog/16574/webkit-features-in-safari-...
       
              ctippett wrote 7 hours 50 min ago:
              I'm on version 18.5 (20621.2.5.11.8) and it's there.
       
          judah wrote 10 hours 54 min ago:
          And I don't yet see an entry for this on caniuse.com. I'm guessing
          this is super new.
       
            jeroenhd wrote 6 hours 39 min ago:
            MDN doesn't even have it yet. Looks like it's WebKit exclusive for
            a while.
            
            The [draft for addition to the CSS spec]( [1] ) just got added.
            Kind of wonder why Apple includes this in Safari as color-contrast
            rather than -webkit-color-contrast until other browsers have at
            least indicated a position on this draft. All I can find is
            decisions to defer the specifications (going back to as far as
            2020).
            
   URI      [1]: https://drafts.csswg.org/css-color-5/#resolving-contrast
       
              ZYbCRq22HbJ2y7 wrote 5 hours 0 min ago:
              
              
   URI        [1]: https://drafts.csswg.org/css-color-5/#contrast-color
       
              frosted-flakes wrote 5 hours 2 min ago:
              Prefixes are no longer used for new features, and any that still
              exist are old. What happens now is that features are gated behind
              feature flags for testing until the browser working group settles
              on the final spec for that feature, at which point any
              browser-maker is free to implement it in public releases.
       
            miiiiiike wrote 10 hours 38 min ago:
            Very new. I think Safari is the only one that ships it and even
            then it’s still in preview
       
              homebrewer wrote 10 hours 36 min ago:
              It works in "Gnome Web", which is mostly a wrapper around WebKit.
              
              > Support for this feature first shipped in March 2021, in Safari
              Technology Preview 122. [1] > Added experimental support for CSS
              Color 5 color-contrast()
              
   URI        [1]: https://webkit.org/blog/11577/release-notes-for-safari-t...
   URI        [2]: https://trac.webkit.org/changeset/273683/webkit/
       
       
   DIR <- back to front page