Categories
Apps & scripts Original

CSS.coloratum: Convert and share CSS colors

Whenever I wanted to convert a CSS named color to RGB, I used to open the CSS3 colors spec in a new tab, search in the page and copied the values. Every time it felt even more tedious. I didn’t want to search in long tables, I wanted to type the color somewhere and get the values back, in an easy to copy format. So, after yet another color lookup earlier today, I decided to scratch my own itch and do it myself.

Of course, I didn’t plan to include a whole database of CSS colors in the website. My idea was much simpler: Use the named color to draw a rectangle in a <canvas> and then read the R,G,B values through ctx.getImageData().

I got the core functionality done in under 10 minutes, so I started adding stuff. I added a hex and HSL representation, I used canvas.toDataURL() to get a data URI of the rectangle and use it as a dynamic favicon*, I made the colors sharable and bookmarkable by using an old-fashioned hash. Also, I realized it actually supports any CSS supported color represenation by design, not just named colors.

Regarding the color conversions themselves, I took extra care to avoid redundancy. So values < 1 don’t have leading zeroes (.5 instead of 0.5) and when the hex color is in the format #xxyyzz it gets converted to #xyz. When it’s an RGBA color, it still converts it to hex, since those values will be supported in CSS4.

Since it’s for developers, I didn’t bother at all with fallbacks.

Cool stuff used:

  • HTML5: canvas, autofocus, output, oninput event, hashchange event
  • CSS3: gradients, media queries, box-sizing, background-clip, border-radius, shadows, RGBA
  • ES5: Array#map()
  • Selectors API

The reason the input’s border appears weird on Webkit is this long standing Webkit bug. Also, for some reason my nice dynamic favicons don’t display on Firefox, although they display fine in Webkit and Opera.

Enjoy: CSS.coloratum
Happy color sharing! Let me know of any problems or suggestions you may have.
PS: In case you’re wondering about the domain, I’ve had it for ages for another project and I thought it was quite fitting.

*Thanks to @milo for giving me the idea of using a dynamic favicon

Categories
Apps & scripts Original Personal

twee+: Longer tweets, no strings attached

As some people that have been following me for a while know, the 140 character limit on twitter bugs me a lot sometimes, and I’ve tried to find a way to overcome it previously as well. The most common ways these days seems to be either cutting down the long tweet into multiple pieces (yuck) or using a service to host the longer tweet and post a summary with a link to it.

The latter isn’t an entirely horrible option. However, I see 3 big downsides:

  1. I’m not very comfortable with the idea of some external service hosting my content which could close down any time due to failure to monetize their website. In that case, I’d be left with some dead links that are of no value and my content would be lost forever. Yes, they usually warn you in advance in such cases, but such news could be missed for a number of reasons.
  2. People (including yours truly) don’t plan those things in advance. They just seek services like that at the exact moment when they want to post a long tweet. Being greeted with a prompt to use Twitter Connect is NOT nice. For starters, it slows me down. Also, I don’t want to give permission to every website on the effing interwebs to post on my twitter timeline. I owe it to my followers to be responsible and not risk filling their timelines with crap.
  3. Most of these websites look like someone puked and what came out happened to be HTML and CSS. The only exception I’ve found is twtmore, but it still suffers from #1 and #2.
So, like every developer with a healthy amount of NIH syndrome, I decided to write my own 😀
My goals were:
  1. It had to be entirely client-side (except initially getting downloaded from the server of course). This way, whoever is concerned can download the full website and decode their tweets with it if it ever goes down. Also, being entirely client side allows it to scale very easily, as serving files is not a very resource intensive job (compared to databases and the like).
  2. No Twitter Connect, the tweets would get posted through Twitter Web Intents.
  3. It had to look good. I’m not primarily a designer, so I can’t make something that looks jaw-droppingly amazing, but I can at least make it look very decent.
  4. If I was gonna go through all the hassle of making this, I may as well try to keep it under 10K, so that I could take part in the 10K apart contest. (I haven’t submitted it yet, I’ll submit a few days before the deadline, as it seems you can’t make changes to your submission and I want to polish the code a bit, especially the JS — I’m not too proud about it)
I managed to succeed in all my goals and I really liked the result. I ended up using it for stuff I never imagined, like checking if a twitter username corresponds to the account I think (as it shows the avatars). So I went ahead and came up with a name, bought a domain for it, and tweeplus.com was born 🙂

twee+? Seriously?

Yes, I like it. The plus means “more”, which is fitting and + kinda looks like a t, so it could be read as “tweet” as well. Yes, I know that the word “twee” has some negative connotations, but oh well, I still like the name. Whoever doesn’t can just not use it, I won’t get depressed, I promise. 😛

Geeky stuff

How it works

  • A relatively new feature, Twitter automatically wraps URLs in t.co links, making them only 20 characters long.
  • All the text of the tweet is stored in the URL hash (query string will also work, although the output uses a hash). Some research revealed that actually browsers can handle surprisingly long URLs. Essentially, the only limit (2083 characters) is enforced by Internet Explorer. I decided to limit tweets to 2000 characters (encoded length), not only because of the IE limit, but also because I wouldn’t like people to post whole books in t.co links. We don’t want Twitter to start taking measures against this, do we? 🙂
  • A hard part was deciding which encoding to use (twitter is quite limited in the characters it parses as part of a URL).
    • My first thought was base64, but I quickly realized this was not a very good idea:
      • The encoding & decoding functions (btoa() and atob() respectively) are relatively new and therefore not supported by older browsers. I’m fine with the app hardly working in old browsers, but existing links must as a minimum be readable.
      • It uses approximately 1.34 characters per ASCII character. Unicode characters need to be URL-encoded first, otherwise an Exception is thrown. URL-encoding them uses 6 characters, which would result in 8 characters when they’re base64 encoded.
    • Then I thought of using URL-encoding for the whole thing. The good thing with it is that for latin alphanumeric characters (which are the most) it doesn’t increase the string length at all. For non-alphanumeric characters it takes up 3 characters and 6 characters for Unicode ones. Also, it’s much more readable.
    • Still, implementing it was tricky. It doesn’t encode some characters (like the dot), even though twitter doesn’t accept them as part of a URL. Also, escape() and encodeURI() behave differently and the Unicode encoding returned by the former isn’t accepted by Twitter. So I had to combine the two and do some substitutions manually.
  • When the textarea changes, the hash does too. The whole thing is a form with action=”http://twitter.com/intent/tweet”, so submitting it does the right thing naturally. I keep a hidden input with the tweet and the textarea has no name, so it doesn’t get submitted.
  • Usernames, hashtags and URLs get extracted and linkified. Usernames also get an avatar (it’s dead easy: Just use twitter.com/api/users/profile_image?screen_name={username} where {username} is the user’s username)
  • Internal “pages” (like “About” or “Browser support”) are essentially long “tweets” too.
  • A little easter egg is that if the browser supports radial gradients, the gradient follows the mouse, creating a spotlight effect. This looks nice on Chrome and Firefox, and really shitty on IE10, probably due to bugs in the gradient implementation (which I have to reduce & report sometime).

Buzzword compliance

This little app demonstrates quite a lot new open web technologies (HTML5, CSS3 etc), such as:

  • textarea maxlength
  • placeholder
  • autofocus (edit: I had to remove it cause it triggered a Webkit bug in Safari)
  • required inputs
  • New input types (url)
  • History API
  • oninput event (with keyup fallback)
  • hashchange event
  • SVG
  • Common CSS3 (border-radius, shadows, transitions, rgba, media queries)
  • CSS3 gradients
  • CSS3 animations
  • CSS3 resize
  • :empty
Let me know if I forgot something.
Oh yeah, I did forget something. There it is: twee+
Categories
Apps & scripts Original

A polyfill for HTML5 progress element, the obsessive perfectionist way

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.

Categories
Apps & scripts Original

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

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.

Categories
Apps & scripts Original

CSS3 patterns gallery and a new pattern

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).

Categories
Apps & scripts Original

Incrementable length values in text fields

I always loved that Firebug and Dragonfly feature that allows you to increment or decrement a <length> value by pressing the up and down keyboard arrows when the caret is over it. I wished my Front Trends slides supported it in the editable examples, it would make presenting so much easier. So, I decided to implement the functionality, to use it in my next talk.

If you still have no idea what I’m talking about, you can see a demo here:
View demo

You may configure it so that it only does that when modifiers (alt, ctrl and/or shift) are used by providing a second argument to the constructor and/or change the units supported by filling in the third argument. However, bear in mind that holding down the Shift key will make it increment by ±10 instead of ±1 and that’s not configurable (it would add too much unneeded complexity, I’m not even sure whether it’s a good idea to make the other thing configurable either).

You may download it or fork it from it’s Github repo.

And if you feel creative, you may improve it by fixing an Opera bug I gave up on: When the down arrow is pressed, the caret moves to the end of the string, despite the code telling it not to.

Categories
Apps & scripts Original Personal

My FT2010 slides and CSSS: My presentation framework

Screenshot of the first slideAbout a week ago, I was in Warsaw, Poland to give my first talk at a big conference, Front Trends 2010. As every first-time speaker, I was extremely nervous and worried that everything would go bad. That my talk would be boring or too basic or that I would just freeze at stage, unable to say a word. It was a 2-hour talk with a break in between, so I was also terrified that nobody would show up the second hour.

Contrary to my fears and insecurities, it went better than I could have ever hoped. The feedback on twitter and in general was enthusiastic! There wasn’t a single negative comment. Even people I look up to, like Tantek Çelik, PPK, Jake Archibald or Robert Nyman had something good to say! And instead of nobody showing up the second hour, the audience almost doubled!

At this point, I would like to thank Christian Heilmann for helping me become less nervous before my talk by going through all my slides with me and offering his invaluable advice for every part (I forgot to follow most of it, but it really helped in my attitude). I can’t thank you enough Christian!

Categories
Apps & scripts Original

CSS3 structural pseudo-class selector tester

I was doing some research today about how people explain the CSS3 structural* pseudo classes and I stumbled upon this demo by CSS tricks: http://css-tricks.com/examples/nth-child-tester/

I thought the idea is awesome, but lacks a few features:

  • It doesn’t use the native browser algorithm for selecting the elements. Granted, it’s not that tough to code your own properly, but I trust a browser implementation more (IE doesn’t support these altogether, so it’s out of the question anyway).
  • Doesn’t allow you to test for nth-last-child, nth-of-type, nth-last-of-type (and especially the last two are a lot harder to understand for most people)
  • Doesn’t allow you to add/remove list items to see the effects of the selector with different numbers of elements (especially needed if nth-last-child, nth-of-type, nth-last-of-type were involved)

So, I decided to code my own. It allows you to test for all 4 nth-something selectors, supports adding/removing elements (the selected elements update instantly) and uses the native browser implementation to select them (so it won’t work on IE and old browsers).

Enjoy: CSS3 structural pseudo-class selector tester 🙂

*Yes, :root and :empty also belong to those, but are rarely used. All other structural pseudoclasses are actually shortcuts to some particular case of the aforementioned 4 🙂

Categories
Apps & scripts Replies

A CSS3 learning(?) tool

In case anyone is interested, this is my take on the “challenge” that Brad Neuberg posted today on Ajaxian. It needs more properties, but it’s very easy to extend. I guess I should also add CSS3 values (RGBA/HSL(A) colors, CSS gradients etc) but oh well, I’m currently in a hurry. I will, if anyone actually finds it useful (?).

It didn’t prove much of a challenge actually and I honestly doubt it’s educational value (actually it’s value in general), but it was an interesting thing to do while drinking my first coffee in the morning — I really enjoyed writing it 🙂

Categories
Apps & scripts Original

Cross-browser imageless linear gradients v2

A while ago, I posted a script of mine for creating 2-color cross-browser imageless linear gradients. As I stated there, I needed them for a color picker I have to create. And even though 2-color gradients are sufficient for most components, in most color spaces, I had forgotten an important one: Hue. You can’t represent Hue with a 2-color gradient! So, I had to revise the script, and make it able to produce linear gradients of more than 2 colors. Furthermore, I needed to be able to specify a fully transparent color as one of the gradient colors, in order to create the photoshop-like 2d plane used by the picker (and no, a static image background like the one used in most JS color pickers wouldn’t suffice, for reasons irrelevant with this post). I hereby present you Cross-browser, imageless, linear gradients v2!