TextMate CSS Vendor Prefix Helper Bundle

(More or less experimental, so far)

For CSS authors, it’s quite a hassle to write those nasty vendor prefixes, although you probably need less prefixes than you might think. So I wrote a bundle for TextMate (a great text editor for Mac OS X) which helps you to spare some typing as well and to avoid unnecessary vendor prefixes.

The story behind

(If just want to know how to work with this bundle and you’re not interested in learning why I wrote it, just proceed to the Usage section.)

Since I started working a lot with CSS3 animations I had to learn that the vendor prefixes still aren’t superfluous. At time of writing, even current versions of Safari und Chrome need the -webkit prefix for animation-name, animation-duration etc. The prefix for transitions were dropped in Safari 6.1 and Chrome 26 and since I like to write backwards compatible code it’s still too early for me to ditch them.

So, I was looking for a way to avoid entering the prefixes each time and moreover, to be able to stop even thinking about which prefix is needed for which property and which browser. I tried the server-sided solution CSSfix class, but it screw up on some @keyframe blocks and it puts the non-prefixed line at the beginning of the cascade. Since it is written in PHP I could have looked into the code trying to fix this, but I thought it wasn’t worth the effort: Since the CSS file would be processed by the PHP interpreter each time it is called, it would never be cached by the users’ browser. And of course, when you use the Style Inspector that modern browsers offer to fix CSS related problems, they never give you the right line number in your (unprocessed) CSS file.

I tried the client-sided -prefix-free JavaScript solution but it produced FOUC rather quickly (i.e. even when the processed CSS wasn’t that large).

For some time, I worked with Jack Brewer’s Vendor Prefix Bundle for TextMate, which came close to what I wanted – unfortunately, it adds the vendor prefixes no matter if they are needed or not, and it doesn’t handle @keyframe blocks at all. Nonetheless it was a great help on various projects, so in case Jack is reading this: Thanks a lot!
And if you feel that you know when to set the vendor prefixes and only want to spare some typing, I recommend Jack’s bundle.

I thought that it might be useful to combine CSSfix’s approach of providing a list of the vendor prefixes you need with Jack’s approach to handle it in TextMate. And so, I wrote the Vendor Prefix Helper bundle.

Usage

For single lines, I just copied the behavior of Jack Brewer’s bundle.
Type the properties without any prefixes, e.g.:

transition: all 1.5s ease;

At the end of your line, add a ‘-‘ followed by TAB:

transition: all 1.5s ease;-

This will result in:

-webkit-transition: all 1.5s ease;
   -moz-transition: all 1.5s ease;
    -ms-transition: all 1.5s ease;
     -o-transition: all 1.5s ease;
        transition: all 1.5s ease;

The bundle also works with multi-line selections. If you’ve got this:

animation-name: myAnimation;
animation-timing-function: ease;
animation-iteration-count: 1;
animation-duration: 1.5s;

Select all the above lines and then press SHIFT + COMMAND + - (that’s the minus char, preferably typed from the numeric keypad) and you’ll get:

-webkit-animation-name: myAnimation;
   -moz-animation-name: myAnimation;
    -ms-animation-name: myAnimation;
     -o-animation-name: myAnimation;
        animation-name: myAnimation;
-webkit-animation-timing-function: ease;
   -moz-animation-timing-function: ease;
    -ms-animation-timing-function: ease;
     -o-animation-timing-function: ease;
        animation-timing-function: ease;
-webkit-animation-iteration-count: 1;
   -moz-animation-iteration-count: 1;
    -ms-animation-iteration-count: 1;
     -o-animation-iteration-count: 1;
        animation-iteration-count: 1;
-webkit-animation-duration: 1.5s;
   -moz-animation-duration: 1.5s;
    -ms-animation-duration: 1.5s;
     -o-animation-duration: 1.5s;
        animation-duration: 1.5s;

You see that we’re using a named animation here.
The bundle also supports the corresponding @keyframe blocks. Select the full block starting at @keyframe and ending at the closing }:

@keyframes myAnimation {
    from {
        transform: translate(300%, -500%);
    } to {
        transform: translate(0, 0);
    }
}

Then press SHIFT + COMMAND + K and you’ll get:

@-webkit-keyframes myAnimation {
    from {
        -webkit-transform: translate(300%, -500%);
                transform: translate(300%, -500%);
    } to {
        -webkit-transform: translate(0, 0);
                transform: translate(0, 0);
    }
}
@-moz-keyframes myAnimation {
    from {
        -moz-transform: translate(300%, -500%);
             transform: translate(300%, -500%);
    } to {
        -moz-transform: translate(0, 0);
             transform: translate(0, 0);
    }
}
@-ms-keyframes myAnimation {
    from {
        -ms-transform: translate(300%, -500%);
            transform: translate(300%, -500%);
    } to {
        -ms-transform: translate(0, 0);
            transform: translate(0, 0);
    }
}
@-o-keyframes myAnimation {
    from {
        -o-transform: translate(300%, -500%);
           transform: translate(300%, -500%);
    } to {
        -o-transform: translate(0, 0);
           transform: translate(0, 0);
    }
}

If you use the bundle on properties that don’t need any vendor prefix, none will be added. Moreover, when prefixes are needed, it will only add those that are needed for the specific property, e.g. if you use it here:

box-sizing: border-box;

it will result in:

-moz-box-sizing: border-box;
     box-sizing: border-box;

… because the -webkit-, -ms- and -o- prefixes were never needed here (while the -moz- prefix is needed in Firefox up to version 28).

And if you ever worked with CSS flexboxes, you know that there, you don’t have to prefix the display property but the value. The bundle will do that for you, too.
Example:

display: flex;

will be rewritten to:

display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;

I strongly suggest that you use the bundle on single lines (with tab trigger) or on selected blocks containing the lines you need to change ONLY!
On some occasions, it’ll work correctly when you select a full CSS file and then call the bundle. But mostly this will screw up your code!

How does it work?

The bundle is written in PHP, so if you want to use it, you’ll need a running PHP installation. Fortunately, Mac OS X has PHP build in so it should run out of the box.

The bundle has a list included to tell which prefixes are needed for which properties. It looks like this (and even if you don’t know PHP, I guess you’ll understand):

$properties = array(
    'animation' => array('webkit', 'moz', 'ms', 'o'),
    'animation-timing-function' => array('webkit', 'moz', 'ms', 'o'),
    (...)
    'background-clip' => array('webkit', 'moz'),
    'background-origin' => array('webkit', 'moz'),
    (...)
);

You might want to mention that -moz-background-clip was last needed in Firefox 3.6 – and you’d be right! The list was compiled to guarantee full backwards compatibility. If you think that’s too much, feel free to customize the list to you liking. ;-)

I’ve written this bundle for TextMate 2, but it needed only a few adjustments to run with TextMate 1.x as well. So I’m offering two versions – I don’t know if there’s a way to make it run in both versions without any adjustments.

Shortcomings

The bundle sure isn’t perfect yet.
The bundle only works when the line(s) you want to process end with a semicolon. If you’ve got a comment behind the semicolon (or even a few space chars), it’ll do nothing.
On some occasions, the code might not be formatted the way it should be (i.e. the bundle screws up with indenting). More importantly, I’m not sure if it covers all the flexbox properties and values correctly (they have be changed two times so I got kinda confused). It won’t translate the opacity property to IE-style filter properties. And currently it doesn’t support neither the gradient nor the calc value at all.
I’m trying to remove these shortcoming as time goes by but I won’t promise anything.

The property list which, after all, is the linchpin of the bundle, might still contain a few glitches and expendabilities. I originally took it from the CSSfix class mentioned above and applied a few changes but at some point I was fed up with doing the research.

And as I’ve said before, it tries to support outdated browsers such as Firefox 3.6 and Safari 4.
Maybe someday I’ll provide a list which drops the prefixes for such old pieces of software…

Download

So, here’s the bundle. The gzip archive contains both the bundle itself as well as this text.
Download Vendor Prefix Helper Bundle for TextMate 2
Download Vendor Prefix Helper Bundle for TextMate 1.x

Why don’t you put it to GitHub where along with all the other TextMate bundles?

I might do it some day. When I think it’s better (see above).

License

Permission to copy, use, modify, sell and distribute this
software is granted. This software is provided “as is” without
express or implied warranty, and with no claim as to its
suitability for any purpose.

Contact

For comments, suggestions etc. leave a reply here or write to the email address given on the imprint page.

If you’d like to improve the bundle or rewrite it to a different language, feel free to do it, but please let me know.

Share on Facebook