What I Learned Today - 100 Days

Select

I loved writing 100 words for 100 days & now want to write 100 days of little HTML, CSS or JS (ES6) lessons. I'm going to write about methods and techniques that I use often, either at work or on personal projects. The lessons will be written from a NEWBIE (i.e. my) perspective, and so may not be perfect, but they will offer a valuable insight into the thoughts of a new developer. My goal is to learn/document things for myself, and to show people, particularly other new developers, how someone like me approaches my work and hopefully give them something they can relate to :) Thanks to Charlotte for the suggestion!

Write about a different pseudo class every day? Or a different HTML element or JS lesson every day? Anything you want to learn more about? I had hoped to do something similar and never got round to it.

— Charlotte Jackson (@lottejackson) May 1, 2018

Day 20 - filter  # Back to the top arrowClick this to go back to the top of the blog post

Howdy, sorry for the long hiatus. I was busy... planning an underwater holiday park. Nah, I was working hard and getting a little too much imposter syndrome. But now I've taken some helpful advice from myself to cut all that out and acknowledge the brilliant and hardworking developer that I am! And you should do the same. It does wonders for your self-esteem and sanity :)

Anyway, I've been playing with some Codewars katas and getting into the Array.prototype.filter() method in JS, and I like it. It's an almost disturbingly simple way to get some things done.

I was scratching my head about how to complete this task today:

Return an array that contains all values of array a, apart from those that exist in array b.

arrayA = [1, 2, 2, 2, 3]
arrayB = [2]

newArray = [1, 3] // <- make this magic happen!

What filter does for you is filter out any value you wish. You can attach the fitler method to an array, give it a condition, and it will return everything in the array that matches the condition. Note: when I first began using filter, I thought it would remove all values that match the condition, however the values that match the condition are actually kept. This seems a little unintuitive to me, but hey, I didn't write JS ;)

Here is the a solution:

newArray = arrayA.filter(value => !arrayB.includes(value))

In it, we are taking each value of arrayA and if arrayB contains any of these values, we do not display them in our newArray. If the ! was not present, we would create an array containing the values of arrayB that match values in arrayA (i.e. [2, 2, 2]).

Using the filter method takes time to get your head around, but it's worth it! Play around with the example above in your browser console. Also note the Array.prototype.includes() method being used in the example. I will cover this next time. Over and out for now.

Day 19 - Console debugging  # Back to the top arrowClick this to go back to the top of the blog post

A lot of people use console.log to debug in the console.

The log() method of console logs things to the web console. What some people may not know is that you can log things in nice ways! Here are three:

1. Computed property names -

The following objects could be logged one at a time:

const cat = { name: 'Fluffy', colour: 'orange', specialSkill: 'staring' }
const dog = { name: 'Thor', colour: 'brown', specialSkill: 'running' }
const fish = { name: 'Glub', colour: 'blue', specialSkill: 'blowing bubbles' }

And the results would be as follows:

console.log(cat) // {name: "Fluffy", colour: "orange", specialSkill: "staring"}
console.log(dog) // {name: "Thor", colour: "brown", specialSkill: "running"}
console.log(fish) // {name: "Glub", colour: "blue", specialSkill: "blowing bubbles"}

Or, they could be logged with a name label using 'computed property names'. To do this, create an object with the variables as keys:

console.log({ cat, dog, fish }) // {cat: {…}, dog: {…}, fish: {…}}

Inside this object, there will be the details of each variable with its corresponding key:

cat: {name: "Fluffy", colour: "orange", specialSkill: "staring"}
dog: {name: "Thor", colour: "brown", specialSkill: "running"}
fish: {name: "Glub", colour: "blue", specialSkill: "blowing bubbles"}

2. CSS in the console -

Define styles like this in the console:

var styles = [
  'background: linear-gradient(#21618C, #5DADE2)',
  'padding: 5px',
  'border-radius: 8px',
  'text-align: center',
  'color: white',
  'display: block',
].join(';')

Then prefix console log with the %c flag, adding the styles variable to the end:

console.log(
  `%c My cat is ${cat.name}, ${cat.colour}, ${cat.specialSkill}`,
  styles
)

Try it in your console or look at this example on CodeSandbox!

3. Tables in the console -

To display objects in a table in order to more easily compare them, try using console.table. You can do so with the animal objects above by running:

console.table([cat, dog, fish])

Not only will there be a nicely-formatted table to see in the console, but the (unlabeled) objects will also be displayed as well.

Note

All of these things make console logging a little better. Not sure how many I will start using myself, but I'll give them a go to see whether I like them :)

Day 18 - Types  # Back to the top arrowClick this to go back to the top of the blog post

JavaScript has six primitive types. These all have default values and can be checked for using the typeof operator.

Default values:

'boolean' - false
'null' - null
'number' - 0
'string' - ''
'undefined' - void 0
'symbol' - Symbol() // new in ES6

Checking the type of a primitive:

if (typeof myPrimitive !== 'number')
  throw new TypeError('Type must be a number!')

Day 17 - Prebrowsing  # Back to the top arrowClick this to go back to the top of the blog post

This is an umbrella term for telling browsers what users need (and allowing preloading of data) before the user requests them. Luckily, these techniques do their work behind the scenes, and do not block any other operations happening on a web page. Some browsers, e.g. Chrome, have some prebrowsing techniques built in.

They include dns-prefetch, prefetch, preconnect, prerender, and (a deprecated) subresource.

None are guaranteed to provide a performance boost in the form of faster render times for users, but there is no harm in including them. They are a great example of progressive enhancement - browsers that are built to use them may provide users a benefit, and browsers that don't use them won't disadvantage their users in any way.

I'll mention a commonly used one here - dns-prefetch: My understanding is that this technique allows supporting browsers to open a DNS request ahead of time in the background before something on a page begins rendering. So, for example, dns-prefetch can open the connection to the CDN containing some images a small amount of time before they actually begin the process of rendering. This can save some milliseconds in render time. So, we can set the URL of our CDN as the value of an href attribute and add a nice rel attribute with the relevant prebrowsing value. One more thing to note, all prebrowsing techniques are used within the <head> element of an HTML document.

<head>
    <link rel="dns-prefetch" href="//fancyimagecdn.com">
</head>

See this CSS tricks article by Robin Rendle for further information.

Day 16 - indexOf  # Back to the top arrowClick this to go back to the top of the blog post

indexOf() is a handy little JavaScript method that returns the first index (position) of an item within an array or a string. For example:

Array -

const catStory = ['The', 'Cat', 'Is', 'Good', 'The', 'Cat', 'Is', 'Fluffy'];
const firstCatOccurrence = 'Cat'

const firstCatPosition = catStory.indexOf(firstCatOccurrence)

console.log(firstCatPosition) // 1

Notes:

  • indexOf() is case sensitive. Searching for 'cat' will return -1.
  • Numbers can be searched as well, e.g. [1, 2, 3]

Or:

String -

const catStory = 'Pickles the cat slept in twelve different places today';
const catOccurrence = 'cat'

const catPosition = catStory.indexOf(catOccurrence)

console.log(catPosition) // 12

If an occurrence is not found, -1 will be returned. This is because the indexOf() method was written a long time ago, and back then it was thought of as sensible to always return a number. Methods such as match() and includes() were written later and return null and false when no occurrence is found. Therefore, to check whether an occurrence exists in your string (or array):

'Kitty Litter'.indexOf('Lit') !== -1; // true
'Kitty Litter'.indexOf('Kittty') !== -1; // false

See more from MDN about String.prototype.indexOf() here and Array.prototype.indexOf() here.

Day 15 - Array Prototype Methods  # Back to the top arrowClick this to go back to the top of the blog post

Array.prototype methods are super useful for transforming array data and cover a lot of common needs in modern applications! They are a form of higher-order function (HOC), which are functions that take another function as their argument, or return one as a result. A good way to view functions is as values, because then it's easier to imagine being able to pass them around. For me, they've been a great introduction into the world of functional programming. In functional programming, the functions you create are pure, i.e. they have no side effects, rely on the input you give them, and will always produce the same output given the same input.

So, I use array methods more and more at work and they are definitely a pleasure to work with! There are quite a lot of them (I think around 50), but there are some more frequently used ones that cover most use cases, such as sort(), map(), filter(), and reduce(). I was inspired to write about them after reading this post by Angelos Chalaris! Please check out his post because there are great examples & explanations in there!

Of course, since I like them so much, I wanted to give an example here. The one I used most at work is map() but I didn't choose it because I gave an example of it in Day 2 :) As a side note, if you look carefully at the example in Day 2's lesson, you'll see how the elements array takes the map function, which in turn takes a function as its input, and returns a value based on the input. Below, I decided to create an example of reduce().

const initialCatRating = [10, 10, 10]
const accurateCatRating = initialCatRating.reduce((total, amount) => {
  total.push(amount * 2)
  return total
}, [])

accurateCatRating // [20, 20, 20]

This example shows one of the many things reduce can do - alter values in an array, and push the altered values into a new array! This means a brand new array is returned, rather than altering the initial array. Let me explain what's happening:

There is an initialCatRating variable, which shows ratings of cats out of ten. In the accurateCatRating variable, reduce() is called on initialCatRating.

The first argument in reduce() is a callback function (see this in pink above). The callback takes at least two and up to four arguments (accumulator, currentValue, currentIndex, array). The above example has taken two - total and amount, which are actually accumulator and currentValue. Naming doesn't matter here, but order does.

The second argument in reduce() is initialValue, which is optional. In the above example, initialValue is an empty array. The callback only operates on every element in an array when initialValue is present, so for the above example it is not optional.

Putting the callback and initialValue together allows reduce() to take each element in the given array and operate on it, then push the returned values (using push() - another array method) into a new array.

Of course, to make it re-usable, you can extract the callback function from the above example into something like:

const doubleMyValue = (total, amount) => {
  total.push(amount * 2)
  return total
}

Then, it can be put straight into reduce() (as an argument), to read:

const initialCatRating = [10, 10, 10]
const accurateCatRating = initialCatRating.reduce(doubleMyValue, [])

accurateCatRating // [20, 20, 20]

The reduce() callback above is actually not a pure function, because it modifies one of its parameters. To keep reduce() pure/functional, the callback can only take primitive values. See the MDN article for examples. And see some more examples here. Try some Array.prototype methods out in your browser console! :)

Day 14 - Ternary Operator  # Back to the top arrowClick this to go back to the top of the blog post

This is one of my favourite things in JavaScript. Not only is it simple and easy to use but it's also applicable to lots of situations and it can replace more verbose syntax (like if statements). It looks something like this:

const hoursOfSleep = 5;
const timeForSleep = (hoursOfSleep < 8) ? 
    "Yup, no more phone for you" : 
    "Ah nah, a few more minutes of phone time won't hurt"; 

Notice the ? and the :

These are the important parts.

If the condition (in this case hoursOfSleep) in front of the question mark evaluates to true, the value of the first expression before the colon is returned. If the condition in front of the question mark evaluates to false, the value of the second expression after the colon is returned. As you can see, if you have had less than 8 hours of sleep, you shouldn't be using your phone.

Ternary operators are really flexible and can be used in a number of ways. You can stack them together:

const catsRule = true,
const dogsDrool = false,
const catDog = catsRule ? 
    (dogsDrool ? "Let's all live in harmony": "Both cats and dogs drool") :
    (dogsDrool ? "Dogs are cool, nearly as cool as cats" : "Dogs and cats can be friends");

This outputs "Both cats and dogs drool", and it's also total nonsense but I hope you had fun staring at it and trying to figure it out. You don't even need to use the parentheses, and can also use multiple statements separated by commas. You can return statements in functions. You can use them in place of bulky if/else statements with much nicer-to-read code. The question mark means if and the colon means else.

I use ternary operators at work all the time. I hope you enjoy them as much as I do. Check out the MDN page for some examples. This post is lovely too.

Day 13 - Object Literals  # Back to the top arrowClick this to go back to the top of the blog post

I didn't learn about these at work but rather from a video on the JavaScript reduce function by the wonderful MPJ.

Object literals are a data structure that can be used in JavaScript. I really like seeing how data can be organised and object literals do this really nice and tidily. Here's an example:

var cat = {
    myCat: 'Tabby',
    getCat: catTypes('Siamese')
}

The above code is an alteration of the MDN example. I found MDN's explanation of object literals a little mechanical (compared to other resources I found), but it does give quite a clear portrayal of how flexible object literals can be. For instance, the typical combination of a key (myCat), value (Tabby) pair can be accessed and used in other places in your code, without these values polluting the global scope*. You can use the catTypes function like so:

function catTypes(type) {
    if (type !== 'Siamese') {
        return type;
    } else {
        return "Many " + type + " cats have blue eyes.";
    }
}

console.log(cat.getCat) // Many Siamese cats have blue eyes.

If this was not exciting enough, there are many other data types (not only functions) that can be organised using object literals - e.g. array literals (see an example of this in MPJ's video), nested object literals, numbers, any string, etc.

My friend Mark also informed me that an object can contain itself (which is not recommend because it breaks JSON.stringify)!

Of course as with any programming language, there are rules. Some of these are that a colon separates the key from the value, a comma separates key-value pairs, there shouldn't be a comma after the last value-pair (well, it's fine to have a dangling comma, but many style guides don't want you to do it), etc.

For more rules and when to use, check out this nice post, and the MDN page.

I haven't had much of a chance to use object literals in the wild yet, but I hope to soon. After I have, I hope to write an updated post that describes my new insights.

  • An object (literal) can be used like a namespace to avoid polluting the global object, but there's still the reference of the object attached to global. If you want to completely eliminate variables polluting the global object as fields, then IIFEs are for you. Some modules are also isolated from global. So, object literals limit pollution through namespacing, but do not entirely eliminate it. (Thanks, Mark, for the information).

Day 12 - Testing  # Back to the top arrowClick this to go back to the top of the blog post

Today at work, we talked about test automation. One of the developers mentioned this quote:

We cannot rely on mass inspection to improve quality, though there are times when 100 percent inspection is necessary. As Harold S. Dodge said many years ago, ‘You cannot inspect quality into a product.’ The quality is there or it isn’t by the time it’s inspected. - William E. Deming in Out of the Crisis

Therefore we cannot rely on creating features in a hurry, throwing them over the fence and then expecting our applications to work well and without bugs. To instil quality from the start of a feature, there should be tests for it.

Automated testing helps with this. Pre-commit hooks can be used when deploying builds so that errors are caught and addressed early. Unit tests can be run using pre-commit hooks - see my post on unit tests here. However, there is a fine line between having too many automated tests, e.g. end-to-end tests that take too long to run with each build, and not having enough. Some companies run quicker unit tests on each build, and then run end-to-end tests as a nightly build.

Please see the image below for one of many examples of the testing pyramid if you are confused when I mention unit tests or end-to-end (UI) tests:

The Testing Pyramid

Manual testing is important too. It is usually done by QA engineers, and helps reveal edge cases that automated tests do not catch. As one developer at my work said, these tests are like the cherry on top of the testing pyramid.

Day 11 - Emmet  # Back to the top arrowClick this to go back to the top of the blog post

Emmet provides a really useful way to make developing easier. It improves the developer experience™. I only discovered it recently but love it already. It originated as Zen Coding about ten years ago. There are a few uses (see official docs), but I'll focus on the amazing abbreviation and snippet expansion feature.

In your HTML, say you need 100 divs. And each should have a class of teddybear. Typing these out by hand might be boring. With Emmet, you can write div*100.teddybear (then press 'tab'). Or if you need each class to be item1, item2, etc. then you can write div.item$*3. There are also HTML elements that get handily created with relevent attributes - try typing a or img. See one of the original articles on Emmet here for more examples. You can download it or check if it comes built-in with your text editor of choice - I use VSCode and found Emmet was ready for use!

Emmet also features CSS selector expansion which allows you to type abbreviated selectors that are expanded when you press 'tab'. It can also automatically add vendor prefixes for you. Try and see how many abbreviations you can guess here ;)

Day 10 - Strings  # Back to the top arrowClick this to go back to the top of the blog post

  • A sequence containing some letters, numbers or symbols.
  • Have available methods and properties.
  • Can be stored in variables.
  • Sit between either single quotes (' '), double quotes (" "), or backticks ( ).
  • Can be concatenated (stuck together) with the + operator, or with backticks (template strings) in ES6.
  • Template strings, or template literals, can take any valid JavaScript expression, allowing dynamic strings.
  • Can contain special characters, such as quotation marks, as long as they are escaped - e.g. "She'\ll be coming '\round the mountain when she comes".
  • There's no need to escape dissimilar quote marks. For example: "This 'is' fine". This is probably why we tend to favour double quotes in HTML attribute values, and singles in JS (since it allows you to create some innerHTML without the need for escaping).
  • When using template literals, you don't need to escape ' or " ... and this` `"is"` `'also'` `fine
  • Is either a string primitive - immutable and more common, e.g. const stringPrimitive = "Hello, I am a string."; .
  • Or a string object - const stringObject = new String("Hello, I am a string.");
  • The typeof operator is used to determine if a string's type is string or object.
  • Each character is indexed and can be accessed by an index number using square bracket notation (e.g. "Hello World" - myString[0] outputs "H").
  • Similar methods to the one above include: charAt(), indexOf(), lastIndexOf(), slice().
  • Other common methods and properties are: length, toUpperCase(), toLowerCase(), split(), trim(), replace().

This list is meant as a quick and basic introduction to the magical world of JavaScript strings. If there's something you'd like me to add, let me know!

Many thanks to my good friend Mark for suggesting additions :)

Day 9 - Readable Code  # Back to the top arrowClick this to go back to the top of the blog post

There are so many books, articles, and videos about how to make code readable, so I'll keep this short and from my perspective (as a new developer who works mainly with JavaScript).

  • Code style of your project. This is specific to each project and covers things like indentation, levels of nesting, naming, spacing etc. There are some nice tools to help with this - for example ESLint that you can configure to auto-format your code to your specified style upon file save.
  • Structure. This is about how you organise your code and files in a project. I have been taught the benefit of abstracting and modularising code, making it easier to tell what each part does and easier to test. In React, I've been writing components that are either presentational (how things look) or containers (how things work). Between different projects and programming languages, there are many, many ways to structure code well, and opinions tend to differ.
  • Commenting. There are three ways I've been doing this - either in my CSS, or in one of two ways (single-line with // or the JSDoc way) in my JS. The most important way to comment CSS is when magic numbers, i.e. seemingly random numbers that don't use pre-defined mixins or seem to relate to the rest of the code, are present. Leaving a note about these numbers can help other developers (or yourself a few months later) understand why the CSS is written that way. An important thing to remember when commenting JS code is that comments should state what the expected results of the code (e.g. a function) is, and not a description of what the code is doing.
  • Naming. This is well-known as one of the hardest things in programming. But it pays off big time. It helps developers get as close a possible to the coveted self-documenting code that doesn't need any comments (although I think no comments at all is probably a bad thing). I feel some developers keep function and variable names short in order to make their code look cleaner and keep file sizes small. However, on my latest project at work, without some of the really long and descriptive naming going on, I'd have a much harder time understanding the complex codebase.

These are the four areas around readable code that popped into my mind. There are definitely more, and there are so many resources on this. Go check 'em out, and discuss them with people! I know I'll continue to do both those things for a long time to come.

Day 8 - Debugging  # Back to the top arrowClick this to go back to the top of the blog post

Recently at work, I've watched other developers use console.log a lot in code to find desired values given by certain functions. I am often still confused where to put console.log, and it is definitely not the only way to debug, so I've also begun to use the developer tools JavaScript debugger in Firefox and Chrome. These tools allow you to pause the execution of your code, and walk through it to help you find bugs.

The debugger can do a lot, and it'd take a much longer post to walk through this tool's UI, so I'll mention four of the most commonly used debugging methods here.

  • Step over code

    • Steps over a function that doesn't contain a bug and runs its code
  • Step into code

    • Steps inside a function and allows you to run each part separately
  • Step out of code

    • Steps out of a function you are inside, and runs its code
  • Resume execution of code

Debugging is something developers have to be really good at. So don't be scared to do it! Or, be scared but do it anyway, you'll get better :)

Check out the docs on the Firefox debugger and the Chrome debugger. Lots of great info there to help you get started. Also check out this article from Peter Lyons. He explains debugging of both front-end and back-end JavaScript code.

Also, check this out - an honest post about how even experienced devs find it hard to debug.

Day 7 - CSS Layout  # Back to the top arrowClick this to go back to the top of the blog post

CSS layout is something that amazes and confuses me at the same time. There seem to be so many approaches (e.g. floats, flexbox, grid), and so many frameworks (way too many to mention). The paradox of choice seems to apply here.

I love hearing from people about CSS layout, and I was lucky to hear Miriam Suzanne talk about it at Beyond Tellerrand (check out the awesome layout on her site). The message she gave was to use CSS grid, and provide fallbacks for browsers that aren't grid-compatible. She reasons that as grid makes layouts so easy (and naturally responsive), that there is time to re-create fallback layouts, which allows more creative control.

Often I allow fallback layouts to be much simpler. CSS Grid has power to create layouts that have no *exact* fallback. Since grid makes many layouts easier, I have extra time to do both. Similar time spent, more creative control.

Your mileage will depend on your constraints.

— Miriam Suzanne (@mirisuzanne) May 8, 2018

One thing I really like about CSS layouts is that they aren't designed to be used in isolation. On the contrary, you can mix and match them. A grid item can become a flex container, and a flex item can become a grid. You can even use floats with flexbox and grid.

I am half-way through Wes Bos's CSS grid course and already have ideas I am excited to make come to life using grid. There are looots of great posts and articles out there by people who have had tonnes of fun and learned loads by using grid. I really recommend finding some and making some stuff!

Day 6 - JSON-LD  # Back to the top arrowClick this to go back to the top of the blog post

JSON, or JavaScript Object Notation, is a simple language that represents objects on the Web and facilitates data exchange. LD, or Linked Data, allows for the expression of critical data on a site, and for it to be shared across sites. I first heard of it at Beyond Tellerrand in Düsseldorf on May 7th, during a talk about web annotations by Lyza Danger Gardner. JSON-LD allows expressions of linked data in JavaScript. It's like grammar for describing strutured data. It can be thought of as JSON, but with added semantics. And it can be easily implemented into existing JSON structures. Here's some example JSON:

{
    "name": "Amber Wilson",
    "homepage": "https://amberwilson.co.uk",
    "picture": "https://twitter.com/account/
    profil_image/ambrwlsn90"
}

Here is similar information in JSON-LD format:

{
    "@context": {
        "xsd": "http://www.w3c.org/2001/XMLSchema#",
        "foaf": "http://xmlns.com/foaf/0.1/",
    },
    "@id": "http://me.amberwilson.co.uk",
    "@type": "foaf:Person",
    "foaf:name": "Amber Wilson",
}

Above, we see that context can be added to data. foaf stands for "friend of a friend" (see here), which deals with people-related terms. id and type, like context, assist in making our data shareable and semantic.

The concept of JSON-LD is simple, but using it can take getting used to. For more in-depth information, see here.

Day 5 - Flux  # Back to the top arrowClick this to go back to the top of the blog post

Recently, I began to write React at work and I've been doing okay with presentational components, but much less so with business logic (I hear ya Brad Frost). I've heard that improving my ES6 will really help, so you'll see more little lessons on it, but I also want to touch on how to manage dynamic state. Despite the popularity of Redux, one of my developer friends recommended covering Flux.

Flux is an application architecture for React (that can also be used elsewhere) utilizing a unidirectional data flow. In essence, it is an observer pattern that offers one-way data binding. Very useful when you need to keep lots of components in sync.

action -> dispatcher -> store -> view

  • The action creator formats messages (what the user does) from the UI
  • The dispatcher takes the formatted messages and synchronously sends them to different stores
  • The store holds all state logic and changes it by deciding what actions it wants to pay attention to
  • The view takes changes from the store and updates the UI

Please look at Lin Clark's great cartoon guide for more details. For a more code-heavy example, see here. I feel like the best way to learn about Flux is to build things in tandem with reading about it (and finding nice developers who can guide you)!

Day 4 - This  # Back to the top arrowClick this to go back to the top of the blog post

The this keyword is found in various programming languages, and behaves a certain way in JavaScript. Apparently even experienced developers get confused by it.

See this codepen for some example code. It showcases one of the six ways this is used in JavaScript - thanks to what I learned from Zell Liew's great blog post. I really recommend this post for beginners - you can try the examples in your console! In short, this can be used globally, in object constructions, object methods, simple functions, arrow functions, and event listeners. See the MDN docs for more code-heavy examples.

Day 3 - Pseudo Selectors  # Back to the top arrowClick this to go back to the top of the blog post

I only just found out that ::before (:before) and ::after (:after) are pseudo elements, which are different from pseudo classes. Both of these are grouped under pseudo selectors. I like this quote from MDN ~

Even the most skilled web developers are still amazed by what's possible using selectors.

pseudo selectors are only two types of selectors. The others are: simple selectors, attribute selectors, multiple selectors and combinators. All of these help us to target and style HTML elements.

So, pseudo selectors include both pseudo elements and pseudo classes. They are added to the end of other selectors, and don't apply to whole elements, only parts of them.

The pseudo classes (e.g. :hover, :focus, and :nth-of-type() - plus 38 others) style elements in a certain state.

The pseudo elements (e.g. ::after, ::before, and ::first-letter - plus 3 others, not including experimental ones) apparently need :: rather than :, although I've used them with only one. These don't depend on the state of an element.

See this MDN page for great examples and to use their awesome active learning playground (I did and it was great for learning)!

Day 2 - Arrow Functions  # Back to the top arrowClick this to go back to the top of the blog post

Also known as a fat arrow, =>. This ES6 feature is a fat topic, so I'll concentrate on one aspect today.

var elements = [
'Hydrogen',
'Helium',
'Lithium',
'Beryllium'
];

(elements.map(function(element) {return element.length}))
(elements.map(element => {return element.length}))
(elements.map(element => element.length))
(elements.map(({length}) => length))

Above is an altered version of the MDN JavaScript Demo, where you will find a wealth of information on what fat arrows can do for you. The first function in the list is written without fat arrows. The last three functions are variations of the first function, showing how fat arrows can be used to write shorter function expressions, and therefore less code. You will need a code compiler like Babel to compile fat arrows into ES5 syntax so older browsers can use your JavaScript.

There are a lot of resources that try explaining this syntax. Try Wes Bos's introduction for a start. This is complicated subject matter, though, so I suggest searching around for different posts, reading a few and finding ones that make most sense to you.

Day 1 - BEM  # Back to the top arrowClick this to go back to the top of the blog post

I keep getting tripped up at work by forgetting to write modular CSS classes. There are so many benefits to a robust CSS architecture that I really want to get it right. BEM is a methodology to achieve this. Block, Element and Modifier. A Block is a component or feature than can stand alone and is not dependent on any other code. It can be re-used anywhere. Next, an Element. This is always part of a Block and has no meaning on its own. Lastly, there is the Modifier. This changes the behaviour and/or appearance of a Block or Element.

Example:

.button is a block.

.button__label is an element.

.button--confirm is a modifier.

See resources here and here.