Blog

38 posts 2009 16 posts 2010 50 posts 2011 28 posts 2012 15 posts 2013 7 posts 2014 10 posts 2015 5 posts 2016 4 posts 2017 7 posts 2018 2 posts 2019 17 posts 2020 7 posts 2021 7 posts 2022 11 posts 2023 6 posts 2024

Vote for me in The .net awards 2011!

1 min read 0 comments Report broken page

I don’t usually post shameless plugs like that, but I’m so excited about this I decided to make an exception. A few minutes ago I found out that I’m shortlisted in the “Brilliant newcomer” category of The .net awards!!!

Thank you so much @ everyone that nominated me and/or plans to vote for me. I really appreciate it guys*! :)

* “guys” in that context is used in a gender neutral fashion, I’m not only thanking the men :P


Detecting CSS selectors support + my JSConf EU talk

2 min read 0 comments Report broken page

I’ll start with a little backstory, if you want to jump straight to the meat, skip the next 4 paragraphs.

In the past few months, my CSS research has been getting some attention and I’ve been starting to become somewhat well-known in the CSS industry. A little known fact about me is that JavaScript has always been one of my loves, almost as much as CSS (even more than it in the past). Ironically, the first time I was asked to speak in a big conference, it was about JavaScript, even though I ended up choosing to speak about CSS3 instead.

Lately, I’ve started wanting to get more into the JavaScript industry as well. I’m quite reluctant to submit speaking proposals myself (every conference or meetup I’ve given a talk so far has asked me to speak, not the other way around) and most JavaScript conferences expect you to submit a proposal yourself. I also couldn’t think of a good topic, something I was passionate about and hasn’t already been extensively covered.

This changed a few weeks ago. While I was writing my <progress> polyfill, it dawned on me: Polyfills is something that’s JS-related and I’m passionate about! I love studying them, writing them, talking about them. I quickly searched if there were any talks about polyfill writing already and I couldn’t find any. So, I decided to submit a proposal to JSConf EU, even though the call for speakers had passed 10 days ago. When I read @cramforce’s tweet that they had decided on most of the speakers, I spent a few days stressed as hell, checking my inbox every few minutes and hoping that my gut feeling that I would get accepted was right.

And it was! 3 days ago I received an email from JSConf EU that my proposal was accepted!! I can’t even begin to describe how happy and excited I am about it. And nervous too: What if they know everything I’m going to say? What if they hate my talk? What if the JavaScript industry is really as sexist as some people claim and they dismiss me because of my gender? I decided to put my fears aside and start working on my slides, as I couldn’t wait until later (even though I have multiple deadlines creeping up on me right now…).

A big part of writing polyfills is feature detection. Before trying to implement a feature with JavaScript, you first have to check if it’s already supported. So, a substantial portion of my talk will be about that. How to detect if APIs, HTML elements, CSS properties/values/selectors etc are supported. There are already established solutions and techniques about most of these, except CSS selectors. Modernizr doesn’t detect any, and judging from my Google search nobody has written about any techniques for doing so in a generic fashion.

A really simple way to detect CSS selectors support is using document.querySelector() in a try...catch statement. If the selector is not supported, an error will be thrown. However, that’s not really reliable, as the Selectors API is not supported in IE < 8. So, I thought of another idea: What if I turn the hassle of reading out a stylesheet via the DOM methods (browsers drop stuff they don’t understand) into a feature detection method?

The basic idea is creating a new <style> element with an empty rule and the selector we want to test support for, and then read out the stylesheet through the DOM methods to see if a rule actually exists. I’ve so far tested it in Firefox, Opera and Chrome and it seems to work. I haven’t tested it in IE yet, as I currently have too many apps running to turn on the vm, so it might need a few fixes to work there (or I might be unlucky and the idea might not work at all).

You can test it out yourself in this fiddle, just check the console: http://fiddle.jshell.net/leaverou/Pmn8m/show/light/

Apologies if this has already been documented elsewhere, I really couldn’t find anything.

Edit: James Long worked on fixing my example’s issues with IE


A polyfill for HTML5 progress element, the obsessive perfectionist way

6 min read 0 comments Report broken page

Yesterday, for some reason I don’t remember, I was looking once more at Paul Irish’s excellent list of polyfills on Github. I was really surprised to see that there are none for the <progress> element. It seemed really simple: Easy to fake with CSS and only 4 IDL attributes (value, max, position and labels). “Hey, it sounds fun and easy, I’ll do it!”, I thought. I have no idea how in only 1 day this turned into “OMG, my brain is going to explode”. I’ve documented below all the pitfalls I faced. And don’t worry, it has a happy ending: I did finish it. And published it. So, if you’re not interested in long geeky stories, just jump straight to its page.

First things first: Controlling the width of the value bar

Most progress bars out there use 2 elements: One for the container and one for the value bar. I was pretty stubborn about not using an extra element. I wanted to use pseudo-elements instead and keep the DOM tree as clean as I found it. And there it was, the first problem: How to set the width?

CSS3 attr() and calc() are hardly supported and attr() is not even allowed in calc(), so I quickly realized that a pure CSS solution was out of the question. However, if I used JavaScript, how would I set a different width for every progress::before? You can’t set that in an inline style, and assigning every <progress> element an ID and adding separate rules seems a bit too intrusive to me. Think about it for a second, what would you do?

I realized I had to control the width of the pseudo-element through CSS properties of the parent container somehow. And then it dawned on me: If the pseudoelement has display:block, it will automatically get the parent width, minus the padding and borders. There it was, this was my solution. I just had to set padding-right accordingly, so that the value bar gets the width it needs to be! And I had already given it box-sizing: border-box, as it was in Webkit’s UA stylesheet, so I didn’t have to worry about padding changing the width of the element. The first problem was solved.

Becoming dynamic

The static part was quite easy indeed. Selecting all <progress> elements and using their attributes to set an appropriate padding-right was pretty much run of the mill. But that wasn’t enough. What happens if you set the properties through script? What happens if you set the attributes? The progress bar should update accordingly, it had to be dynamic. A static progress bar is not much of a fallback. It might be acceptable for <meter>, since in most interfaces it’s used in a static way. But a progress bar needs to change in order to show um, progress.

First step was adding the properties that are in its DOM Interface. “Easy, I’ll add them to the prototype” thought my naïve self. So, I needed to find which prototype, I didn’t want to add them in every HTML element of course. So I eagerly typed Object.prototype.toString.call(document.createElement('progress')) in Firebug’s console and it slapped me in the face with an '[object HTMLUnknownElement]'. D’oh! I had forgotten that unknown elements share a common prototype named like that. So, I had to add them to each one individually. I hated that, but since it was the only way, I did it and moved on.

Of course, I didn’t just assign a static value to them, otherwise they wouldn’t solve much: The progress bar would still be static. I assigned getters and setters that used the value and max attributes to return what they should. Assigning getters and setters to a property is a whole new problem by itself, as some browsers use __defineGetter__/__defineSetter__ and some others the ES5 standard Object.defineProperty. But I had solved that one before, so it didn’t slow me down.

The getters and setters solved the issue one-way only: If you set the properties, the progress bar and its attributes would be updated. That would be enough for most authors using the polyfill, but no, I wanted it to be perfect. “If you change the attributes, the progress bar and its properties should too!” my annoyingly pedantic inner self insisted. “And what if you dynamically add more <progress> elements?”.

There are two ways to do stuff when attributes change and elements get added: Polling and mutation events. The advantage of polling is its perfect browser support, which comes at a big cost: It’s horrible performance-wise. Also, polling introduces a delay that could be unacceptable in some cases, especially considering how short the duration of some progress bar use cases is. So, I went with mutation events, even though they are deprecated (seriously W3C? deprecating something, without providing a solid alternative??) and don’t have perfect browser support. After all, it was the only way (I don’t consider polling a real option in this case).

Styling

After messing around a little, it seemed to work great in Opera 10.63 and Firefox 5, which I had open for my tests. It was time to write some unit tests and check it out in more browsers. Instead, I opted to style it, as a desperate attempt to delay my confrontation with IE8 a bit longer (and for good reason, as it turned out later). Given that CSS is kinda my specialization, I expected styling to be a piece of cake and even relaxing. Instead, it came with it’s fair share of trouble and hard dilemmas.

If you notice the native progress bars in OSX, you will see that they use gradients. I mocked up something similar with CSS gradients, which wasn’t easy, as I wanted to keep the hue/saturation information in the background-color only, for easy modifications and Webkit uses a regular gradient with color stops that have different hues and saturations. And then I realised that this was not going to show up at all in IE8-IE9, which were 2 major browsers that my polyfill would target. No gradient may be acceptable in determinate progress bars, but it’s not an option in indeterminate ones: Scrolling diagonal stripes is the convention and there’s no other way to communicate this status to the average user.

So I decided to go with the old way of using raster images for gradients (through a data URI). Another painful slap in the face was when I realized that those moving stripes need to be semi-transparent. To do that, my options were:

  • CSS3 animations - no good in my case, as it’s crucial to show up and their browser support isn’t that good
  • SVG with SMIL - Much better browser support than CSS3 animations, but still no go in IE
  • APNG - Only supported by Firefox and Opera, even after all these years

I happened to be chatting with Tab Atkins at the moment, and he suggested I go with plain ol’ GIFs. I was originally negative, but after thinking about it I realized that antialiasing is not that crucial in 45deg stripes, especially when they’re moving. I tried it, I liked the result, so I kept it. Phew, that one was easy.

The IE8 nightmare

After spending a few hours tweaking the gradients and the CSS (yes, hours. I said I’m an obsessive perfectionist, didn’t I?) I finally wrote some unit tests and fired up Virtualbox to test with IE8. I prepared myself for the worst, and secretly hoped I’d be pleasantly surprised. Instead, I faced a developer’s worst nightmare. Two words: Stack overflow.

The culprit was a classic IE bug with DOM properties and HTML attrtibutes that I had blissfully forgotten: IE thinks they’re the same. I had added getters and setters (or etters, as I like to call both) to the max and value properties which used the max and value attributes, resulting in infinite recursion in IE8.

This was the hardest of all problems, and I never completely solved it: A few unit tests still fail in IE8 because of it, although there’s no infinite recursion any more. Luckily, this bug was fixed in IE9, so the polyfill works flawlessly there.

My first idea was the obvious one: to duplicate the values somewhere. In a lookup table, in another property, somewhere. I didn’t quite like the idea, so I kept brainstorming. And then it dawned on me. They’re already duplicated somewhere, and not only it’s not redundant, but actually encouraged: in the WAI-ARIA attributes!

To clarify, when progress elements are natively supported, they already have built-in ARIA roles and attributes. However, when they’re not, you should add them yourself, if you want the control to be accessible. From my research, there was a progressbar role, and it required the attributes aria-valuemin, aria-valuemax, aria-valuenow and aria-labelledby. I implemented all but the latter, as it proved too much of a hassle for very few edge cases (how many people put IDs in their labels without using aria-labelledby themselves?). So, aria-valuemax was already duplicating max and aria-valuenow was duplicating value. I changed everything to use those instead.

After lots of head-scratching, IE-cursing and feeling that my brain was going to explode all over my laptop, I managed to kinda have it working. I knew in advance that some unit tests would fail, as it doesn’t support mutation events. I eventually gave up when I realized that the last unit test in the “static” category failed because getAttribute('max') returned null, since IE had completely removed the attribute from the DOM tree. It was the last straw and made me say “That’s it, I’m done with this piece of shit”.

Safari 5 craziness

After IE, it was Safari’s turn. I knew that I could only target Safari 5, as Safari 4 doesn’t support etters on DOM elements and Safari 5.1 will probably support progress elements natively, since they’ve been in Webkit for ages. I launched Safari without fear. “How can it possibly not work in Safari? It will probably be fine, maybe just need a one or two little tweaks in the worst case”, I reassured myself thinking.

The progress bars were not even showing. At all. My first guess was that it was a one time rendering error. When it persisted after a few reloads, I opened the dev tools to see what the hell happened. I saw a series of errors like this:

<progress> is not allowed inside <label>. Content ignored. Unmatched encountered. Ignoring tag.

At first, I thought the problem was the label. So I made all labels external. And then still got the same errors for the <li>s. And every other element I tried. Even when I put them directly into the <body>, Safari complained that they are not allowed to be inside it! It turned out that this was a bug in a build of Webkit, and coincidentally, this build was the one Safari 5 uses.

There wasn’t much to think about in this one: They’re not in the DOM, so I can’t do anything about them. It’s mission impossible.

Happy(?) end

After IE8’s and Safari5’s cruel rejection, I was quite dispirited. IE8 had already caused me to make my code uglier and more verbose, and now Safari 5 flat out refuses to accept any treatment. It worked flawlessly in Firefox 3.5, but that didn’t cheer me up much. I decided that this has already taken up too much of my time. It’s now the community’s turn. Have any ideas about how further improvement? Maybe some more unit tests? I’ll be waiting for your pull requests! :) Github repo

Appendix: Why do some unit tests fail in browsers that natively support <progress>?

While developing this, I discovered 2 browser bugs: One in Webkit’s implementation and in for Opera’s. I plan to report these soon.


CSS reflections for Firefox, with -moz-element() and SVG masks

2 min read 0 comments Report broken page

We all know about the proprietary (and imho, horrible) -webkit-box-reflect. However, you can create just as flexible reflections in Firefox as well, by utilizing -moz-element(), some CSS3 and Firefox’s capability to apply SVG effects to HTML elements. And all these are actually standards, so eventually, this will work in all browsers, unlike -webkit-box-reflect, which was never accepted by the CSS WG.

First and foremost, have a look at the demo:

How it works

  • For every element, we generate an ::after pseudoelement with the same dimensions and a position of being right below our original element.
  • Then, we make it appear the same as our element, by giving it a background of ‑moz-element(#element-id) and no content.
  • Reflections are flipped, so we flip it vertically, by applying transform: scaleY(‑1);
  • If we want the reflection to have a little distance from the element (for example 10px like the demo), we also apply a transform of translateY(10px)
  • We want the reflection to not be as opaque as the real element, so we give it an opacity of around 0.3-0.4
  • At this point, we already have a decent reflection, and we didn’t even need SVG masks yet. It’s essentially the same result -webkit-box-reflect gives if you don’t specify a mask image. However, to really make it look like a reflection, we apply a mask through an SVG and the mask CSS property. In this demo, the SVG is external, but it could be a data URI, or even embedded in the HTML.

Caveats

  • Won’t work with replaced elements (form controls, images etc).
  • If you have borders, it gets a bit more complicated to size it properly
  • Doesn’t degrade gracefully, you still get the pseudoelement in other browsers, so you need to filter it out yourself
  • Bad browser support (currently only Firefox 4+)
  • You need to set the reflection’s background for every element and every element needs an id to use it (but this could be done automatically via script)

Further reading

Credits: Thanks to Christian Heilmann for helping me debug why SVG masks for HTML elements weren’t originally working for me.


Pure CSS Tic Tac Toe

1 min read 0 comments Report broken page

It’s supposed to be used by 2 people taking turns (click twice for the other sign).

Basic idea:

  • It uses hidden checkboxes for the states (indeterminate means empty, checked means X, not checked means O) and labels for the visible part
  • When it starts, a little script (the only js in the demo) sets the states of all checkboxes to indeterminate.
  • It uses the :checked and :indeterminate pseudo-classes and sibling combinators to change the states and show who won.
  • Once somebody clicks on a checkbox (or in this case, its label) they change it’s state from indeterminate to either checked or not checked, depending on how many times they click on it.

As a bonus, it’s perfectly accessible through the keyboard (although I assume it’s not screen reader accessible).

A <table> would be much more appropriate for the markup, but I decided to sacrifice semantics in this case to make the demo simpler.

All modern browsers support the indeterminate state in checkboxes (for Opera you will need the latest Opera.Next), however this demo doesn’t work on old Webkit (Chrome and Safari) because of an old bug that made the sibling combinators (+ and ~) static in some cases which has been fixed in the nightlies. It should work in Firefox, Opera.next, Webkit nightlies and IE9, although I haven’t tested in Opera.next and IE9 to verify.

Enjoy:


jQuery Pure: Call for contributors

2 min read 0 comments Report broken page

This post is about an idea I’ve had for ages, but never found the time to actually start working on it. Maybe because it looks like a quite big project if done properly, so it’s scary to do it on my own without any help.

jQuery has a huge amount of code that deals with browser bugs and lack of implementations. For example, it needs a full-fledged selector engine, to cater for old browsers that don’t support the Selectors API. Or, it needs code that essentially does what the classList API is supposed to do, because old browsers don’t support it. Same goes for nextElementSibling (the .next() method) and tons of other stuff. However, not everyone needs all this. Some projects don’t need older browsers support, either due to the developer mindset or due to their tech-savvy target group. Also, some people only write demos/proof-of-concepts for modern browsers only and don’t need all this code. Same goes for intranet apps that are only designed for a particular modern browser. Last but not least, this code bloat makes the jQuery library hard to study for educational purposes.

However, even in a browser that supports all the modern stuff, the jQuery API is still more concise than the native methods. Besides, there are tons of plugins that depend on it, so if you decide to implement everything in native JavaScript, you can’t use them.

What I want to build is a fork of jQuery that is refactored so that all the extra code for working around browser bugs removed and all the code replaced by native functionality, where possible. All the ugliness removed, leaving a small, concise abstraction that only uses the current standards. Something like jQuery: The good parts. It could also serve as a benchmark for browser standards support.

The API will work in the exact same way and pass all unit tests (in modern browsers, in cases where they are not buggy) so that almost every plugin built on top of it will continue to function just as well. However, the jQuery library itself will be much smaller, with more elegant and easy to understand code.

So, who’s with me? Do you find such an idea interesting and useful? Would you want to contribute? If so, leave a comment below or send me an email (it’s in the about page). Also, please let me know if you can think of any other uses, or if there’s already something like that that I’ve missed.


My experience from Web Directions @media & Standards.next

2 min read 0 comments Report broken page

Last week, I was in London to give 2 talks. The first one was last Thursday, in one of the conferences I wanted to go ever since I learned my first CSS properties: Web directions @media. The second one was 2 days later in a smaller event called Standards.next.

Web Directions @media

I managed to get my @media talk early on schedule, so I could relax afterwards and enjoy the rest of the conference. Before I saw the feedback on twitter I thought they hated it, since the audience was silent and didn’t laugh at any of my jokes and asked no questions afterwards. However, I was wrong: The tweets about it were enthusiastic! Here’s a small sample:

You can play with the HTML version of my slides or view them on slideshare:

Mastering CSS3 gradients

View more presentations from Lea Verou

I really enjoyed some of the other talks in @media, especially:

Standards.next

The morning before my Standards.next talk, I woke up with a sore throat, a running nose and a blocked ear. I even thought about cancelling my talk, but I’m one of those people that have to be dying to change their schedule. So I went, and I’m glad I did, as I got to attend Peter Gasston’s incredible talk on CSS3 layout. I really learned so much stuff from that!

As for my talk (“CSS Secrets: 10 things you might not know about CSS3”), it went fine after all. I had some trouble hearing the questions, due to the blocked ear, but nothing too bad. I had trouble with my last demo, as I got confused and used background-origin: padding-box; instead of content-box, but nobody there hated me because of it, like I was afraid would happen if I ever screwed up one of my demos :)

That event was much smaller (it took place in a small room in a pub), so the tweets were much fewer, but still very positive:

https://twitter.com/patrick\_h\_lauke/status/74496751716929536

https://twitter.com/patrick\_h\_lauke/status/74501557349138432

https://twitter.com/patrick\_h\_lauke/status/74506910807764992

I found out afterwards that one particular lady in the audience complained about my pronunciation of the words “fuchsia” and “ems”. That’s what I would’ve said to her if I heard: “Here’s some breaking news to you: Not everyone is a native english speaker. Shocking, isn’t it? I would really be interested to hear your pronunciation if you ever did a presentation in Greek. KKTHXBAI”

Overall, I had a great time in London. I hadn’t been there for more than 10 years, so I had forgotten how beautiful city it is. I loved attending and speaking at both of those events, and I would like to thank Maxine Sherrin and John Allsopp for inviting me to @media and Bruce Lawson for inviting me at Standards.next.


Get your hash — the bulletproof way

3 min read 0 comments Report broken page

This is probably one of the things that everyone thinks they know how to do but many end up doing it wrong. After coming accross yet one more super fragile snippet of code for this, I decided a blog post was in order.

The problem

You want to remove the pound sign (#) from location.hash. For example, when the hash is "#foo", you want to get a string containing "foo". That’s really simple, right?

Tricky cases

What most developers seem to miss is that in modern, JavaScript-heavy applications, a hash can contain any unicode character. It doesn’t necessarily have to correspond to the value of an actual id attribute in the page. And even when it does, ID attributes can now contain almost any unicode character. Another thing sometimes forgotten is that there might be no hash in the page. Even in a URL that ends in #, location.hash is actually equal to "" (the empty string) and not "#".

Naive approaches

This one is the most recent, found in a book I was tech reviewing:

var hash = location.hash.match(/#(\w+)/)[1];

which has quite a few issues:

  • Returns wrong results when there is any non-latin or non-alphanumeric character in the hash. For example, for the hash #foo@o#bar$%huh hello, just "foo" would be returned.
  • Throws a TypeError when location.hash is empty, since .match() will return null.

Other variations of this pattern I’ve seen include using explicitly defined character classes instead of \w, adding an anchor (^) before the pound sign (which is an excellent idea for performance) and checking if .match() actually returned something before using its result. However, they usually also fall into at least one of the 2 aforementioned issues.

Another approach a friend of mine once used was this:

var hash = location.hash.split(‘#’)[1];

This also has its issues, which are ironically less than the first one, even though it seems a far more naive approach.

  • With the same test hash, it would at least get the "foo@o" part, which means it only fails when the hash contains a pound sign
  • When there’s no hash, it doesn’t throw an error, although it returns undefined instead of the empty string.

Getting it right

The approach I usually use is far simpler than both of the above and probably looks too loose:

var hash = location.hash.substring(1);

However, let’s examine it a bit:

  • With our weird test hash, it actually returns the correct result: “foo@o#bar$%huh hello”
  • When no hash exists, it correctly returns the empty string

“But it assumes there’s a pound sign at the start of the string!” I almost hear some of you cry. Well, that could be a real concern, if we were dealing with an arbitrary string. In that case, we would have to check if there’s actually a pound sign first or if the string even exists. However, with location.hash the only case when that is not true, is when there is no hash. And we got that case covered. ;)

Edit: As pointed out in the comments, you may also use location.hash.slice(1) instead of substring. I kinda prefer it, since it’s 4 bytes shorter.

If however you’re obsessed with RegExps and want to do it with them no matter what, this is just as bulletproof and almost as short:

var hash = location.hash.replace(/^#/, ‘’);

If for some reason (OCD?) you want to do it with .match() no matter what, you could do this:

var match = location.hash.match(/^#?(.*)$/)[1];

In that case, since the pound sign is optional, since .match() never returns null. And no, the pound sign never erroneously becomes part of the returned hash, because of the way regex engines work.

“This is too basic, what a waste of my time!”

Sorry for that. I know that for some of you, this is elementary. But the guy who wrote that book is very knowledgable (the book is really good, apart from that code snippet) so I thought this means there are many good developers out there who get this wrong, so this post was needed to be written. If you’re not one of them, you can take it as a compliment.

“Hey, you missed something too!”

In that case, I’d love to find out what it is, so please leave a comment! :)


Change URL hash without page jump

1 min read 0 comments Report broken page

In modern complex layouts, sometimes the point where a hash will transport you to will be entirely different than the one you actually wanted. If you prevent the default event, you will save yourself from the page jump, but the hash won’t change either. You can accept the regular behavior and change scrollTop after the jump, but the user will still see a distracting flicker. Chris Coyier found a great workaround last year but it’s not meant for every case.

A different solution

Turns out we can take advantage of the History API to do that quite easily. It’s just one line of code:

history.pushState(null, null, ‘#myhash’);

and we can combine it with the old method of setting location.hash to cater for older browsers as well:

if(history.pushState) { history.pushState(null, null, ‘#myhash’); } else { location.hash = ‘#myhash’; }

Browser support?

The History API is supported by:

  • Firefox 4+
  • Safari 5+
  • Chrome 8+
  • Coming soon in Opera

Enjoy :)


My experience from Geek Meet

1 min read 0 comments Report broken page

I decided to start writing a blog post after every talk I give, to be able to go back and remember what I thought about each event, what feedback my talk got etc. And I’m starting with Geek Meet May 2011.

The event

Geek Meet is a meetup organized in Stockholm by Robert Nyman. It has hosted talks by many industry leaders like Jake Archibald, Bruce Lawson, Molly Holzschlag, Chris Mills, Remy Sharp, Christian Heilmann and more. It’s free to attend and has sponsors so it can afford to offer free food, drinks and speaker accommodation.

My experience

I was very surprised to hear that the event was sold out just 18 minutes after Robert’s announcement! According to him, that set a new record for it!

This event was kinda challenging in many ways. I was the only speaker, so if I failed, everyone would notice. Also, I had to give 2 talks and one of them was brand new, which is always stressful.

However, the crowd there was awesome! Not only they were very relaxed, but they had a great sense of humor too. I don’t think I had ever been in an event that was so relaxed. And their reaction to my talks was so encouraging, I don’t think I have ever heard such loud clapping in my life!

I’m saving the feedback I got here, to bottle the feeling:


StronglyTyped: A library for strongly typed properties & constants in JavaScript

2 min read 0 comments Report broken page

StronglyTypedI’ll start by saying I love the loosely typed nature of JavaScript. When I had to work with strongly typed languages like Java, it always seemed like an unnecessary hassle. On the contrary, my boyfriend even though very proficient with HTML, CSS and SVG, comes from a strong Java background and hates loosely typed scripting languages. So, to tempt him into JS and keep him away from heavy abstractions like Objective-J, I wrote a little library that allows you to specify strongly typed properties (and since global variables are also properties of the window object, those as well) of various types (real JS types like Boolean, Number, String etc or even made up ones like Integer) and constants (final properties in Java). It uses ES5 getters and setters to do that and falls back to regular, loosely typed properties in non-supporting browsers.

Also, as a bonus, you get cross-browser Function.prototype.bind and Array.prototype.forEach and a robust type checking function: StronglyTyped.is(type, value).

Example: Strongly typed properties

You define strongly typed properties by using the corresponding methods of the StronglyTyped object. For example, the following snippet defines a boolean property called “foo” on an object literal:

var o = {};

StronglyTyped.boolean(o, ‘foo’, true);

console.log(o.foo); // prints true

o.foo = false; console.log(o.foo); // prints false

o.foo = ‘bar’; // TypeError: foo must be of type Boolean. bar is not.

Example: Constants

You define constants by using the constant method of the StronglyTyped object. For example, the following snippet defines a global MAGIC_NUMBER constant:

var o = {};

StronglyTyped.constant(window, ‘MAGIC_NUMBER’, 3.1415926535);

console.log(MAGIC_NUMBER); // prints 3.1415926535

MAGIC_NUMBER = 4; console.log(MAGIC_NUMBER); // prints 3.1415926535

Please note that constants only become read-only after they first get a non-undefined value. For example:

StronglyTyped.constant(window, ‘MAGIC_NUMBER’);

console.log(MAGIC_NUMBER); // prints undefined

MAGIC_NUMBER = undefined;

console.log(MAGIC_NUMBER); // prints undefined

MAGIC_NUMBER = 3.1415926535; console.log(MAGIC_NUMBER); // prints 3.1415926535

MAGIC_NUMBER = 4; console.log(MAGIC_NUMBER); // prints 3.1415926535

Supported types

The property types currently supported by StronglyTyped are:

  • Array
  • Boolean
  • Date
  • Function
  • Integer
  • Number
  • RegExp
  • String

null and undefined are valid in every type. NaN and Infinity values are accepted in both the Number and the Integer types.

If you want to use a type that’s not among the above but either is native to the browser (for example Element) or a global object, you can use the generic method StronglyTyped.property(type, object, property [, initialValue]):

var o = {};

StronglyTyped.property(‘Element’, o, ‘foo’, document.body);

console.log(o.foo); // prints a representation of the <body> element

o.foo = document.head; console.log(o.foo); // prints a representation of the <head> element

o.foo = 5; // TypeError: foo must be of type Element. 5 is not.

Browser support

It should work on every browser that supports Object.defineProperty or __defineGetter__ and __defineSetter__. As you can see from kangax’s awesome compatibility tables for Object.defineProperty and __define(G|S)etter__, those are:

  • Firefox 3.5+
  • IE8 (only on DOM elements)
  • IE9+
  • Opera 10.5+
  • Chrome 5+
  • Safari 4+
  • Konqueror 4.4+

However, it’s only verified to work in:

  • Firefox 4 (Win and OSX)
  • IE9+
  • Opera 11.10 for OSX, Opera 11 for Windows
  • Chrome (Win and OSX)
  • Safari 5 (Win and OSX)

This doesn’t mean it won’t work in the rest, just that it hasn’t been tested there (yet). You can load the unit tests (sort of…) in a browser you want to test and let me know about the results. :)

Naice! Can I haz?

As usual, you can get it from Github: Github repo

Credits

Thanks a lot to Max (@suprMax) for Windows testing!


Rule filtering based on specific selector(s) support

2 min read 0 comments Report broken page

I’ve been using this trick for quite a while, but I never thought to blog about it. However, I recently realized that it might not be as common as I thought, so it might be a good idea to document it in a blog post.

If you follow the discussions on www-style, you might have noticed the proposal for a @supports rule to query property and value support. Some people suggested that it should also test for selectors, for example whether a certain pseudo-class is supported. However, you can do that today, albeit in a limited manner (no OR and NOT support).

The main principle that you need to keep in mind is that browsers are expected to drop rules with selectors they don’t understand, even partially. So, if only one selector in a group cannot be parsed, the whole rule will be dropped. This means we can construct selector “tests”, which are use cases of the selector whose support we want to test, that will not match anything, even if the selector is supported. Then, we include that selector in the beginning of our selector group. If all this is unclear, don’t worry, as there’s an example coming next :)

Example

Suppose you want to apply the following CSS (for rudimentary custom checkboxes):

input[type=“checkbox”] { position:absolute; clip: rect(0,0,0,0); clip: rect(0 0 0 0); }

input[type=“checkbox”] + label::before { content: url(‘checkbox.png’); }

input[type=“checkbox”]:checked + label::before { content: url(‘checkbox-checked.png’); }

only in browsers that support the attribute equality selector, the :checked pseudo-class and the ::before pseudo-element. We need to try to think of a selector that includes all of them but matches nothing. One such selector would be #foo[type="checkbox"]:checked::before. Even in supporting browsers, this matches nothing as there’s no element with id=“foo”. We can reduce the test for every rule to conserve bandwidth: For example, we don’t need to include tests for the attribute selector in any of them, since they are present anyway in all three rules. Also, we may eliminate ::before from the second test and we don’t need any test for the 3rd one, since it includes all features we want to test for. To sum up:

#foo:checked::before, input[type=“checkbox”] { position:absolute; clip: rect(0,0,0,0); clip: rect(0 0 0 0); }

#foo:checked, input[type=“checkbox”] + label::before { content: url(‘checkbox.png’); }

input[type=“checkbox”]:checked + label::before { content: url(‘checkbox-checked.png’); }

An important caveat of this technique is that Internet Explorer up to version 7 will split selectors before parsing them, so it will completely ignore our filters :( (Thanks to Ryan Seddon for finding that out).

Disclaimer: The original idea about custom checkboxes belongs to Ryan Seddon, although his code was quite different.


CSS3 patterns gallery and a new pattern

1 min read 0 comments Report broken page

I finally got around to doing what I wanted to do for quite a few months: Create a gallery with all the basic patterns I was able to create with CSS3 gradients. Here it is:  CSS3 Pattern Gallery

Also, it includes a brand new pattern, which is the hardest one I have ever made so far: Japanese cubes. Thanks to David Storey for challenging me about it.

Supported browsers:

  • Firefox 4 (the patterns themselves work on 3.6 too but the gallery doesn’t due to a JS limitation)
  • Opera 11.10
  • IE10
  • Google Chrome
  • Webkit nightlies

However bear in mind that every implementation has its limitations so a few of them won’t work in all the aforementioned browsers (for example Opera doesn’t support radial gradients and Firefox doesn’t support explicitly sized ones).


Invert a whole webpage with CSS only

1 min read 0 comments Report broken page

I recently saw Paul Irish’s jQuery invert page plugin. It inverts every color on a webpage including images or CSS. This reminded me of the invert color keyword that’s allowed on outlines (and sadly only supported by Opera and IE9+). So I wondered how it could be exploited to achieve the same effect through CSS alone. Turned out to be quite simple actually:

body:before { content:“”; position:fixed; top:50%; left: 50%; z-index:9999; width:1px; height: 1px; outline:2999px solid invert; }

Not even pointer-events:none; is needed, since outlines don’t receive pointer events anyway, and there’s no issue with scrollbars since they don’t contribute to scrolling. So this is not even CSS3, it’s just plain ol’ CSS 2.1.

And here’s a bookmarklet to inject it into any given page: [Invert page](javascript:(function(){var%20style=document.createElement(‘style’);style.innerHTML=‘body:before%20{%20content:%22%22;%20position:fixed;%20top:50%25;%20left:50%25;%20z-index:9999;%20width:1px;%20height:%201px;%20outline:2999px%20solid%20invert;%20}’;document.body.appendChild(style)})();)

**Note:**This will only work on Opera and IE9+ since they’re currently the only ones supporting the color keyword ‘invert’ on outlines. However, it’s probably possible to add Firefox support too with SVG filters, since they support them on HTML elements as well.

As for why would someone want to invert a page… I guess it could be useful for people that can read white text on dark backgrounds more easily, April fools jokes, konami code fun and stuff like that.

Update: Mozilla is planning to never support invert because there’s a loophole in the CSS 2.1 spec that allows them to do that. However, you can push them to support it by voting on the relevant issue.


Create complex RegExps more easily

30 min read 0 comments Report broken page

When I was writing my linear-gradient() to -webkit-gradient() converter, I knew in advance that I would have to use a quite large regular expression to validate and parse the input. Such a regex would be incredibly hard to read and fix potential issues, so I tried to find a way to cut the process down in reusable parts.

Turns out JavaScript regular expression objects have a .source property that can be used in the RegExp constructor to create a new RegExp out of another one. So I wrote a new function that takes a string with identifiers for regexp replacements in and replaces them with the corresponding sub-regexps, taken from an object literal as a second argument:

/** * Create complex regexps in an easy to read way * @param str {String} Final regex with for replacements * @param replacements {Object} Object with the replacements * @param flags {String} Just like the flags argument in the RegExp constructor */ RegExp.create = function(str, replacements, flags) { for(var id in replacements) { var replacement = replacements[id], idRegExp = RegExp(’ + id + ', ‘gi’);

if(replacement.source) { replacement = replacement.source.replace(/^\^|\$$/g, ‘’); }

// Don’t add extra parentheses if they already exist str = str.replace(RegExp(‘\\(’ + idRegExp.source + ‘\\)’, ‘gi’), ‘(’ + replacement + ‘)’);

str = str.replace(idRegExp, ‘(?:’ + replacement + ‘)’); }

return RegExp(str, flags); };

If you don’t like adding a function to the RegExp object, you can name it however you want. Here’s how I used it for my linear-gradient() parser:

self.regex = {};

self.regex.number = /^-?[0-9]*\.?[0-9]+/;self.regex.keyword=/(?:tops+|bottoms+)?(?:right|left)|(?:rights+|lefts+)?(?:top|bottom)/;

self.regex.direction = RegExp.create(‘^(?:|deg|0)$’, { keyword: self.regex.keyword, number: self.regex.number });

self.regex.color = RegExp.create(‘(?:||)’, { keyword: /^(?:red|tan|grey|gray|lime|navy|blue|teal|aqua|cyan|gold|peru|pink|plum|snow|[a-z]{5,20})/,func:RegExp.create(′(?:rgb|hsl)a?((?:s\*', { number: self.regex.number }), hex: /^#(?:[0-9a-f]{1,2}){3}$/ });

self.regex.percentage = RegExp.create(‘^(?:%|0)$’, { number: self.regex.number });

self.regex.length = RegExp.create(‘|0’, { number: self.regex.number, unit: /%|px|mm|cm|in|em|rem|en|ex|ch|vm|vw|vh/ });

self.regex.colorStop = RegExp.create(‘\\s*?’, { color: self.regex.color, length: self.regex.length }, ‘g’);

self.regex.linearGradient = RegExp.create(‘^linear-gradient\\(\\s*(?:()\\s*,)?\\s*(\\s*(?:,\\s*\\s*)+)\\)$’, { direction: self.regex.direction, colorStop: self.regex.colorStop }, ‘i’);

(self in this case was a local variable, not the window object)