Fear not, this isn’t another mildly aggressive blog post telling you that you’re inferior; I’m not here to tell you what you don’t know about web development.
I’m here to ask you … how do you know what you don’t know about web development?
Imagine a city or town you know well. Perhaps you’ve lived there your whole life. You know every street and alley, every nook and cranny, right? Of course not. No matter how well you know a place, there will surely be a stairwell, a doorway, an underground club that is kitted out like a train carriage that you weren’t aware of. But without walking every single street of the city all over again, how do you find these unknown places? The unknown is masked by the known, wrapped up and buried deep.
And it’s the same with web development: the more you know, the more arduous the task of finding out those last few nuggets of information. This is a problem.
This is a problem worth trying to solve.
But, I know all I need to know
If you think like this, that’s cool. I’m not a judgemental person and I think this is a totally valid, idiotic, reasonable view to have in life. You may stop reading now (I assume you were waiting for my permission) or carry on and I’ll see if I can’t change your mind.
Rather than have you sit through my rambling thoughts and a (spoiler) inconclusive ending, I’d like to throw in some maybe-useful information. Like a lollie bag at the opera.
And since I hate birds, I’d like to kill two of the little blighters with one stone. So in addition to this maybe-useful information, I also hope to get you interested in the problem, and even a little bit excited at the prospect of undiscovered nuggets.
And so, without further mountain dew, here’s a spattering of things I have discovered over the last little while.
JSON parse and stringify goodies
Did you know that JSON.parse() can do clever things when parsing? Imagine you get data from an API and it gives you the strings “true” and “false” rather than a boolean, and gives you a numeric cost value as a string with a dollar sign. We can use the JSON.parse() reviver to convert these.
Later in the code, when I show the result in the DOM, I convert it back to a string with JSON.stringify() and pass in additional parameters to get it to ‘pretty-print’ on the result tab.
String.replace takes a function
This one is like my green crocodile-skin jacket. I know it’s a good idea. I know that one day I’ll be glad that I have it, but for now I’m not exactly sure what to do with it. So it’s simply my green-jelly eating jacket because the untrained eye won’t spot any mishaps. And if you’ve seen me eat jelly…
Anyhoo, when using string replace, a function can be passed in as a second parameter that will be called for each match. My terrible, made up example is replacing backticks with alternating open and close <code> tags.
This is a great example of how knowledge differs from wisdom. I have known for a while that the currentColor keyword existed in CSS, I had that knowledge. But I wasn’t clever enough to realise that this is the best way to color icons made in SVG. I even wrote a whole blog post about Icons as React Components and passing in color as a prop. Stupid. No dinner for David tonight.
Now, since we all know that quantity trumps quality*, here are 21 other things that I haven’t bothered to do code samples for (some are old, some are quite new):
- You can use the CSS function attr() to access an element’s attribute for some reason.
- As I mentioned in another post, you can make the whole page editable by typing document.designMode = ‘on’ in the console.
- A MediaQueryList will emit an events when media query matches occur. They make a very faint trumpet sound too.
- There is a whole bunch of tags for user output, rather than just <pre> or <code>. Like <kbd> to represent keyboard strokes, and <var> to represent variables, and <samp> to represent sample output. And you are totally going to use those now because they’re semantic and that’s um, more accessible or something.
- You can do a dainty little transform: rotate(1turn). I tried transform: translateY(1twerk) and it didn’t do anything for me.
- text-align-last sets the alignment for the last line in a paragraph.
- There’s a presentation API just for sending content to a second screen. Isn’t that great?
- A <table> element has .insertRow() and .deleteRow() and other such methods.
- There’s a <details> element that expands collapses its contents (with some fairly ugly UI) via an open attribute.
- Event interfaces have handy constants. So if you want to know if the event you’re looking at is at the target phase, instead of checking if e.eventPhase === 2 you can instead use the more readable e.eventPhase === Event.AT_TARGET (if you type Event.AT_TARGET in the console, you’ll see it’s just a ‘2’)
- document.images gives you a list of all the images on the page. I don’t know why.
- You can programmatically call undo with document.execCommand(‘undo’)
- There’s a Node.contains() to see if one element contains another e.g. if (document.querySelector(‘.modal’).contains(e.target)) return;
- If you want to check that an element is a particular element based on a CSS selector: Element.matches(‘#my-list li:nth-of-type(2)’)
- The TreeWalker, NodeIterator, NodeFilter trio were incredibly useful, exactly once (as a way to traverse all the comments in the DOM, since comments are nodes just like any element).
- There’s an Element.classList.toggle(‘my-class’) method. You can pass it a boolean second parameter too, sort of.
- You can finally use forEach on a NodeList (in very modern browsers). E.g. document.querySelectorAll(‘img’).forEach(img => console.log(img.src))
- There is a helper for working with query parameters in URLs. E.g. new URLSearchParams(location.search).get(‘ sourceid’) would get the value of the ‘sourceid’ parameter.
- I will eat my nearest pet if you already knew what window.length returns.
- You can requestIdleCallback(myFunc) to get a function to run only when the browser is having a rest.
Did I learn you something with at least one of those? Was your reaction the same as mine: “Hey, neato! … I want more!”
OK that’s the end of the useful stuff, now for some outloud thinking about the solution I am planning…
I was reading html5test.com recently (as one does) and felt a tingling in my head meat. I shook me noggin to dislodge the feeling but it was wedged in good and proper. And it was turning into words.
“We need an html5test for humans!” I exclaimed as water overflowed the bath in which I was reading.
With html5-test-for-humans, rather than asking the browser if it knows about shadow DOM, or the MIDI API or the <details> element, we’ll ask a human. We’ll ask ourselves. And we’ll ask for everything.
We will need two things: data and UI.
We can’t just ask “do you know shadow DOM”. For the same reason we can’t just ask “do you know about <ol>”. I thought I knew all about <ol>, before I learned it has a start attribute if you want it to start at something other than 1.
If it’s worth doing this little project at all, it has to be atomic. All or nothing, as people say (up until now, every time I’ve heard someone suggest ‘all or nothing’, the latter has been by far the better option).
Okey dokey, we need to distill everything out there into a simple list. Every property, value, function, object, interface, event, method and data type in CSS, CSSOM, HTML, SVG, ECMAScript, the DOM, Web APIs, and NodeJS for good measure.
That’s going to be a mind-numbing task for someone.
As luck would have it, mind-numbing tasks are like catnip to me. I’ve finished with SVG (439 items), HTML (1,098 items) and CSS (1,215 items, spread across 32 specs!). I’m currently working on DOM, then there’s just Web APIs, ECMAScript and NodeJS left to go.
I would love to make this something that others find useful, but even if I’m the only person on earth who cares, it’s still been a worthwhile learning experience.
If you or I are going to go through a list of several thousand things, we want minimal effort. Which means giving UX some thought.
- I want non-rodent navigation (keyboard shortcuts) to move through the list and ‘rate’ how well I know something.
- I want the app to remember where I’m up to if I take a break.
- On mobile I want to tap on the same point on the screen and have the page scroll to the next item for me. The text I need to read should be above where my big fat finger is tapping the screen.
- I want links to the item in the relevant spec for when I think I know something but want to check (although I’m not sure I want to manually go and get five thousand links).
- I want the ability to indicate that “I don’t care”. For example, I don’t care about WebGL, I can skip those thousand items.
- The ability to view a shortlist of things I don’t know so I can focus on getting to know them.
- Maybe for those that don’t actually want to spend the time with this (and once I have some user data), a list of the most little-known things about web development.
Here’s a very rough prototype of where I’m at so far.
You can only ‘know’ leaf nodes, the very lowest level. But you can say that you don’t know any higher level in the tree.
I feel the need to point out that the scope of all this is knowledge, and nothing more than that.
Knowledge is knowing that a tomato is a fruit, wisdom is not putting it in a fruit salad.
Learning 100% of everything will not make you the best web developer you can be. But you can’t be the best if there are things you don’t know.
It’s not the only ingredient, but it is a required ingredient.
Where to next
I have no idea how long it will take me to finish this. Probably months at the current rate, I guess end of 2016 is a good goal. Ironically, by the time I’ve finished building the tool, I won’t really need it, but the longer-term plan is to make it extensible to any sort of data. There’s nothing web-development specific about the concepts here. Just a hierarchical list of stuff that you can know.
So if you’ve got any ideas, comments, or soup-themed jokes, please, share below.
- I wonder if the idiom “to trump something” will change in meaning any time soon. (Like “Jeez Louise, you really trumped that dolphin!” “Yeah, the poor little fella never saw it comin.”)