Next revision | Previous revisionNext revisionBoth sides next revision |
ideas:feature-testing [2010/05/07 15:43] – created tabatkins | ideas:feature-testing [2014/12/09 15:48] – external edit 127.0.0.1 |
---|
| ====== Feature Testing: ====== |
| |
| |
As we produce more advanced CSS properties, the possibility of creating something that is unusable in the absence of that property increases. For example: | As we produce more advanced CSS properties, the possibility of creating something that is unusable in the absence of that property increases. For example: |
* the new layout modes (template, flexbox) may significantly screw up a page in a UA that supports CSS but not that specific layout mode | * the new layout modes (template, flexbox) may significantly screw up a page in a UA that supports CSS but not that specific layout mode |
This is not going to be bulletproof. It's impossible to be so. But it can be at least as capable as capability-testing in javascript, and if done well can at least somewhat discourage using this for hacky UA-detection. | This is not going to be bulletproof. It's impossible to be so. But it can be at least as capable as capability-testing in javascript, and if done well can at least somewhat discourage using this for hacky UA-detection. |
| |
Suggestion: use the !required syntax, to allow the "ignore if you don't support" ability of CSS to spread to more than just the single invalid line. | ===== Suggestion: ===== |
| |
| use the !required syntax, to allow the "ignore if you don't support" ability of CSS to spread to more than just the single invalid line. |
| |
When used in a normal declaration block, if the property that !required is used on is not supported, the entire declaration block will be ignored. Multiple !required properties must all be supported; if any are not, the entire block is ignored. | When used in a normal declaration block, if the property that !required is used on is not supported, the entire declaration block will be ignored. Multiple !required properties must all be supported; if any are not, the entire block is ignored. |
As well, a new @supports{} @-rule is introduced. Within this, all !required rules in all declaration blocks must be supported, or else the entire @supports block will be ignored. | As well, a new @supports{} @-rule is introduced. Within this, all !required rules in all declaration blocks must be supported, or else the entire @supports block will be ignored. |
| |
Examples: | ===== Examples: ===== |
| |
h2 { | |
background: white; | h2 { |
color: black; | background: white; |
} | color: black; |
h2 { | } |
background: white; | h2 { |
color: white; | background: white; |
text-shadow: 0 0 2px black !required; | color: white; |
} | text-shadow: 0 0 2px black !required; |
| } |
| |
If text-shadow is supported, color is set to white and the text-shadow keeps it legible. If not, the entire second block is ignored, and color is set to black. | If text-shadow is supported, color is set to white and the text-shadow keeps it legible. If not, the entire second block is ignored, and color is set to black. |
| |
| |
body { position: relative; width: 800px; } | body { position: relative; width: 800px; } |
#header { position: absolute; left: 0; right: 0; top: 0; height: 150px;} | #header { position: absolute; left: 0; right: 0; top: 0; height: 150px;} |
#sidebar { position: absolute; left: 0; top: 150px; width: 200px;} | #sidebar { position: absolute; left: 0; top: 150px; width: 200px;} |
#content { position: absolute; left: 200px; right: 0;top: 150px; } | #content { position: absolute; left: 200px; right: 0;top: 150px; } |
@supports { | @supports { |
body { | body { |
display: "aa" /150px | display: "aa" /150px |
"bc" /auto | "bc" /auto |
200px auto !required; | 200px auto !required; |
| } |
| #header { position: a; height: auto;} |
| #sidebar { position: b; width: auto;} |
| #content { position: c; } |
} | } |
#header { position: a; height: auto;} | |
#sidebar { position: b; width: auto;} | |
#content { position: c; } | |
} | |
| |
In this example, if a browser supports Template Layout, the later `position` values override the previous values of "absolute" (and the left/top/right values are thus ignored), and the page is laid out according to the Template Layout spec. If the browser doesn't support Template Layout, though, then the entire @supports block is ignored, and the previous absolute positioning takes effect instead. | In this example, if a browser supports Template Layout, the later `position` values override the previous values of "absolute" (and the left/top/right values are thus ignored), and the page is laid out according to the Template Layout spec. If the browser doesn't support Template Layout, though, then the entire @supports block is ignored, and the previous absolute positioning takes effect instead. |
| |
| ===== Consequences: ===== |
| |
| |
This sort of feature testing is as close to ideal as I think we can get something in this space. The feature that you're testing for is directly annotated, making it obvious what's required. The tested-for value must actually be used, which limits the ability to UA-detect in dangerous ways (in practice, some values can indeed still be used for this as they have irrelevant or inconsequential effects in the context you're using them in). | This sort of feature testing is as close to ideal as I think we can get something in this space. The feature that you're testing for is directly annotated, making it obvious what's required. The tested-for value must actually be used, which limits the ability to UA-detect in dangerous ways (in practice, some values can indeed still be used for this as they have irrelevant or inconsequential effects in the context you're using them in). |
| |
The user can, of course, trivially UA-detect by tying !required to a prefixed property. We really can't prevent this without gutting a substantial amount of power from the proposal (if I can't detect that -webkit-text-shadow is supported, I still can't use it in a way that would fail badly if it's not supported). However, we can at least be certain that UA-detection based on prefixes will be *correct*. You'll never see a webkit-based browser claim to support a -moz-* property or value. Thus the damage is actually relatively limited, and better than the current situation where UA-detection hacks in CSS can accidentally spread to other browsers when they start to support new properties. | The user can, of course, trivially UA-detect by tying !required to a prefixed property. We really can't prevent this without gutting a substantial amount of power from the proposal (if I can't detect that -webkit-text-shadow is supported, I still can't use it in a way that would fail badly if it's not supported). However, we can at least be certain that UA-detection based on prefixes will be *correct*. You'll never see a webkit-based browser claim to support a -moz-* property or value. Thus the damage is actually relatively limited, and better than the current situation where UA-detection hacks in CSS can accidentally spread to other browsers when they start to support new properties. |