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.