Categories
News

Important -prefix-free update

Reading Time: 3 minutes

Those of you that have been following and/or using my work, are surely familiar with -prefix-free. Its promise was to let you write DRY code, without all the messy prefixes, that would be standards-compliant in the future (which is why I’m always against adding proprietary features in it, regardless of their popularity). The way -prefix-free works is that it feature tests which CSS features are available only with a prefix, and then adds the prefix in front of their occurences in the code. Nothing will happen if the feature is supported both with and without a prefix or if it’s not supported at all.

This worked well when browsers implementations aren’t significantly different from the unprefixed, standard version. It also works fine when the newer and the older version use incompatible syntaxes. For example, direction keywords in gradients. The old version uses top whereas the new version uses to bottom. If you include both versions, the cascade does its job and ignores the latter version if it’s not supported:

background: linear-gradient(top, white, black);
background: linear-gradient(to bottom, white, black);

However, when the same syntax means different things in the older and the newer version, things can go horribly wrong. Thankfully, this case is quite rare. A prime example of this is linear gradient angles. 0deg means a horizontal (left to right) gradient in prefixed linear-gradients and a vertical (bottom to top) gradient in unprefixed implementations, since they follow the newer Candidate Recommendation rather than the old draft. This wasn’t a problem when every browser supported only prefixed gradients. However, now that IE10 and Firefox 16 are unprefixing their gradients implementations, it was time for me to face the issue I was avoiding ever since I wrote -prefix-free.

The solution I decided on is consistent with -prefix-free’s original promise of allowing you to write mostly standards-compliant code that will not even need -prefix-free in the future. Therefore, it will assume that your gradients use the newer syntax, and if only a prefixed implementation is available, it will convert the angles to the legacy definition. This means that if you update -prefix-free on a page that includes gradients coded with the older definition, they might break. However, they would break anyway in modern browsers, so the sooner the better. Even if you weren’t using -prefix-free at all, and had written all the declarations by hand before the angles changed, you would still have to update your code. Unfortunately, that’s the risk we all take when using experimental features like CSS gradients and I think it’s worth it.

-prefix-free will not take care of any other syntax changes, since when the syntaxes are incompatible, you can easily include both declarations. The angles hotfix was included out of necessity because there is no other way to deal with it.

Here’s a handy JS function that converts older angles to newer ones:

function fromLegacy(deg) { return Math.abs(deg-450) % 360 }

You can read more about the changes in gradient syntax in this excellent IEblog article.

In addition to this change, a new feature was added to -prefix-free. If you ONLY want to use the prefixed version of a feature, but still don’t want to write out of all the prefixes, you can just use -*- as a prefix placeholder and it will be replaced with the current browser’s prefix on runtime. So, if you don’t want to change your angles, you can just prepend -*- to your linear-gradients, like so:

background: -*-linear-gradient(0deg, white, black);

However, it’s a much more futureproof and standards compatible solution to just update your angles to the new definition. You know you’ll have to do it at some point anyway. 😉

Edit: Although -prefix-free doesn’t handle syntax changes in radial gradients, since the syntaxes are mutually incompatible, you may use this little PrefixFree plugin I wrote for the CSS Patterns Gallery, which converts the standard syntax to legacy syntax when needed:

StyleFix.register(function(css, raw) {
	if (PrefixFree.functions.indexOf('radial-gradient') > -1) {
		css = css.replace(/radial-gradient\(([a-z-\s]+\s+)?at ([^,]+)(?=,)/g, function($0, shape, center){
			return 'radial-gradient(' + center + (shape? ', ' + shape : '');
		});
	}

	return css;
});

Keep in mind however that it’s very crude and not very well tested.

Categories
Personal Speaking

So, you’ve been invited to speak

Reading Time: 8 minutes

I’ve been lucky enough to be invited to do about 25 talks over the course of the past few years and I have quite a few upcoming gigs as well, most of them at international conferences around Europe and the US. Despite my speaking experience, I’m still very reluctant to call myself a “professional speaker” or even a “speaker” at all. In case you follow me on twitter, you might have noticed that my bio says “Often pretends to be a speaker”, and that captures exactly how I feel. I’m not one of those confident performers that don’t just present interesting stuff, but also can blurt jokes one after the other, almost like stand-up comedians and never backtrack or go “ummm”. I greatly admire these people and I aspire to become as confident as them on stage one day. People like Aral Balkan, Christian Heilmann, Nicole Sullivan, Jake Archibald and many others. Unlike them, I often backtrack mid-sentence, say a lot of “ummmm”s and sometimes talk about stuff that was going to be later in my slides, all of which are very awkward.

However, I’ve reached the conclusion that I must be doing something right. I do get a lot of overwhelmingly positive feedback after almost every talk, even by people I admire in the industry. I don’t think I’ve ever gotten a negative comment for a talk, even in cases that I thought I had screwed up. Naturally, after all these conferences, I’ve attended a lot of technical talks myself, and I’ve gathered some insight on what constitutes a technical talk the audience will enjoy. I’ve been pondering to write a post with advice about this for a long time, but my lack of confidence about my speaking abilities put me off the task. However, since people seem to consider me good, I figured it might help others doing technical talks as well.

All of the following are rules of thumb. You have to keep in mind that there are exceptions to every single one, but it’s often quicker and more interesting to talk in absolutes. I will try to stay away from what’s already been said in other similar articles, such as “tell a story” or “be funny” etc, not because it’s bad advice, but because a) I’m not really good at those so I prefer to let others discuss them and b) I don’t like repeating stuff that’s already been said numerous times before. I will try to focus on what I do differently, and why I think it works. It might not fit your style and that’s ok. Audiences like a wide range of presentation styles, otherwise I’d be screwed, as I don’t fit the traditional “good speaker” profile. Also, it goes without saying that some of my advice might be flat out wrong. I’m just trying to do pattern recognition to figure out why people like my talks. That’s bound to be error-prone. My talks might be succeeding in spite of X and not because of it.

Categories
Personal

Why I bought a high-end MacBook Air instead of the Retina MBP

Reading Time: 4 minutes

After the WWDC keynote, I was convinced I would buy a new MacBook Air. I was looking forward to any announcements about new hardware during the event, as my 13″ 2010 MacBook Pro (Henceforth abbreviated as MBP) was becoming increasingly slow and dated. Also, I wanted to gift my MBP to my mother, who is currently using a horrible tiny Windows XP Netbook and every time I see her struggling to work on it, my insides hurt. All tweets about my shopping plans, or, later, about my new toy (I bought it yesterday) were met with surprise and bewilderment: I was repeatedly bombarded with questions asking why I’m not getting a Retina MacBook Pro, over and over again. The fact that I paid about $2200 + tax for it (it’s the best 13″ Air you can currently get) made it even more weird: If you could afford that, why wouldn’t you possibly get the Retina MBP at the exact same price?

At first, I tried to reply with individual tweets to everyone that asked. Then I got tired of that and started replying with links to the first tweets, then I decided to write a blog post. So, here are my reasons:

Categories
Tips

Hacking lookahead to mimic intersection, subtraction and negation

Reading Time: 2 minutes

Note: To understand the following, I expect you to know how regex lookahead works. If you don’t, read about it first and return here after you’re done.

I was quite excited to discover this, but to my dismay, Steven Levithan assured me it’s actually well known. However, I felt it’s so useful and underdocumented (the only references to the technique I could find was several StackOverflow replies) that I decided to blog about it anyway.

If you’ve been using regular expressions for a while, you surely have stumbled on a variation of the following problems:

  • Intersection: “I want to match something that matches pattern A AND pattern B”
    Example: A password of at least 6 characters that contains at least one digit, at least one letter and at least one symbol
  • Subtraction: “I want to match something that matches pattern A but NOT pattern B”
    Example: Match any integer that is not divisible by 50
  • Negation: “I want to match anything that does NOT match pattern A”
    Example: Match anything that does NOT contain the string “foo”

Even though in ECMAScript we can use the caret (^) to negate a character class, we cannot negate anything else. Furthermore, even though we have the pipe character to mean OR, we have nothing that means AND. And of course, we have nothing that means “except” (subtraction). All these are fairly easy to do for single characters, through character classes, but not for entire sequences.

However, we can mimic all three operations by taking advantage of the fact that lookahead is zero length and therefore does not advance the matching position. We can just keep on matching to our heart’s content after it, and it will be matched against the same substring, since the lookahead itself consumed no characters. For a simple example, the regex /^(?!cat)\w{3}$/ will match any 3 letter word that is NOT “cat”. This was a very simple example of subtraction. Similarly, the solution to the subtraction problem above would look like /^(?!\d+[50]0)\d+$/.

For intersection (AND), we can just chain multiple positive lookaheads, and put the last pattern as the one that actually captures (if everything is within a lookahead, you’ll still get the same boolean result, but not the right matches). For example, the solution to the password problem above would look like /^(?=.*\d)(?=.*[a-z])(?=.*[\W_]).{6,}$/i. Note that if you want to support IE8, you have to take this bug into account and modify the pattern accordingly.

Negation is the simplest: We just want a negative lookahead and a .+ to match anything (as long as it passes the lookahead test). For example, the solution to the negation problem above would look like /^(?!.*foo).+$/. Admittedly, negation is also the least useful on its own.

There are caveats to this technique, usually related to what actually matches in the end (make sure your actual capturing pattern, outside the lookaheads, captures the entire thing you’re interested in!), but it’s fairly simple for just testing whether something matches.

Steven Levithan took lookahead hacking to the next level, by using something similar to mimic conditionals and atomic groups. Mind = blown.

Categories
Thoughts

Teaching: General case first or special cases first?

Reading Time: 2 minutes

A common dilemma while teaching (I’m not only talking about teaching in a school or university; talks and workshops are also teaching), is whether it’s better to first teach some easy special cases and then generalize, or first the general case and then present special cases as merely shortcuts.

I’ve been revisiting this dilemma recently, while preparing the slides for my upcoming regular expressions talks. For example: Regex quantifiers.

1. General rule first, shortcuts after

You can use {m,n} to control how many times the preceding group can repeat (m = minimum, n = maximum). If you omit n (like {m,}) it’s implied to be infinity (=”at least m times”, with no upper bound).

  • {m, m} can also be written as {m}
  • {0,1} can also be written as ?
  • {0,} can also be written as *
  • {1,} can also be written as +

Advantages & disadvantages of this approach

  • Harder to understand the general rule, so the student might lose interest before moving on to the shortcuts
  • After understanding the general rule, all the shortcuts are then trivial.
  • If they only remember one thing, it will be the general rule. That’s good.

2. Special cases first, general rule after

  • You can add ? after a group to make it optional (it can appear, but it may also not).
  • If you don’t care about how many times something appears (if at all), you can use *.
  • If you want something to appear at least once, you can use +
  • If you want something to be repeated exactly n times, you can use {n}
  • If you want to set specific upper and lower bounds, you can use {m,n}. Omit the n for no upper bound.

Advantages & disadvantages of this approach

  • Easy to understand the simpler special cases, building up student interest
  • More total effort required, as every shortcut seems like a separate new thing until you get to the general rule
  • Special cases make it easier to understand the general rule when you get to it

What usually happens

In most cases, educators seem to favor the second approach. In the example of regex quantifiers, pretty much every regex book or talk explains the shortcuts first and the general rule afterwards. In other disciplines, such as Mathematics, I think both approaches are used just as often.

What do you think? Which approach do you find easier to understand? Which approach do you usually employ while teaching?

Categories
News

Poll: ¿Is animation-direction a good idea?

Reading Time: 4 minutes

¿animation-direction?

Lets assume you have a CSS animation for background-color that goes from a shade of yellow (#cc0) to a shade of blue (#079) and repeats indefinitely. The code could be something like this:

@keyframes color {
  from { background: #cc0 }
  to { background: #079 }
}

div {
  animation: color 3s infinite;
}

If we linearize that animation, the progression over time goes like this (showing 3 iterations):

As you can see, the change from the end state to the beginning state of a new iteration is quite abrupt. You could change your keyframes to mitigate this, but there’s a better way. A property with the name animation-direction gives a degree of control on the direction of the iterations to smooth this out. It also reverses your timing functions, which makes it even smoother.

In early drafts, only the values normal and alternate were allowed. normal results in the behavior described above, whereas alternate flips every other iteration (the 2nd, the 4th, the 6th and so on), resulting in a progression like this (note how the 2nd iteration has been reversed):

The latest draft also adds two more values: reverse which reverses every iteration and alternate-reverse, which is the combination of both reverse and alternate. Here is a summary of what kind of progression these four values would create for the animation above:

The problem

I was excited to see that reverse and alternate-reverse were finally added to the spec, but something in the syntax just didn’t click. I initially thought the reason was that these four values essentially set 2 toggles:

  • ¿Reverse all iterations? yes/no
  • ¿Reverse even iterations? yes/no

so it’s pointless cognitive overhead to remember four distinct values. I proposed that they should be split in two keywords instead, which would even result to a simpler grammar too.

The proposal was well received by one of the co-editors of the animations spec (Sylvain Galineau), but there was a dilemma as to whether mixing normal with alternate or reverse would make it easier to learn or more confusing. This is a point where your opinion would be quite useful. Would you expect the following to work, or would you find them confusing?

  • animation-direction: normal alternate; /* Equivalent to animation-direction: alternate; */
  • animation-direction: alternate normal; /* Equivalent to animation-direction: alternate; */
  • animation-direction: normal reverse; /* Equivalent to animation-direction: reverse; */
  • animation-direction: reverse normal; /* Equivalent to animation-direction: reverse; */

A better (?) idea

At some point, in the middle of writing this blog post (I started it yesterday), while gazing at the graphic above, I had a lightbulb moment. ¡These values are not two toggles! All four of them control one thing: which iterations are reversed:

  • normal reverses no iterations
  • reverse reverses all iterations
  • alternate reverses even iterations
  • alternate-reverse reverses odd iterations

The reason it’s so confusing and it took me so long to realize myself, is that the mental model suggested by these keywords is detached from the end result, especially in the case of alternate-reverse. You have to realize that it works as if both alternate and reverse were applied in sequence, so reverse first reverses all iterations and then alternate reverses the even ones. Even iterations are reversed twice, and are therefore equivalent to the original direction. This leaves the odd ones as being reversed. It’s basically a double negative, making it hard to visualize and understand.

I thought that a property that would reflect this in a much more straightforward way, would be animation-reverse (or animation-iteration-reverse), accepting the following values:

  • none (equivalent to animation-direction: normal)
  • all (equivalent to animation-direction: reverse)
  • even (equivalent to animation-direction: alternate)
  • odd (equivalent to animation-direction: alternate-reverse)

Not only this communicates the end result much better, but it’s also more extensible. For example, if in the future it turns out that reversing every 3rd iteration is a common use case, it will be much easier to add expressions to it, similar to the ones :nth-child() accepts.

I knew before proposing it that it’s too late for such drastic backwards-incompatible changes in the Animations module, however I thought it’s so much better that it’s worth fighting for. After all, animation-direction isn’t really used that much in the wild.

Unfortunately, it seems that only me and Sylvain thought it’s better, and even he was reluctant to support the change, due to the backwards compatibility issues. So, I started wondering if it’s really as much better as I think. ¿What are your thoughts? ¿Would it make it simpler for you to understand and/or teach? Author feedback is immensely useful for standardization, so please, ¡voice your opinion! Even without justifying it if you don’t have the time or energy. Gathering opinions is incredibly useful.

TL;DR

  1. ¿Is alternate reverse and reverse alternate (either would be allowed) a better value for animation-direction over alternate-reverse?
  2. ¿If so, should redundant combinations of normal with alternate or reverse also be allowed, such as normal alternate?
  3. ¿Or maybe we should ditch it altogether and replace it with animation-reverse, accepting values of none, all, even, odd?

Side note: If you’re wondering about the flipped question and exclamation marks (¿¡) it’s because I believe they improve the usability of the language if widely adopted, so I’m doing my part for it 😉 And no, I don’t speak Spanish.

Categories
Replies Tips

Text masking — The standards way

Reading Time: 2 minutes

As much as I like .net magazine, I was recently outraged by their “Texturizing Web Type” article. It features a way to apply a texture to text with -webkit-mask-image, presenting it as an experimental CSS property and misleading readers. There are even -moz-, -o- and -ms- prefixes for something that is not present in any specification, and is therefore unlikely to ever be supported by any non-WebKit browser, which further contributes to the misdirection. A while back, I wrote about how detrimental to our work and industry such proprietary features can be.

A common response to such complaints is that they are merely philosophical and who cares if the feature works right now and degrades gracefully. This argument could be valid for some cases, when the style is just a minor, gracefully degrading enhancement and no standards compliant alternative is present (for example, I’ve used ::-webkit-scrollbar styles myself). However, this is not the case here. We have had a standards compliant alternative for this for the past 11 years and it’s called SVG. It can also do much more than masking, if you give it a chance.

Categories
Personal

How I got into web development — the long version

Reading Time: 12 minutes

I’m often asked how I got into web development, especially from people that haven’t met many women in the field. Other times it’s people with little kids and they are asking for guidance about how to steer them into programming. I promised them that I would write a long post about it at some point, and now that I’m in the verge of some big changes in my life, I’ve started reflecting on the fascinating journey that got me here.

Rebecca Murphey wrote something similar a while back (albeit much shorter and less detailed), and I think it would be nice if more people in the field started posting their stories, especially women. I sure would find them interesting and if you give it a shot, you’ll see it’s quite enjoyable too. I sure had a blast writing this, although it was a bit hard to hit the “Publish” button afterwards.

Keep in mind that this is just my personal story (perhaps in excruciating detail). I’m not going to attempt to give any advice, and I’m not suggesting that my path was ideal. I’ve regretted some of my decisions myself, whereas some others proved to be great, although they seemed like failures at the time. I think I was quite lucky in how certain things turned out and I thank the Flying Spaghetti Monster daily for them.

Warning: This is going to be a very long read (over 3000 words) and there is no tl;dr.

Categories
Tips

Pure CSS scrolling shadows with background-attachment: local

Reading Time: 2 minutes

A few days ago, the incredibly talented Roman Komarov posted an experiment of his with pure CSS “scrolling shadows”. If you’re using Google Reader, you are probably familiar with the effect:

Screenshot demonstrating the “scrolling shadows” in Google Reader

In Roman’s experiment, he is using absolutely positioned pseudoelements to cover the shadows (which are basically radial gradients as background images), taking advantage of the fact that when you scroll a scrollable container, its background does not scroll with it, but absolutely positioned elements within do. Therefore, when you scroll, the shadows are no longer obscured and can show through. Furthermore, these pseudoelements are linear gradients from white to transparent, so that these shadows are uncovered smoothly.

When I saw Roman’s demo, I started wondering whether this is possible with no extra containers at all (pseudoelements included). It seemed like a perfect use case for background-attachment: local. Actually, it was the first real use case for it I had ever came up with or seen.

Categories
Uncategorized

git commit -m “EVERYTHING”

Reading Time: < 1 minute

I was working on a project today, when I realized that I had forgotten to commit for days (local only repo). I switched to my terminal, spent at least five minutes trying to decide on the commit message before settling to the completely uninformative “Another commit”. Embarrassed with myself, I shared my frustration with twitter:

[blackbirdpie url=”https://twitter.com/#!/LeaVerou/status/187533962283986944″]

Immediately, I started getting a flood of suggestions of what that commit message could have been. Some of them were hilarious, some clever and some both. So, I decided I wouldn’t be selfish and I’d share them. Enjoy: