Issues with CSS `currentColor` keyword in iOS and

2020-08-21 04:27发布

问题:

TL;DR

  1. Here's a fiddle (thank you @NicoO) : In Safari, initial "red" colour gets applied to all other instances of currentColor.
  2. How can I fix, with CSS, the inheritance issue of currentColor?
  3. Or how can I feature-detect support for the CSS colour keyword currentColor?
  4. I also need to detect partial support. For example, Apple Webkit is unstable to use in most cases.

Full Story

I am using the CSS colour keyword currentColor in a project. Using it rather profusely, I might add. For example:

I'm using it on a Site Header component that floats over a full-viewport Carousel.

Each slide has a varying background-color and a contrasting color assigned to it. When the slide changes, it updates the Site Header to inform it of the new contrast. The Site Header's color is swapped accordingly and anything with the inherit or currentColor keyword gets updated, such as an <svg>'s fill, some border-colors, and some background-colors.

Another, simpler, example:

I have various colour palettes that I apply as a class name (e.g., bg--emerald or bg--blue) onto boxes. The contents of these boxes can be links or buttons or just text. With currentColor applied to button borders, for instance, the CSS becomes quite simple because I just need to set the color property for each colour scheme. No need to update each affected child node.

All this is very slick.

Support is superb under Firefox, Chrome, Opera, Internet Explorer 9+, and their "mobile" equivalents. Unfortunately, Apple Webkit (iOS Safari and OSX Safari) is suffering from poor and erratic support. It doesn't work everywhere, nor all the time—even in the simplest of examples—nor does it repaint very well or consistently when needed.

I've done some searching and haven't found many people using this practical CSS keyword and ergo no existing means to feature-detect it or polyfill it. I don't know how I would go about making a Modernizr test for this feature. Especially to detect partial-support like I'd need for Apple Webkit.

I'm probably just going to browser-detect it at the moment until I can think of a solution or stumble upon someone with the smarts that can think of a solution faster than me.

JSFiddle

I've modified the fiddle (linked above) to grossly replicate the issues I'm having. What I've noticed is it's like currentColor gets locked with the initially inherited value ("red") and carries it along when applied to everything else. For example, if you switch :nth-child(1)'s color to something else that new value gets applied to all following elements using currentColor.

Browsers

Broken

  • OSX, Safari 6–7
  • iOS 6–7, Safari

Works

  • Windows, Safari 5
  • iOS 5, Safari

Something in Safari 6 and up got borked. Since this is such an underrated feature, nobody noticed.

回答1:

This is one of the issue I've faced recently. border-color inherit the same color as font by default so The solution is not to use currentColor at all. Try breaking down border properties. for e.g.

border : 1px solid currentColor 

to

border-width : 1px;
border-style : solid;

I've made a little fiddle for you http://jsfiddle.net/6of25jw8/



回答2:

If you are setting via js then you can make a simple hack.

You need to force safari to redraw the dom elements. You can simply hide all the elements (parent and children) and show them. this will make the children to have the intended colors set.

var nodeStack =[element];
while (node = nodeStack.pop()) {
    if (node.nodeType == 1) {
        node.style.display="none";
        node.style.display="";
        var i = node.childNodes.length;
        while (i--) {
            nodeStack.push(node.childNodes[i]);
        }
    }
}

This forces safari to redraw div so that the color will be set correctly as currentColor.

but this will not reflect in psuedo elements like :after

http://codepen.io/PrasannaRkv/pen/QyjZZg



回答3:

It seems as if it could be behaving exactly as it should be.

If the {currentColor} keyword is set on the {color} property itself, it is treated as {color:inherit}. 4.4. ‘currentColor’ color keyword

In the fiddle you attached a color to the first div tag...

div:nth-child(1){
color: red;
} 

and then it appears you attached the keyword {currentColor} to all of the division elements when you tried to add a {border} and {box-shadow}(shown below) with {currentColor} but, {border} and {box-shadow} were already assigned a color in {div:nth-child(1)} and likely initiated the default mode {color:inherit} for all properties of the division and created a change in the structure of the content block.

div {
margin: 1em;
border: 1px solid currentColor;
box-shadow: 2px 2px 1px currentColor;
padding: 10px;
} 

I would suggest not using the keyword {currentColor} with the division tag after the initial use of color in the first and second element and see how it works for you. Also, the {border} and {box-shadow} color does not need to be updated after you added the color when you created your function so I don't see why you really needed to use the keyword to accomplish your goals in this situation. Check the fiddle below and see if it fixes your issues. With a few minor changes all divisions are inheriting an individualized color set by the random function and changing at the set interval. fiddle! I would think that making a few adjustments to the usage of this keyword would eliminate the need for limited support detection.