New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot use prefix-specific overrides when using prefixfree #16

Open
KrofDrakula opened this Issue Oct 17, 2011 · 16 comments

Comments

Projects
None yet
6 participants
@KrofDrakula

KrofDrakula commented Oct 17, 2011

This is really more of an issue of how to correctly handle vendor-specific rendering problems, but I'm logging this issue so you're aware of this effect.

When using different vendor-spefic selectors, I can easily specify CSS attributes for different rendering engines:

-webkit-transform: rotate(15deg) rotateX(0); /* Force Chrome to render as 3D, enabling antialias */
-moz-transform: rotate(15deg);
-ms-transform: rotate(15deg);
-o-transform: rotate(15deg);
transform: rotate(15deg);

Using prefixfree, however, writing something like this:

-webkit-transform: rotate(15deg) rotateX(0);
transform: rotate(15deg);

...turns the resulting CSS on Chrome into:

-webkit-transform: rotate(15deg) rotateX(0);
-webkit-transform: rotate(15deg);

This negates the vendor-specific attribute spec and reverts it back to a non-antialiased view.

Now, I know that this could be solved by simply applying a Modernizr-like class name for specific browsers (and platforms, like IE), but the alternative would be to assign vendor-specific attributes a higher priority than unprefix ones, eg. if the rule exists prefixed in addition to the unprefixed one in source, do not transform the unprefixed one. This enables the override which would fix this issue.

Again, not sure if this is something that should be handled by prefixfree or not, just putting it out there.

@LeaVerou

This comment has been minimized.

Show comment
Hide comment
@LeaVerou

LeaVerou Oct 17, 2011

Owner

I've been thinking about this issue for a while, trying to come up with different solutions.

The one I had come up was to use comments like /* don't expand */ to not prefix anything in a declaration or /* expand */ to substitute a prefixed one with the current prefix.

I hadn't thought of the classes idea. That could be useful, although it would force you to use a separate rule, which I don't like, and it might encourage browser-specific CSS.

Owner

LeaVerou commented Oct 17, 2011

I've been thinking about this issue for a while, trying to come up with different solutions.

The one I had come up was to use comments like /* don't expand */ to not prefix anything in a declaration or /* expand */ to substitute a prefixed one with the current prefix.

I hadn't thought of the classes idea. That could be useful, although it would force you to use a separate rule, which I don't like, and it might encourage browser-specific CSS.

@KrofDrakula

This comment has been minimized.

Show comment
Hide comment
@KrofDrakula

KrofDrakula Oct 17, 2011

Well the issue here is that this case is a version-specific fix, so I'm not sure if it's the domain of prefixfree to fix it.

One possible solution would be to not expand the universal attribute if there's a vendor-specific attribute available for the currently running browser (eg. webkit will not expand the above example, while others will).

KrofDrakula commented Oct 17, 2011

Well the issue here is that this case is a version-specific fix, so I'm not sure if it's the domain of prefixfree to fix it.

One possible solution would be to not expand the universal attribute if there's a vendor-specific attribute available for the currently running browser (eg. webkit will not expand the above example, while others will).

@LeaVerou

This comment has been minimized.

Show comment
Hide comment
@LeaVerou

LeaVerou Oct 17, 2011

Owner

Yes, that would be ideal. But it would introduce too much complexity in the algorithm that makes the substitutions so I'm trying to avoid it. I don't want to end up having to code a full CSS parser, that would be quite slow and would substantially increase the filesize.

Owner

LeaVerou commented Oct 17, 2011

Yes, that would be ideal. But it would introduce too much complexity in the algorithm that makes the substitutions so I'm trying to avoid it. I don't want to end up having to code a full CSS parser, that would be quite slow and would substantially increase the filesize.

@KrofDrakula

This comment has been minimized.

Show comment
Hide comment
@KrofDrakula

KrofDrakula Oct 17, 2011

For sure. Just close the issue if you think it's outside the scope of the current (or future) implementation, I'm just putting it out there in case someone else stumbles onto this issue.

KrofDrakula commented Oct 17, 2011

For sure. Just close the issue if you think it's outside the scope of the current (or future) implementation, I'm just putting it out there in case someone else stumbles onto this issue.

@LeaVerou

This comment has been minimized.

Show comment
Hide comment
@LeaVerou

LeaVerou Oct 17, 2011

Owner

I'm not closing it, cause I really want to come up with a solution for it. Just not sure which one.

Owner

LeaVerou commented Oct 17, 2011

I'm not closing it, cause I really want to come up with a solution for it. Just not sure which one.

@LeaVerou

This comment has been minimized.

Show comment
Hide comment
@LeaVerou

LeaVerou Oct 17, 2011

Owner

I added the classes functionality you suggested in this commit:

55fa4ce

but I'm still not closing it, as that doesn't solve all issues. For example, gradients will have different syntax once they become unprefixed and this won't solve that problem.

Owner

LeaVerou commented Oct 17, 2011

I added the classes functionality you suggested in this commit:

55fa4ce

but I'm still not closing it, as that doesn't solve all issues. For example, gradients will have different syntax once they become unprefixed and this won't solve that problem.

@paulwalker

This comment has been minimized.

Show comment
Hide comment
@paulwalker

paulwalker Oct 21, 2011

Why not just reverse the order of the selectors? eg:

transform: rotate(15deg);
-webkit-transform: rotate(15deg) rotateX(0);

paulwalker commented Oct 21, 2011

Why not just reverse the order of the selectors? eg:

transform: rotate(15deg);
-webkit-transform: rotate(15deg) rotateX(0);
@LeaVerou

This comment has been minimized.

Show comment
Hide comment
@LeaVerou

LeaVerou Oct 21, 2011

Owner

Yes, that's what I currently suggest people to do. But I don't like it much, as it's not future proof in most cases.

Owner

LeaVerou commented Oct 21, 2011

Yes, that's what I currently suggest people to do. But I don't like it much, as it's not future proof in most cases.

@yuchi

This comment has been minimized.

Show comment
Hide comment
@yuchi

yuchi Oct 25, 2011

Actually using prefixed properties to bring specific css to specific browser, is actually the wrong path. If you want to apply a different transform on browsers which support transition (for example) then you should check for transition (Modernizr) and then change the transform.

yuchi commented Oct 25, 2011

Actually using prefixed properties to bring specific css to specific browser, is actually the wrong path. If you want to apply a different transform on browsers which support transition (for example) then you should check for transition (Modernizr) and then change the transform.

@KrofDrakula

This comment has been minimized.

Show comment
Hide comment
@KrofDrakula

KrofDrakula Oct 25, 2011

@yuchi: That doesn't solve the problem at all; Chrome 14 cannot be differentiated in this manner. The specific case here being that that browser is the only one needing the additional forced 3D transform, but its capabilities match a wide variety of different browsers.

I've been thinking more about this issue – maybe I should just stick with a single transform including 3D which would render this issue moot for all browsers. Granted, all browsers would then force 3D rendering, but at least it would be consistent.

KrofDrakula commented Oct 25, 2011

@yuchi: That doesn't solve the problem at all; Chrome 14 cannot be differentiated in this manner. The specific case here being that that browser is the only one needing the additional forced 3D transform, but its capabilities match a wide variety of different browsers.

I've been thinking more about this issue – maybe I should just stick with a single transform including 3D which would render this issue moot for all browsers. Granted, all browsers would then force 3D rendering, but at least it would be consistent.

@yuchi

This comment has been minimized.

Show comment
Hide comment
@yuchi

yuchi Oct 25, 2011

Do you mean that -webkit-transform: rotate(15deg) rotateX(0); it's an hack over Chrome 14?

yuchi commented Oct 25, 2011

Do you mean that -webkit-transform: rotate(15deg) rotateX(0); it's an hack over Chrome 14?

@KrofDrakula

This comment has been minimized.

Show comment
Hide comment
@KrofDrakula

KrofDrakula Oct 25, 2011

It's a hack for Chrome 14 (jagged edges when rotating in 2D), but affects all webkits, yes. So far, I've been using this with positive outcomes, though it's a tradeoff between simplicity, convenience and targeting specificity.

If anyone has a better way of targeting (preferably not relying on browser sniffing), I'd love to hear it.

KrofDrakula commented Oct 25, 2011

It's a hack for Chrome 14 (jagged edges when rotating in 2D), but affects all webkits, yes. So far, I've been using this with positive outcomes, though it's a tradeoff between simplicity, convenience and targeting specificity.

If anyone has a better way of targeting (preferably not relying on browser sniffing), I'd love to hear it.

@oli

This comment has been minimized.

Show comment
Hide comment
@oli

oli Jan 6, 2012

Specific for this example, but as the 3D transform doesn’t do anything and is only for WebKit, you could apply it to a nested element with a -webkit- prefix preventing -prefix-free from expanding it. Even an empty child span with a 3D transform will cause the parent text block to get the stronger anti-aliasing.

http://dabblet.com/gist/1569637

Update:
I found the bug: http://code.google.com/p/chromium/issues/detail?id=96769
Also, adding a background-color turns sub-pixel anti-aliasing back on in Chrome 16, but not in Canary
http://dropshado.ws/post/6142339613/resolving-anti-aliasing-on-webkit-hardware-accelerated

oli commented Jan 6, 2012

Specific for this example, but as the 3D transform doesn’t do anything and is only for WebKit, you could apply it to a nested element with a -webkit- prefix preventing -prefix-free from expanding it. Even an empty child span with a 3D transform will cause the parent text block to get the stronger anti-aliasing.

http://dabblet.com/gist/1569637

Update:
I found the bug: http://code.google.com/p/chromium/issues/detail?id=96769
Also, adding a background-color turns sub-pixel anti-aliasing back on in Chrome 16, but not in Canary
http://dropshado.ws/post/6142339613/resolving-anti-aliasing-on-webkit-hardware-accelerated

@KrofDrakula

This comment has been minimized.

Show comment
Hide comment
@KrofDrakula

KrofDrakula Jan 6, 2012

Yikes. Just read the chromium issue thread. Thanks for those pointers!

KrofDrakula commented Jan 6, 2012

Yikes. Just read the chromium issue thread. Thanks for those pointers!

@le717

This comment has been minimized.

Show comment
Hide comment
@le717

le717 Jan 27, 2014

@LeaVerou I was lead here after discovering -prefix-free (which is a great library. I'm using it myself on my site. 👍) and learning of this limitation.

Perhaps I can provide a fresh take on fixing this bug. From read the conversation, it does not appear to be mentioned but it might have been privately considered already.

To heavily simplify here, -prefix-free currently:

  1. Gets the browser's vendor prefix
  2. Reads your stylesheet
  3. Checks if a property needs prefixing
  4. If so, appends the prefix.

The error being reported here is if a non-prefixed property is used after an already prefixed property. In this case, the second property is prefixed and the rule is invalid.

Again, this may sound simple or absurd, but I figured it was worth a shot to report.

The fix would look something like this:

  1. Gets the browser's vendor prefix
  2. Reads your stylesheet, storing all the properties in some form of array
  3. Checks if a property needs prefixing
  4. If so, check the array for an already prefixed version.
  5. If an already prefixed version is present (to reuse @KrofDrakula's example, -webkit-transform: rotate(15deg) rotateX(0);), do not prefix and move on to next property.
  6. Otherwise, append the prefix.

The only real drawback here is the array. If the stylesheet is massive, then the array will be massive as well, thus going through it and checking if a prefix is needed would slow the script down by a currently unknown amount. The if checking may also slow things down a bit, but I imagine not near as much as the array.

So yea, that's help. I don't know if this will help any, but I figure I would share this.

le717 commented Jan 27, 2014

@LeaVerou I was lead here after discovering -prefix-free (which is a great library. I'm using it myself on my site. 👍) and learning of this limitation.

Perhaps I can provide a fresh take on fixing this bug. From read the conversation, it does not appear to be mentioned but it might have been privately considered already.

To heavily simplify here, -prefix-free currently:

  1. Gets the browser's vendor prefix
  2. Reads your stylesheet
  3. Checks if a property needs prefixing
  4. If so, appends the prefix.

The error being reported here is if a non-prefixed property is used after an already prefixed property. In this case, the second property is prefixed and the rule is invalid.

Again, this may sound simple or absurd, but I figured it was worth a shot to report.

The fix would look something like this:

  1. Gets the browser's vendor prefix
  2. Reads your stylesheet, storing all the properties in some form of array
  3. Checks if a property needs prefixing
  4. If so, check the array for an already prefixed version.
  5. If an already prefixed version is present (to reuse @KrofDrakula's example, -webkit-transform: rotate(15deg) rotateX(0);), do not prefix and move on to next property.
  6. Otherwise, append the prefix.

The only real drawback here is the array. If the stylesheet is massive, then the array will be massive as well, thus going through it and checking if a prefix is needed would slow the script down by a currently unknown amount. The if checking may also slow things down a bit, but I imagine not near as much as the array.

So yea, that's help. I don't know if this will help any, but I figure I would share this.

@LeaVerou

This comment has been minimized.

Show comment
Hide comment
@LeaVerou

LeaVerou Jan 28, 2014

Owner

No, the drawback is that PF does not parse the stylesheet, so there is no array figured out.

Owner

LeaVerou commented Jan 28, 2014

No, the drawback is that PF does not parse the stylesheet, so there is no array figured out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment