Skip to content
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

Expose vendor prefix in future version. #233

Closed
rockinghelvetica opened this issue Apr 8, 2011 · 16 comments
Closed

Expose vendor prefix in future version. #233

rockinghelvetica opened this issue Apr 8, 2011 · 16 comments
Assignees
Milestone

Comments

@rockinghelvetica
Copy link

I love Modernizr because it allows me to do feature-based code branching. When setting CSS properties for transitions (and the like) in JS, it would be ideal if Modernizr exposed the appropriate browser prefix, since that's surely discovered in the course of its work.

@paulirish
Copy link
Member

you know...

i wasnt planning on doing this.. but that's a good idea.

a really good idea. :)

@paulirish
Copy link
Member

Modernizr._prefix // 'webkit' or 'moz' or 'o' or 'ms'  

?

EDIT: scroll down to see the revised API proposal,.

@rockinghelvetica
Copy link
Author

Ideally it would be more like "-webkit-" so that it could be concatenated like Modernizr._prefix + "transition"

My full design pattern looks something like:

if(Modernizr.csstransforms) {
CSS = {
transform: vendorPrefix + 'transform',
open: (Modernizr.csstransforms3d) ? 'translate3d(' : 'translate(',
close: 'px,0,0)',
transition: vendorPrefix + 'transition',
event: 'webkitTransitionEnd mozTransitionEnd'
};
} else {
...
}

Then in use that's something like (in Jquery):

elem.css(CSS.transform, CSS.open + value + CSS.close);

On Apr 8, 2011, at 9:39 AM, paulirish wrote:

Modernizr._prefix // 'webkit' or 'moz' or 'o' or 'ms'

?

Reply to this email directly or view it on GitHub:
#233 (comment)

@paulirish
Copy link
Member

That helps. Thanks.

@rockinghelvetica
Copy link
Author

One interesting snag with my model seems to be that setting "-ms-transform" is not accepted via JS. Seems that msTranform and "ms-transform" are, however.

On Apr 8, 2011, at 9:51 AM, paulirish wrote:

That helps. Thanks.

Reply to this email directly or view it on GitHub:
#233 (comment)

@paulirish
Copy link
Member

I think we can't just generalize this because i need a property to test this against.. and always expecting a vendor prefix isnt futureproof.

Might have to do something like....

Modernizr.prefixed('transform'); // '-webkit-transform' or false if unsupported.

@rockinghelvetica
Copy link
Author

Having just put this all to test in a real project, I found it necessary to determine & cache prefixes this way:

vendorPrefix = (function() {
  var regex = /^(Moz|Webkit|Khtml|O|ms|Icab)(?=[A-Z])/;
  var tester = document.getElementsByTagName('script')[0];
    for(var prop in tester.style) {
      if(regex.test(prop)) {
        return prop.match(regex)[0];
      }     
    }
    if('WebkitOpacity' in tester.style) return 'Webkit';
    if('KhtmlOpacity' in tester.style) return 'Khtml';
  return '';    
})();

This was from http://leaverou.me/2009/02/find-the-vendor-prefix-of-the-current-browser/ and it works efficiently as a standalone.

CSS syntax strings are only marginally useful and not reliable in Firefox or IE. Setting a css property as "-moz-transform" can fail, but MozTransform will work. Sadly, IE chooses to use a lowercase prefix, and while they do accept CSS syntax, they drop the leading hyphen. All told it's too nuanced to use. Closing the gap between storing prefixes as detected above and future-friendly end-use would be a utility method such as you propose (to pseudocode, where the prefix is cached):

Modernizr.prefixed = function(prop) {
  return  _prefix != '' && _prefix + prop.charAt(0).toUpperCase() + prop.slice(1) || prop;
};

This way, you return plain "transform" going forward, but for now you get back:

WebkitTransform
KhtmlTransform
msTransform
OTransform

Thanks for considering this feature. It would be really useful in setting CSS3 properties.

On Apr 9, 2011, at 11:20 AM, paulirish wrote:

I think we can't just generalize this because i need a property to test this against.. and always expecting a vendor prefix isnt futureproof.

Might have to do something like....

Modernizr.prefixed('transform'); // '-webkit-transform' or false if unsupported.

Reply to this email directly or view it on GitHub:
#233 (comment)

@KuraFire
Copy link
Member

I think either way we go with this, we’re excluding the other use case.

Setting a css property as "-moz-transform" can fail, but MozTransform will work.

Why is this? I don’t understand why one would fail but the other method would work. Is this a Firefox-particular bug?

I suggest that we expose the JS-oriented version (e.g. Webkit, Moz, O, ms…) since that’s always the environment in which the property will be used. If you want to use the property in a CSS composition, it’s an easy enough conversion: .toLowerCase() and surround it with hyphens. Done.

@paulirish
Copy link
Member

it probably makes sense to expose the JS version.. also this would be wise because IE breaks spec and uses msFoo instead of the more correct MsFoo

However it makes it difficult for the people who like to set a bunch of properties via elem.style.cssText = .... where you'd use the -vendor-prop notation. But yeah its a matter of this.... (this'll have to go into the docs somewhere..)

str.replace(/([A-Z])/g, function(str,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-');

Also I want to point out this post http://leaverou.me/2009/02/find-the-vendor-prefix-of-the-current-browser/ which has a different technique and is generalized. basically it looks over every prop in the style object until it finds one that has a prefix.. and returns that.

That is probably more expensive than what we do (requiring the property you're looking for.) but anyway...

@paulirish
Copy link
Member

So yeah, to summarize.. we're looking to do an API like this:

Modernizr.prefixed('transform') // 'WebkitTransform'  or 'msTransform' ... 
Modernizr.prefixed('border-radius') // 'borderRadius' or 'MozBorderRadius'
Modernizr.prefixed('transition') // false boolean in unsupporting browsers: e.g. IE6-9.

Also we'll try to cache the prefix we find during test running so we dont have to test things twice.'

Plz holler if you have a use-case that isnt satisfied by this.

@ghost ghost assigned paulirish Apr 12, 2011
@desandro
Copy link

Funky use case: transition end events

  • WebKit : webkitTransitionEnd or WebkitTransitionEnd
  • Firefox : transitionend
  • Opera : oTransitionEnd

There's also the chance that I'm using CSS properties setting a CSS property like transitionProperty

elem.style.WebkitTransitionProperty  = '-webkit-transform, opacity'

I don't think these warrant exposing which in -vendor- is functional. But I'd thought I might as well bring them up.

@KuraFire
Copy link
Member

One use case I would like for this to cater to is this:

// Set opacity-transition
$("#someElem").css(Modernizr.prefixed('transition'), "opacity .5s ease");

// Do some stuff that applies a fade by simply changing its opacity

// Remove opacity-transition
$("#someElem").css(Modernizr.prefixed('transition'), "none");

@focalstrategy
Copy link

This would be awesome. I'm currently doing this:

var vP = "";
var transitionEnd = "transitionEnd";
if ($.browser.webkit) {
    vP = "-webkit-";
    transitionEnd = "webkitTransitionEnd";
} else if ($.browser.msie) {
    vP = "-ms-";
} else if ($.browser.mozilla) {
    vP = "-moz-";
    transitionEnd = "transitionend";
} else if ($.browser.opera) {
    vP = "-o-";
    transitionEnd = "oTransitionEnd";
}

Then something like:

var cssArgs = {};
cssArgs[vP+"transform"] = "translate(100px,0px)";

animate($("#someID"),cssArgs);

Which kinda sucks.

@desandro
Copy link

@richbradshaw - Quick way for getting transition end event name might be to just set up some hashes

var transEndEventNames = {
  '-webkit-transition' : 'webkitTransitionEnd',
  '-moz-transition' : 'transitionend',
  '-o-transition' : 'oTransitionEnd',
  'transition' : 'transitionEnd'
},

transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];

paulirish added a commit that referenced this issue May 22, 2011
@paulirish
Copy link
Member

It's in. :)

@austegard
Copy link

Nice! we were just discussing the need for it, and you fixed it already. Thanks.

patrickkettner pushed a commit to patrickkettner/Modernizr that referenced this issue Feb 22, 2015
…e variant of your input

Modernizr.prefixed('boxSizing') // 'MozBoxSizing'

fixes Modernizr#233

Properties must be passed as dom-style camelcase, rather than `box-sizing` hypentated style.

Return values will also be the camelCase variant, if you need to translate that to hypenated style use:

    str.replace(/([A-Z])/g, function(str,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-');
patrickkettner pushed a commit to patrickkettner/Modernizr that referenced this issue Feb 22, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants