You know a site has its shit together when…

By David Gilbertson Message

Whenever I see z-index: 9999 I gently but firmly bring my palm to my face. There is an assumption here that no one will ever think of a number bigger than 9999.

If you do this, I’m about to blow your mind:

The proper way to do it is super-simple, a set of z-index variables:

$z-index-header: 1;
$z-index-menu: 2;
$z-index-hamburger: 3;
$z-index-modal: 4; // then something like this
.my_modal { z-index: $z-index-modal;
And if you later want to add something in between two z-indexes, you just bump them all up, because you never ever set z-indexes directly in your CSS.
$z-index-header: 1;
$z-index-menu: 2;
$z-index-hamburger: 3;
$z-index-menu-nav: 4; // some new z-index that I need
$z-index-modal: 5; // then something like this
.my_modal { z-index: $z-index-modal;
As you may know, when you go to jQuery plugin school, they teach you to write code that interferes with the host site as much as possible. So if you want to keep that jQuery image slider, you’ll need higher z-indexes to override its 9999.
$z-index-header: ∞ + 1;
$z-index-menu: ∞ + 2;
$z-index-hamburger: ∞ + 3;
$z-index-modal: ∞ + 9999; // then something like this
.my_modal { z-index: $z-index-modal;
Fun, slightly related fact: Infinity is an actual JavaScript global property.

[serious face] to make sure a plugin behaves, put it in a new stacking context. For example, wrap your jQuery slider in a div with position: relative and z-index: 1 (or whatever). The 9999 then is only in the context of that div and it can’t ‘break out’ and sit above your well-behaved modal with a z-index of 4 (effectively you’re making the problem element’s z-index 1.9999).

I’m sure there’s some historical reason for valuing short variable names. Evolutionary psychology (aka guessing) probably has a hypothesis. Maybe in the past our ancestors had to pay by the letter and when the great depression hit people started naming variables as though vowels had leprosy.

function cfcm(s, ss) { if (ss.length < 3) return ''; if (s.includes(ss)) return ''; for (let i = 1; i < ss.length; i++) { const fp = ss.substring(0, i); const sp = ss.substring(i); const wlr = new RegExp(`${fp}.${sp.substring(1)}`); if (wlr.test(s)) { return s.replace(wlr, ss); } const elr = new RegExp(`${fp}.${sp}`); if (elr.test(s)) { return s.replace(elr, ss); } if (sp !== 'mail') { const mlr = new RegExp(`${fp}{0}${sp}`); if (mlr.test(s)) { return s.replace(mlr, ss); } } const sl = [ ss.substring(0, i - 1), ss.charAt(i), ss.charAt(i - 1), ss.substring(i + 1), ].join(''); if (s.includes(sl)) { return s.replace(sl, ss); } } return '';

That’s great, you only took up 24 lines. Gold star, ya dope.

If your site has its shit together, it will use proper variable names, and have more comments than a TEDx video on feminism.

Future-you will look back at current-you with pride, not the shame that they are currently on course for.

function checkForCloseMatch(longString, shortString) { // too many false positives with very short strings if (shortString.length < 3) return ''; // test if the shortString is in the string (so everything is fine) if (longString.includes(shortString)) return ''; // split the shortString string into two at each postion e.g. g|mail gm|ail gma|il gmai|l // and test that each half exists with one gap for (let i = 1; i < shortString.length; i++) { const firstPart = shortString.substring(0, i); const secondPart = shortString.substring(i); // test for wrong letter const wrongLetterRegEx = new RegExp(`${firstPart}.${secondPart.substring(1)}`); if (wrongLetterRegEx.test(longString)) { return longString.replace(wrongLetterRegEx, shortString); } // test for extra letter const extraLetterRegEx = new RegExp(`${firstPart}.${secondPart}`); if (extraLetterRegEx.test(longString)) { return longString.replace(extraLetterRegEx, shortString); } // test for missing letter if (secondPart !== 'mail') { const missingLetterRegEx = new RegExp(`${firstPart}{0}${secondPart}`); if (missingLetterRegEx.test(longString)) { return longString.replace(missingLetterRegEx, shortString); } } // test for switched letters const switchedLetters = [ shortString.substring(0, i - 1), shortString.charAt(i), shortString.charAt(i - 1), shortString.substring(i + 1), ].join('');

More scrolling, more understanding.

An up-to-date readme. A readme worth reading. A readme that doesn’t assume the reader knows what you know.

You know your site has its shit together if you can email a link to the repo to some new QA person and they can get your site running without asking you a single question.

If code changes and the readme doesn’t get updated, that commit doesn’t make it through code review.

OK, six is asking a bit much. But at least there are less than 25. If you have 30 different grays, take 10 minutes one Friday morning and fix that.

I might as well float the idea here. I think we should all be doing Tidy Fridy. Every Friday, tidy up one thing that you’ve been meaning to get around to. Maybe a little refactor, DRYing up some code, renaming that function that doesn’t make sense any more.

Tidy code is important. And if it’s not important to you, it is important to someone you love.

As soon as you let one lint error into production, you open the floodgates. You give everyone tacit permission to be a little lazy, and before you know it you’ve got single quotes and double quotes living together like cats and dogs.

Mass hysteria.

So yes, a site that has its shit together runs linting for JavaScript and Sass/Less/CSS on the build server and the build will fail on any error.

Bonus tip, if your new to linting and scared off by the current number of errors, eslint takes a --fix flag that does a pretty good job.

If you shuddered at me typing “your” instead of “you’re” in the previous sentence, you now know how I feel when I see a space between a function name and it’s opening parentheses.

“oldIndexDeleteMe.js” makes me quiver, in a bad way. If you’re afraid to delete a file, then your code shouldn’t be going into production. You have git history if ever you want the file back.

Delete things when they are no longer used. Don’t be like Brian.

Much the same as unused files, if you don’t need the code, delete it. If you only need the code sometimes (maybe some performance logging) then put it behind a flag. Commenting out code is like putting a blanket over your goldfish that just passed away. It’s of no use to you anymore, just get rid of the poor thing and be done with it.

OK that analogy was strained and I apologise, but I miss little Fat Boy Swim and, in a way, writing about him brings him back to life.

Rest in peace Fat Boy, rest in peace.

A TODO poo is a TODO that has just been dropped in the code and left there like it’s someone else’s problem now.

If your TODO doesn’t have a reference to who will TODO it and when it will be TODONE, then say TOODLE-LOO to that TODO poo. (I’m like a scatological Dr Seuss.)

If you want to be properly organised, add a task to your Jira/Trello/whatever, reference that task’s URL from the TODO, and reference the TODO from the task. That way when someone picks up that task, they know to go looking for the TODO, and if someone does the TODO, they know to go and update the task.

As always it’s just as much the job of the code reviewer to not let these things through into production.

This one’s a hard sell. I think it’s a great idea, everyone else I’ve ever met thinks it’s dumb. It’s a lot like my t-shirt with the word t-shirt written on it. But trust me, margins collapsing on each other are a pain in the you-know-what (ass).

By only ever using margin-bottom, every element is in charge of how much space there should be below it. It makes just as much sense to stick to margin-top. But if you set margin-top on some elements and margin-bottom on others, then when they come together they might be touching, depending on their order. That’s madness.

If you define half/half top and bottom, then if you have two of these elements on top of each other, the margins will collapse and you’ll have half the spacing you wanted…

…maybe. The margins will actually collapse depending on some rules that you may not be aware of. You add a 1px bottom border to an element and suddenly your page grows by half a foot.

There are two reasons a CSS reset is a must. Firstly, different browsers have different defaults. For example button padding is different in pretty much every browser, so if you don’t want to see any weird wrapping, make sure you reset the padding to something sane (and don’t go to an Iggy Azalea concert).

The second reason is that browsers are opinionated about margin/padding for certain text elements. If you don’t reset, say, the <h1> tag to have a margin of zero, you will find yourself resetting it in 50 different places, or worse, selecting a tag based on styling rather than semantics. Your heading tags should represent the structure of the content on your site, not which default size/margin looks best.

I use Eric Myer’s reset.css because it lets me build my styles up on top of it (that is, it ‘unstyles’ everything). If you don’t plan to specify the exact styles for everything in your site then you may want something like sanitize.css or normalize.css.

/* v2.0 | 20110126 License: none (public domain)
*/ html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary,
time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline;
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block;
body { line-height: 1;
ol, ul { list-style: none;
blockquote, q { quotes: none;
blockquote:before, blockquote:after,
q:before, q:after { content: ''; content: none;
table { border-collapse: collapse; border-spacing: 0;

So there we have it: The Right Way To Do Things that I’m quite certain everyone will agree with.

Thanks for reading!