Learning much javascript from one line of code

October 6, 2014 10:04 am 69 comments

Since javascript is everywhere nowadays, it is really easy to learn new stuff everyday. Once you know the basics of the language, you can take bits of code from here and there that have a lot of knowledge in them. Bookmarklets are perfect examples of a bunch of packed functionality, whenever I discover a useful one, I enjoy studying their source, discovering how it can do so much. Also snippets to use external services, like the google analytics code, or facebook likebox, can teach us more than some books.

Today I want to break in pieces a one-liner code that Addy Osmani shared a few days ago that can be used to debug your CSS layers. Here it is, in 3 lines to fit in the post:

Try to type it in your browser console, and the different layers of HTML that there are in the web page will be highlighted in different colors. Isn’t it awesome? Basically, it gets all the elements of the page, and applies a 1 px outline to them with a random color. The idea is simple, but to create a code line like this you must master a lot of aspects of web development. Let’s study them.


People from Webucator made a video about this article, so you can watch instead of read. Isn’t it great? If you are learning Javascript, checking Webucator javascript training is a must.

Selecting all the elements of a page

What it is needed the first is to get all the elements, and Addy uses the  function $$ that is only available in the console of browsers. Try it by yourself, open your browser’s javascript console and type $$('a') and you will get a list with all the anchor elements of the current page.

$$ function is part of the command line API of modern browsers, and it is equivalent to use the method document.querySelectorAll, you can pass a CSS selector as argument to get the matched elements in the current page. So if you would like to use the one-liner out the browser’s console you could replace $$('*') by document.querySelectorAll('*'). More about the function $$ can be found in this stackoverflow answer.

It is great! For me, it was worthy to study the code just by meeting the function $$. But there are more about selecting everything in a page, if you have a look at the comments of the gist, there are people discussing this part of the code. One of them is Mathias Bynens, ( a lot of clever people there! ) who suggests that we can also use document.all to select all the elements of a page, it is not standard, but it works ok in every browser but firefox (in FF too).

Iterating over the elements

So we have all the elements now as a NodeList and we want to go through all of them applying the colorful outline. But wait, what the heck is used in our code?

NodeLists seems like Arrays, you can access to their nodes using brackets, and you can check how many elements it contains using the property length, but they doesn’t implement all the methods of the Array interface, so using $$('*').forEach will fail. In Javascript there are several objects that look like arrays but they are not, like the arguments variable inside functions, and we have here a very useful pattern to handle with them: Calling array methods on no-array objects as NodeLists is possible using the Function’s methods call and apply. I wrote about those functions some months ago, they execute a function using the first parameter as the object this inside of the function

The one-liner is using [].forEach.call instead of Array.prototype.forEach.call to save some bytes ( another nice trick yeah? ) calling the method in the Array object []. This would be equivalent to $$('*').forEach if $$('*') value was an Array.

If you have a look at the comments again, there are some people who use for(i=0;A=$$('*');) instead to make the code shorter. It works, but it is leaking global variables, so if you want to use the code out of the console, you better get a clean enviroment using

If you use it in the browser’s console it doesn’t really matter, the variables i and A will be available there since you are declaring them there.

Assigning colors to the elements

To make the elements have that nice border, the code is using the CSS property outline. In case you don’t know, the rendered outline is out of the CSS box model so it doesn’t affect the size of the element or its position in the layout, so it is perfect for this purpose. It’s syntax is like the one used for the border property, so it shouldn’t be difficult to understand this part:

What  is interesting is how the color is defined:

Scary uh? Sure. I am not a bit-wise operations expert, so this is the part I liked the most, because it let me learn a lot of new stuff.

What we want to achieve is a hexadecimal color like white FFFFFF or blue 0000FF or… who knows… 37f9ac. Non super-human people, like me, is used to work with decimal numbers, but our beloved code knows a lot about hexadecimal ones.

First thing it can teach us is how to convert a decimal number to hex using the method toString for integers. The method accepts a parameter to convert a number to a string using a base number of characters. If the parameter is not used, 10 characters are used (0…9, hence, decimal numbers), but you can use whatever other base:

The other way around, you can convert hexadecimal string to decimal numbers using the second parameter of the parseInt method:

So we need a random number between 0 and ffffff in hexadecimal, that is parseInt("ffffff", 16) == 16777215 and 16777215 is exactly 2^24 - 1.

Do you like binary maths? If not, you will be ok knowing that 1<<24 == 16777216 (try it in the console).

If you like them, you need to know that every time that you add a 0 to the right of a 1 you are doing performing the 2^n operation, being n the number of 0s you add.

The left shift operation x << n adds n 0s to the binary representation of the number x, so 1<<24 is a short way of saying 16777216, and doing Math.random()*(1<<24) we get a number between 0 and 16777216.

We are not ready yet, because Math.random return a float number, and we need only the whole part. Our code use the tilde operator to get so. Tilde operator is used to negate a variable bit by bit. If you don’t know about what I am talking about, here it is a good explanation: Javascript’s tilde operator.

But the code doesn’t care about bitwise negation, it uses the tilde because the bitwise operations discard the decimal part of a float number, so bitwise-negation applied twice is a short way of writing parseInt:

Again, if you go to the gist and have a look at the comments you will realize that people there is using a shorter version to get the parseInt result. Using the bitwise OR operator you can get rid of the decimal part of our random number

Or operator is the last to be used in a operation so the parenthesis are not needed anymore. Here it is the precedence of javascript operators in case you are interested in having a look.

Finally we have our random number 0 and 16777216, our random color. We just need to turn it to a hexadecimal string using toString(16) to make it work.

Last thoughts

Being a programmer is not easy. We are used to code like crazy and sometimes we don’t realize about how much knowledge is needed to do what we do. It takes a long long time to learn and internalize all the concepts that we use in our job.

I wanted to highlight the complexity of our job because I know that programmers are usually underestimated, ( especially in my country, Spain ) and it is nice to say ocassionally that we are really worthy and a key part of most of companies nowadays.

If you understood the one-liner code at first sight you can feel proud of yourself.

If not, but you have reach this point of the article, don’t worry, you will be able to write lines like that soon, you are a learner!

If you thought tl;dr at the second line of the article but you are reading this, you are really weird, but your thoughts are also welcome in the comments section below : )


Let’s push your website a bit further

My name is Javier Márquez and I have more than 10 years of web programming and web designing experience. If you have a difficult development to complete, maybe you can stop by and see what I can do for you. You can find me on and Twitter.

69 Comments - Leave yours

  • Svetlana Linuxenko

    This color randomizer (~~(Math.random()*(1<<24))).toString(16) is awesome !

    • Javi Marquez

      Indeed! In the original gist there is an even nicer way of getting the color:

      • Conrad Kleinespel

        That looks so much easier. Any difference with the one from Addy Osmani? Seems like it will just generate random HEX on 6 chars too, after all.

        • Alex Haan

          Technically the slice option is better, because 0|Math.random()*(1<<24).toString(16) can result in a hexadecimal string of length other than 6 (or 3). Those strings are invalid (at least in my Firefox) color values, so the outline would not have a color set. Padding with zeroes would work of course. But I don’t see a short way of doing that.

          Though there is a miniscule chance that Math.random() returns a short float, which would result in the slice(-6) containing the decimal point, also making that an invalid color string.

          • Javi Marquez

            Unfortunatelly for this task, Math.random also can return numbers like 0.4, so slice option also can generate invalid colors. You will need to pad it or use the hsl colors version that is in the original gist.

          • Fredric Rylander

            Actually there is a very simple and short way of padding the result with zeroes — just append them as a string before using the slice operation:

            (Math.random().toString(16)+'0000000').slice(2, 8)

            The intermediate result must be padded with at least seven characters since Math.random() may return zero.

  • Nate Ferrero

    Make your life awesome:

    setInterval(function () { [].forEach.call($$("*"),function(a){
    a.style.outline="2px solid #"+(~~(Math.random()*(1<<12))).toString(16) }, 5);
    }, 100)

    • Javi Marquez

      Geocities is back!!! Yeaah! I will create a chrome extension and apply it automatically to every website :D

    • Jason

      Yeah, that’s great! Takes me back to the 90s!


    • Pon3y

      Epilepsy ?
      setInterval(function () { [].forEach.call($$(“*”),function(a){
      a.style.backgroundColor=”#”+(~~(Math.random()*(1<<12))).toString(16) }, 5);
      }, 100)

  • Great article! I like it very much, I have learnt a couple of things interesting. Every day there is something new to learn from Javascript, and I have been working with JS since 8 years ago.

    About Spanish developers, I agree with your opinion. Best regards from Madrid.

  • The algorithm is clever, indeed I learned a lot with just one line of code. Thanks man!

  • hacedor91

    Great Explanation ! Great Article !

  • Took the oneliner, swapped $$ for document.querySelectorAll, and arrived at this bookmarklet:

    javascript:[].forEach.call(document.querySelectorAll(“*”),function(a){a.style.outline=”1px solid #”+(~~(Math.random()*(1<<24))).toString(16)})

  • jscoop

    this is cool, but writing one-liner as such greatly reduces its readability, dont you think

  • Gerard

    Nice one! Thanks for sharing.

  • imanzuk

    Really nice. Thanks for the great explanation.

  • Anton

    Here’s a nice bookmarklet that achieves a similar effect. :) thanks for breaking down this function to pieces.

  • 叫我钱了个浅


  • CrimX

    Tiny mistake:

    > What is interesting is how the color is defined:
    > ~~(Math.random()*(1<<24))).toString(16)

    The open parenthesis on the left is missed:

  • I really enjoyed the article and explanation, but this is nice as general knowledge. I strongly recommend against such code when you are working on a project with other people, or when you know that in the future someone else will need to maintain your code. This kind of code and similar, usually costs a lot of time, because it’s hard to understand, and the cost is higher than the benefit, in the long run.

  • Havvy

    Just because you can use ~~ for parseInt doesn’t mean you should. Coding is a social activity, and abusing operators to do unrelated tasks makes code reading harder for everybody.

    • RaphaelDDL

      Of course you shouldn’t. But on this self-contained, meant to be smaller as possible code, that is okay.

      On production code is not cool to change from parseInt to ~~, specially with data you receive from somewhere else.

      If you receive a float with leading zero it will throw a SyntaxError, same for 0|.
      And if you for some reason you expect a float but receive an int with leading zero, it will work as parseInt without radix, that is, ~~ and 0| will return octal.

      Therefore it’s use is very situational.

  • Surendra

    You made my day. Thanks a lot!

    I always want all the articles or tutorial on the internet to explain the way you did. Thanks again :)

  • piotrekbass

    I think these one could a start of series of articles about one line of code. Would you mind to write such series?

  • Everything is fine but i am unable to get why function is using $$ instead of $.
    Because i hav’nt used $$ till now to select DOM elements.Can u please provide clarification on it?

    • Javi Marquez

      This code is meant to be used in the browser’s console and without jQuery. In the console, the $ is also available to select nodes, but there are a lot of chances that the current page has overriden the variable $ using some library, like jQuery or MooTools. Using $$ we have more chances of using browser node selection.

      Never use $$ outside the console, it won’t work unless you are using MooTools.

    • Scott

      parseInt is not doing the same thing the other methods are doing. For exlampe, Number( 2px ) is NaN, but parseInt( 2px , 10) is 2.The key difference is that Number (and the implicit conversions) will try to convert the whole thing, and if they fail will return NaN, while parseInt will parse as much as it can and return that.

  • Raju Maisnam

    Awesome article, though I could understand what the code could do, your article explained things a lot more in depth, hope I can reach such level soon

  • Kshitij Tripathi

    Awesome article. Learnt the usage of several components of JS and CSS through this one line of code snippet.

  • calle

    interesting article.

    small typo: “…and doing Math.random()*/(1<<24) we get…" needs to be "…and doing Math.random()*(1<<24) we get…" (remove the slash)

    • Javi Marquez

      Fixed, thanks for pointing it out.

    • Geminis

      Please note that all logical ooeratprs like ~, , >>>, & and | internally operates on a 32 bit integer, while Numbers in javascript is 64 bit floats. Try to convert 2147483648 and notice the sign.Check out the jsperfs page for other variants.However, I’m not sure if the numbers given by jsperf is accurate in this case. When using randomized data I don’t get that much of a difference between the different methods. I would like to see the code that jsperf is running. I think there might be a hidden compilation that we don’t see:Try this:Function( return ~~(1*’12 ) ).toString();In firefox I get:function anonymous() { return 12;}Notice that the expression has been compiled to 12. No wonder that it is faster!

  • olivier

    Using <> to multiply/divide by powers of 2 was a very well known trick in C or assembly back to the times when you couldnt waste one cpu cycle. You also used to write xor ax, ax to optimize registers cleaning… Memories, memories… js is the web’s assembly.

  • Tobi Reif

    This also works in some browsers:

    for(var a of $$(“*”)){


  • AJ Farkas

    Great breakdown. I had fun breaking your page with [].forEach.call – I’ve been looking for a way to call a forEach loop on nodes.

  • Benjamin

    Good share!

    • > In one of the tests that where added to your jsperf there was one that did “0+’12′”. That aclaltuy returns a string.That was me, even if I should have known better: I wanted to test if binary plus suffers from the same poor performance in Firefox as unary plus, but forgot about the fact that Javascript’s plus genrally doesn’t force numeric conversions. I blame it on too much Perl coding .I couldn’t see any pattern in the set of operators which are fast (eg ~~’12 , ’12 -0, ’12 <<0) and those which aren't (eg +'12', '12'|0).

  • yongba

    nice one,thank you for sharing

  • Kelly

    Thanks for the article, it was a fun and insightful read. Please consider that some of your audience aren’t always male – so the conclusion where said ‘man’ was off-putting to me: “If not, but you have reach this point of the article, don’t worry man, you will be able to write lines like that soon, you are a learner!”

  • leega0

    very useful ,as a programmer where in China,i want say 谢谢

  • Kevin

    This is a very nice post because it demonstrates an original and inspired method of learning!

  • Nadav

    Great written and designed article.

  • jane-clover

    Nice one,although some parts make me puzzled

  • TheRegge

    This is great stuff – more! More!

  • Mohamed

    We made the first one liner code of Addy Osmani a Bookmarklet: Easier to use ;)

  • Miguel Mota

    You didn’t really explain how you got 24 as the base log. But for those wondering, here is a way:

    function getBaseLog(x, y) {
    return Math.log(y) / Math.log(x);

    getBaseLog(2, parseInt(‘ffffff’, 16) + 1) // 24

  • Frankie Bagnardi

    One problem is that (~~(Math.random()*(1<<24))).toString(16) can give something like "6356f" or even "1" (note: length is less than 6). This causes the style to be considered invalid, and is ignored by the browser. This causes about 6% of elements to be unstyled. You need to left-pad with 0s.


  • spidermanzy

    I have learned much.

Leave a reply

contact meAnything related to web development like javascript and CSS to create responsive designs, or PHP and node.js to make your website work properly, is my pleasure. If you have an interesting project in mind, I can help to make it real.