Create a gist now

Instantly share code, notes, and snippets.

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

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 -->
Owner

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)})```

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 commented Sep 26, 2014

Excellent!

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

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

kloetzl commented Sep 26, 2014

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

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%)"

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

Owner

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

@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 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"

qfox commented Sep 27, 2014

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

qfox commented Sep 27, 2014

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

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

nice! ;)

qfox 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

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 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!

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)

@aemkei: 51 bytes (without colors):

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

thinkxl 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 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);
Owner

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"

MisterS 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 commented Oct 11, 2014

mark

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%)";
    }
)

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

@shmdhussain reload/refresh the page

Owner

addyosmani commented Sep 26, 2016

Reloading the page will remove the outlines :)

81 bytes if es2015 is allowed.

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

Actually, make that 77.

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

addyosmani commented Sep 26, 2016 edited

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.

@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 commented Sep 27, 2016 edited

Cool! this should be integrated into chrome

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 commented Oct 12, 2016

73b, did I win?

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

shockw4ver commented Nov 29, 2016 edited

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

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