February Front-End Quiz

2021-02-16

Plant by the computer

We held a small quiz on our Instagram the other day and it's time to share the answers!

Question 1

What colour are the paragraphs?

Javascript.blue {
	color: blue;
}

.green {
	color: green;
}
Javascript<p class="green" style="color:red;">
	A colourful paragraph.
</p>

<p class="green blue">
	Another colourful paragraph.
</p>

A. Green and blue

B. Red and green

C. Red and blue

The answer is: B

The first paragraph is red because the inline styling we've set has a higher specificity than the "green" class. The same goes for any rule declared in a style tag or an external style sheet. The only way to actually override inline styling is through the use of !important.

The second paragraph is green because the "green" class is declared after the "blue" class in our style sheet. This is an example of the cascading nature of CSS.

Question 2

What's wrong with this link?

Javascript<a href="/">
	<img src="/logo.png" alt="" />
</a>

A. Nesting an image tag in an anchor tag is invalid HTML

B. An img tag's alt attribute should never be left empty

C. The link lacks a clear label

The answer is: C

With the markup above, screen-reader users will be informed that a link exists, but there will be no indication where that link will take them. To solve this issue, we should provide a descriptive label for the anchor tag. There are a few different ways we can do this and below are three suggestions.

We can set the label on the anchor tag with the aria-label attribute:

Javascript<a href="/" aria-label="Home">
	<img src="/logo.png" alt="" />
</a>

We can provide the label in the omage's alt attribute:

Javascript<a href="/">
	<img src="/logo.png" alt="Home" />
</a>

We can nestle a span with the label inside the anchor tag and style it to be visually hidden using the class below:

Javascript<a href="/">
	<img src="/logo.png" alt="" />
	<span class="visually-hidden">Home</span>
</a>
Javascript/*  */

.visually-hidden { 
    position: absolute !important;
    height: 1px; 
    width: 1px;
    overflow: hidden;
    clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
    clip: rect(1px, 1px, 1px, 1px);
    white-space: nowrap;
}

Credit: https://a11yproject.com/posts/how-to-hide-content/

Question 3

Which example is the most semantically correct?

A. Example 1

B. Example 2

C. Example 3

The answer is: B

Using the native button element is the ideal solution in most cases. The button is focusable and can be activated with the Enter key, Space key or with a mouse click.

If, for some reason, we can't make use of the button element, we need to make sure that our chosen element has the same functionality as a native button by adding the necessary attributes (see Example 1).

Lastly, Example 3 is semantically incorrect simply because all those extra attributes are unnecessary. A button already has the features we want, so adding them again is a waste of resources.

Question 4

Internet Explorer does not support the pseudo class :focus-within. How will that browser interpret the above rule set?

Javascript.container:focus-within,
.container.focus-within {
	text-decoration: underline;
}

A. The selector containing :focus-within is ignored

B. The whole rule set is ignored

C. The browser won't load the page at all

The answer is: B

When a browser comes across a selector it doesn't understand, it will ignore the whole rule set. This is important to remember when writing solid cross-browser compatible CSS.

To fix the above example, we could simply write two separate rule sets, one for each selector.

Question 5

What will be logged in the console?

Javascriptconst array1 = [{ firstName: "Anna" }];
const array2 = [...array1];
array2[0].firstName = "Ayesha";

console.log(array1[0].firstName);

A. Ayesha

B. Anna

C. undefined

The answer is: A

When we spread array1 and assign it to array2 on the second line, we are creating a shallow copy of array1. This means that the object inside array2 is still pointing to the same object in memory as the object in array1. So, even though we now have two arrays, only one object exists. This means that any changes we make to its firstName property are going to be reflected in both array1 and array2.

Question 6

What will be logged in the console?

Javascriptlet dog = {
    breed: "Corgi",
    sound: "Woof!",
    getBreed: () => { 
        return this.breed;
    },
    getSound: function() {
        return this.sound;
    }
};
console.log(dog.getBreed(), dog.getSound());

A. Corgi, Woof!

B. Corgi, undefined

C. undefined, Woof!

The answer is: C

The issue here is that arrow functions don't bind their own this. Instead, they inherit it from their parent scope. So when we try to call dog.getBreed(), the function is trying and failing to find a breed property outside of the dog object.

Question 7

What font size will the two paragraphs have?

Javascripthtml {
	font-size: 16px;
}

article {
	font-size: 0.5em;
}

article p:first-child {
	font-size: 1em;
}

article p:last-child {
	font-size: 1rem;
}
Javascript<article>
	<h2>Spring Cleaning</h2>
	<p>I spent the day re-writing all my CSS!</p>
	<p>It took some time, but it was worth it.</p>
</article>

A. 8px and 16px

B. 16px and 16px

C. 16px and 8px

The answer is: A

To understand what's happening here, we need to understand the difference between em and rem units: em is relative to the font-size of its nearest parent, while rem is always relative to the html (root) font-size.

In our example, the root font-size is set to 16px. The article is then given a font-size of 0.5em which gives it a size of 16px * 0.5 = 8px since article's nearest parent is html.

The first paragraph is set to 1em, giving it the same size as its parent article (8px * 1 = 8px). The second paragraph is instead set to 1rem, which means that it ignores any other potential parents and looks all the way back to the root element to figure out how big it should be: 16px * 1 = 16px.