Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
108 byte CSS Layout Debugger

CSS Layout Debugger

A tweet-sized debugger for visualizing your CSS layouts. Outlines every DOM element on your page a random (valid) CSS hex color.

One-line version to paste in your DevTools

Use $$ if your browser aliases it:

~ 108 byte version

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

Using document.querySelectorAll:

~ 131 byte version

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

~73 byte code-golfed version by @xem

$$('*').map(A=>A.style.outline=`1px solid hsl(${(A+A).length*9},99%,50%`)

~66 byte code-golfed version by @daliborgogic

$$('*').map((A,B)=>A.style.outline=`1px solid hsl(${B*B},99%,50%`)

If you're looking for a proper version that uses a set color per tag type, check out pesticide.io.

Screenshots

Tested from Chrome DevTools:

Tested from Firefox DevTools:

Tested from WebKit Nightlies (Safari):

Tested in IE:

Thanks to gregwhitworth for verifying.

Tag Specific Layout Debugging In 82 Bytes

My original implementation outlined each DOM element on the page with a random (valid) hex color.

Thanks to the work by @aemkei, @p01, @sindresorhus and other commenters, we now have an even shorter version (108 bytes golfed down to 82) that uses a specific hex color per tag name. This lets you visually group elements similar to how pesticide.io does.

for(i=0;A=$$("*")[i++];)A.style.outline="solid hsl("+(A+A).length*9+",99%,50%)1px"

Preview:

Thanks for the awesome help improving this folks <3

function(a){ // Supply a valid selector (e.g '*' for wildcard)
[].forEach.call( // Treat Nodelist as an Array (fewer bytes than Array.prototype.forEach.call(...);)
// Gets the prototype of Array & uses call to execute the function on the NodeList.
document.querySelectorAll(a), // Query DOM for elements matching the supplied selector
// (For 108 bytes, use $$() as Chrome, Safari & FF expose it in DevTools)
function(b){
b.style.outline = "1px solid #" + // Set the selector outline
(~~(Math.random()*(1<<24))) // Pick a valid random CSS hex color
.toString(16)}) // Convert to a base 16 number. BOOM.
}
function(a){return [].forEach.call(document.querySelectorAll(a),function(b){b.style.outline = "1px solid #" +(~~(Math.random()*(1<<24))).toString(16)});}
{
"name": "CSSLayoutDebugger",
"description": "A helper for debugging CSS layouts",
"keywords": [
"css",
"layout",
"debugger"
]
}
<!DOCTYPE html>
<title>CSS Layout Debugger</title>
<div>I am element</div>
<div>I am element</div>
<div>I am element</div>
<div>I am element</div>
<div>I am element</div>
<div>I am element</div>
<div>I am element</div>
<div>I am element</div>
<div>I am element</div>
<div>I am element</div>
<div>I am element</div>
<div>I am element</div>
<div>I am element</div>
<div>I am element</div>
<div>I am element</div>
<div>I am element</div>
<script>
var myFunction = function(a){ // Supply a valid selector (e.g '*' for wildcard)
[].forEach.call( // Treat Nodelist as an Array (fewer bytes than Array.prototype.forEach.call(...);)
// Gets the prototype of Array & uses call to execute the function on the NodeList.
document.querySelectorAll(a), // Query DOM for elements matching the supplied selector
// (For 110 bytes, use $$() as Chrome, Safari & FF expose it in DevTools)
function(b){
b.style.outline = "1px solid #" + // Set the selector outline
(~~(Math.random()*(1<<24))) // Pick a valid random CSS hex color
.toString(16)}) // Convert to a base 16 number. BOOM.
}
myFunction('*');
</script>
<!-- quick JSBin:http://jsbin.com/soseq/2/edit -->
@addyosmani

This comment has been minimized.

Copy link
Owner Author

@addyosmani addyosmani commented Sep 26, 2014

@sindresorhus was able to get my implementation down to 98 bytes and 106 bytes:

First option (98 - leaky globals, but works):

a=$$('*');for(b=0;c=a[b++];)c.style.outline='1px solid #'+(~~(Math.random()*(1<<24))).toString(16)

Second option (106 - contained):

[].forEach.call($$("*"),function(a){a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)})```
@addyosmani

This comment has been minimized.

Copy link
Owner Author

@addyosmani addyosmani commented Sep 26, 2014

@p01

This comment has been minimized.

Copy link

@p01 p01 commented Sep 26, 2014

The [].forEach.call(document.querySelectorAll(a),...) construct is too verbose here.
You can save 8 bytes using document.querySelectorAll(a);for(b=0;a[b];)a[b++]...

Generating the color can be shorten by 5 bytes using: Math.random().toString(16).slice(-6)

This gives us the following 132 byter:

    function(a,b){a=document.querySelectorAll(a);for(b=0;a[b];)a[b++].style.outline="1px solid #" +Math.random().toString(16).slice(-6)}

HTH, I tested in Chrome and Firefox devtools

@gmetais

This comment has been minimized.

Copy link

@gmetais gmetais commented Sep 26, 2014

Excellent!

But can sometime fail to give a valid #RRGGBB color code:

(~~(Math.random()*(1<<24))).toString(16)
"be26f"
@kloetzl

This comment has been minimized.

Copy link

@kloetzl kloetzl commented Sep 26, 2014

Two byte can be saved by using 0|… instead of ~~(…): (0|Math.random()*(1<<24))

@aemkei

This comment has been minimized.

Copy link

@aemkei aemkei commented Sep 26, 2014

Could be 92 bytes:

for(i=0;A=$$("*")[i++];)A.style.outline="1px solid #"+(0|Math.random()*(1<<24)).toString(16)

or 72 if using rainbows:

for(i=0;A=$$("*")[i++];)A.style.outline="1px solid hsl("+i*9+",99%,50%)"
@mathiasbynens

This comment has been minimized.

Copy link

@mathiasbynens mathiasbynens commented Sep 26, 2014

You could use document.all instead of document.querySelectorAll('*').

@addyosmani

This comment has been minimized.

Copy link
Owner Author

@addyosmani addyosmani commented Sep 26, 2014

@aemkei was able to successfully craft two flavors that would display a fixed color per tag name rather than using a random hex color for every element:

for(i=0;A=$$("*")[i++];)A.style.outline="1px solid hsl("+(A+A).length*9+",99%,50%)"

and

for(i=0;A=$$("*")[i++];)A.style.outline="1px solid hsl("+parseInt((A+"")[12],36)*9+",99%,50%)"

This effectively gives us the same effect you would see on pesticide.io. Nice work :)

@sindresorhus

This comment has been minimized.

Copy link

@sindresorhus sindresorhus commented Sep 27, 2014

@addyosmani That A+A and A+"" won't work as document.querySelector('a')+'' returns the url, which means most links will have different color.

Oh, and you can put the 1px at the end to save 1 char.

Maybe something like:

for(i=0;A=$$("*")[i++];)A.style.outline="solid hsl("+parseInt(A.tagName,36)+",99%,50%)1px"
@aemkei

This comment has been minimized.

Copy link

@aemkei aemkei commented Sep 27, 2014

@sindresorhus: Nice one! That makes the color quite unique per tag name.

Here is my 82 bytes version:

for(i=0;A=$$("*")[i++];)A.style.outline="solid hsl("+(A+A).length*9+",99%,50%)1px"
@pvdz

This comment has been minimized.

Copy link

@pvdz pvdz commented Sep 27, 2014

jQuery has a plugin for random color. $x.randColor() would be much shorter.

@pvdz

This comment has been minimized.

Copy link

@pvdz pvdz commented Sep 27, 2014

for(i=0;A=$$("*")[i++];)A.style.outline="solid 1px#"+((A+0).length*7+'')
@aemkei

This comment has been minimized.

Copy link

@aemkei aemkei commented Sep 27, 2014

@qfox: That works good but is not as colorful. Ps: can be reduced to 67 bytes:

for(i=0;A=$$("*")[i++];)A.style.outline="solid 1px#"+(A+0).length*7
@ashumeow

This comment has been minimized.

Copy link

@ashumeow ashumeow commented Sep 27, 2014

nice! ;)

@pvdz

This comment has been minimized.

Copy link

@pvdz pvdz commented Sep 28, 2014

@aemkei oh yeah, silly cruft. i was in a hurry :p maybe not as colorful, but it sometimes may also just be black when the number is >999. ohwell, such sacrifices are to be made in golfing! :p

@doginthehat

This comment has been minimized.

Copy link

@doginthehat doginthehat commented Sep 29, 2014

Very nice.

Works well as bookmarklet too, but have to use document.querySelectorAll instead of $$

This works:

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

This doesn't:

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

The $$ version throws a $$ is not defined reference error for some reason when used as a Bookmarklet.

I'm in chrome

@tomayac

This comment has been minimized.

Copy link

@tomayac tomayac commented Sep 29, 2014

Just pointing out the obvious: the bookmarklet version is

javascript:(function(){for(i=0;A=document.querySelectorAll("_")[i++];)A.style.outline="1px solid hsl("+(A+A).length_9+",99%,50%)";})();

I named it "CSS Outlinify". Thanks all, super useful!

@yodairish

This comment has been minimized.

Copy link

@yodairish yodairish commented Sep 29, 2014

sadly, I work on some projects with iFrames, so there is need some additional, like:
javascript:function f(w){[].forEach.call(w.document.querySelectorAll(""),function(a){a.style.outline="1px solid #"+(~~(Math.random()(1<<24))).toString(16)});[].forEach.call(w.frames, function(b){f(b)})}f(this)

@flenczewski

This comment has been minimized.

Copy link

@flenczewski flenczewski commented Sep 29, 2014

@aemkei: 51 bytes (without colors):

for(i=0;A=$$("*")[i++];)A.style.outline="1px solid"
@j0lv3r4

This comment has been minimized.

Copy link

@j0lv3r4 j0lv3r4 commented Sep 30, 2014

This may be a different way but I do like this on CSS

* { background-color: rgba(0,0,0,0.1); }

Without colors.

@heldr

This comment has been minimized.

Copy link

@heldr heldr commented Sep 30, 2014

I wrote a togglable bookmarklet based on the results already reached

javascript:!function(a){for(a.__CSSDebug__=!a.__CSSDebug__,i=0;A=document.all[i++];)A.style.outline=a.__CSSDebug__?"solid hsl("+9*(A+A).length+",99%,50%)1px":null}(window);
@addyosmani

This comment has been minimized.

Copy link
Owner Author

@addyosmani addyosmani commented Oct 7, 2014

This version should play better with Polymer and Custom Elements (94 bytes):

for(i=0;A=$$("html /deep/ *")[i++];)A.style.outline="solid hsl("+(A+A).length*9+",99%,50%)1px"
@JotFX

This comment has been minimized.

Copy link

@JotFX JotFX commented Oct 10, 2014

Hi guys, some hours ago I twittered another version, but that relied on the 108 byte version. I tinkered with the golfed down version above and now its 79 bytes and should still work fine:

for(i=0;A=$$("*")[i++];)A.style.outline="1px solid #"+(i*999%4096).toString(16)

The coloring should be as distinguishable as the random version. Not sure if the first element gets a valid color coding.

@markyun

This comment has been minimized.

Copy link

@markyun markyun commented Oct 11, 2014

mark

@amirouche

This comment has been minimized.

Copy link

@amirouche amirouche commented Feb 8, 2015

modified the "every element gets a color" to use hsl:

[].forEach.call(
    document.querySelectorAll("*"),
    function(a){
        a.style.outline="1px solid hsl(" + Math.random() * 360 +", 70%, 70%)";
    }
)
@shmdhussain

This comment has been minimized.

Copy link

@shmdhussain shmdhussain commented Feb 7, 2016

Once I enabled the outlines, how could I undo it? Thanks For any help in advance.

@jbmartinez

This comment has been minimized.

Copy link

@jbmartinez jbmartinez commented Feb 8, 2016

@shmdhussain reload/refresh the page

@addyosmani

This comment has been minimized.

Copy link
Owner Author

@addyosmani addyosmani commented Sep 26, 2016

Reloading the page will remove the outlines :)

@lukechilds

This comment has been minimized.

Copy link

@lukechilds lukechilds commented Sep 26, 2016

81 bytes if es2015 is allowed.

for(i=0;A=$$("*")[i++];)A.style.outline=`solid hsl(${(A+A).length*9},99%,50%)1px`
@lukechilds

This comment has been minimized.

Copy link

@lukechilds lukechilds commented Sep 26, 2016

Actually, make that 77.

$$("*").forEach(A=>A.style.outline=`solid hsl(${(A+A).length*9},99%,50%)1px`)
@addyosmani

This comment has been minimized.

Copy link
Owner Author

@addyosmani addyosmani commented Sep 26, 2016

Nice golfing, @lukechilds. On first try, seems to be working well with the latest ES2015 version:

screen shot 2016-09-26 at 3 41 12 pm

Need to do a little work comparing effectiveness of the randomisation approaches on-thread, but imagine that won't matter hugely to some folks.

@lukechilds

This comment has been minimized.

Copy link

@lukechilds lukechilds commented Sep 26, 2016

@addyosmani 74 bytes. We're almost at half a tweet.

for(A of $$('*'))A.style.outline=`solid hsl(${(A+A).length*9},99%,50%)1px`

Ok, I think I'm done.

@zak905

This comment has been minimized.

Copy link

@zak905 zak905 commented Sep 27, 2016

Cool! this should be integrated into chrome

@JyotiDuhan

This comment has been minimized.

Copy link

@JyotiDuhan JyotiDuhan commented Sep 28, 2016

Hi,
Can anyone tell me what is the purpose of using this? I loved to see my page layout in multiple color blocks though :)

@xem

This comment has been minimized.

Copy link

@xem xem commented Oct 12, 2016

73b, did I win?

$$('*').map(A=>A.style.outline=`1px solid hsl(${(A+A).length*9},99%,50%`)
@shockw4ver

This comment has been minimized.

Copy link

@shockw4ver shockw4ver commented Nov 29, 2016

It's likely to build a simple plugin integrated into browser and make it easy to clear a page.
Excellent!

@daliborgogic

This comment has been minimized.

Copy link

@daliborgogic daliborgogic commented Jul 29, 2017

# ~66 bytes
$$('*').map((A,B)=>A.style.outline=`1px solid hsl(${B*B},99%,50%`)
# ~64 bytes but not so colorful
$$('*').map((A,B)=>A.style.outline=`1px solid hsl(${B},99%,50%`)

rainbow

@streamich

This comment has been minimized.

Copy link

@streamich streamich commented Sep 8, 2017

57 bytes:

[...document.all].map(a=>a.style.outline="1px solid red")
@nitinja

This comment has been minimized.

Copy link

@nitinja nitinja commented Oct 27, 2017

I think we should try to minimize the number of outlines. More dom elements present on the page, slower it gets.

@addyosmani

This comment has been minimized.

Copy link
Owner Author

@addyosmani addyosmani commented Oct 31, 2017

@daliborgogic Nice work further code-golfing! Looks pretty alight :)

image

@daliborgogic

This comment has been minimized.

Copy link

@daliborgogic daliborgogic commented Dec 21, 2017

@addyosmani Thank you : )

@daliborgogic

This comment has been minimized.

Copy link

@daliborgogic daliborgogic commented Dec 21, 2017

@nitinja I agree, but this is not for production.

@boi23

This comment has been minimized.

Copy link

@boi23 boi23 commented Aug 20, 2018

Im havin trouble with my css can u help me

@adriadrop

This comment has been minimized.

Copy link

@adriadrop adriadrop commented Jan 11, 2019

I made a module for drupal inspired by this code https://www.drupal.org/project/css_debuger
I added option to show/hide boxes with alt+c

@shinsenter

This comment has been minimized.

Copy link

@shinsenter shinsenter commented Mar 1, 2019

Very useful. String interpolation does not work on IE.

@shinsenter

This comment has been minimized.

Copy link

@shinsenter shinsenter commented Mar 1, 2019

Here is bookmarklet version:

javascript:[].slice.call(document.querySelectorAll("*")).map(function(l,e){l.style.outline="1px solid hsl("+(e*e)+",90%,50%)"})
@noobalex

This comment has been minimized.

Copy link

@noobalex noobalex commented Jan 13, 2020

Perhaps you need a bookmark to restore the layout

javascript:[].slice.call(document.querySelectorAll("*")).map(function(l,e){l.style.outline="none"})

@y4rr

This comment has been minimized.

Copy link

@y4rr y4rr commented Dec 27, 2020

Perhaps you'd like to have just one bookmarklet instead of two. And nicer colors.

Properly escaped code for the bookmarklet:

javascript:(function()%7B%5B%5D.slice.call(document.querySelectorAll(%22*%22)).map(function(l%2Ce)%7Bl._CSSDEBUG%3D!l._CSSDEBUG%3Bl.style.outline%3Dl._CSSDEBUG%3F%22solid%20hsl(%22%2B(l%2Bl).length*13%2B%22%2C45%25%2C55%25)0.1rem%22%3A%22initial%22%7D)%7D)()

Source:

javascript:[].slice.call(document.querySelectorAll("*")).map(function(l,e){l._CSSDEBUG=!l._CSSDEBUG;l.style.outline=l._CSSDEBUG?"solid hsl("+(l+l).length*13+",45%,55%)0.1rem":"initial"})
@dziku86

This comment has been minimized.

Copy link

@dziku86 dziku86 commented Feb 21, 2021

1 byte can be shaved with Q unit if you are not using Safari/IE:

$$('*').map((A,B)=>A.style.outline=`1q solid hsl(${B*B},99%,50%`)
@amir2mi

This comment has been minimized.

Copy link

@amir2mi amir2mi commented May 18, 2021

57 bytes:
[...document.all].map(a=>a.style.outline="1px solid red")

Hi, @streamich thanks! it is possible with CSS, the random color is the point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment