DEV Community

Stas Melnikov
Stas Melnikov

Posted on

Let's Test Your CSS skill

CSS is a language with a bunch of topics. There is a developer who knows all unlikely. Honestly, we don't need to know it to do our job. But there is a piece of CSS without that we can't do. It is the goal of my questions.

If you can't answer some questions, don't worry. It means you have a chance to level up your knowledge 😉

Pay attention, I use the Computed value term. It's a property value that you see in the DevTools Computed tab.

What will specificity be of the following selector?

:is(#container, .content, main) {
  color: red;
}
Enter fullscreen mode Exit fullscreen mode

The :is() pseudo-class function helps browsers select the highest from a given selectors list. In our example, a more high selector is #container. The specificity of this selector is 0, 1, 0, 0. It will be used for the whole at-rule.

The computed value of the color property is red. True or false?

<body>
  <span id="container" class="container">content</span>
</body>
Enter fullscreen mode Exit fullscreen mode
.container {
  color: red;
}

:where(#container) {
  color: blue;
}
Enter fullscreen mode Exit fullscreen mode

True. The :where() pseudo-class function nulles specificity. So the .label selector has more specificity. It's why the computed value of the color property is red.

What is the computed value of the background-color property?

<body>
  <div id="container" class="container">content</div>
</body>
Enter fullscreen mode Exit fullscreen mode
@layer basic, components;

.container { 
  width: 1rem; 
  height: 1rem; 
}

@layer components {
  .container { 
    background-color: pink; 
  }
}

@layer basic { 
  #container { 
    background-color: blue; 
  }
}
Enter fullscreen mode Exit fullscreen mode

Layers are defined in order of priority. The last is more high. So the answer is pink.

What color will the square be in the following example?

.container {
  display: inline;
  width: 1rem;
  height: 1rem;
  background-color: currentColor;
}
Enter fullscreen mode Exit fullscreen mode

If the element has display: inline the width and height properties don't have an effect. We won't see a square.

What is the algorithm for calculating the computed value of the width property of the .child element?

<body>
  <!-- case #1 -->
  <div class="parent">
    <div class="child">content</div>
    <div class="child">content</div>
  </div>
  <!-- case #2 -->
  <div class="parent parent-flex">
    <div class="child">content</div>
    <div class="child">content</div>
  </div>
</body>
Enter fullscreen mode Exit fullscreen mode
.parent {
  display: block;
}

.parent-flex {
  display: flex;
}
Enter fullscreen mode Exit fullscreen mode

In the case #1 the .child elements are block-level elements. Their width property is equal to the width property of the parent element.

In the case #2 the .child elements are flex items. Their width property is calculated depending on content.

What is the computed value of the display property of the pseudo-elements?

.parent {
  display: inline-grid;
}

.parent::before {
  content: "";
  display: inline;  
}

.parent::after {
  content: "";
  display: flex;
}
Enter fullscreen mode Exit fullscreen mode

block and flex. The grid or inline-grid values transform inline-* values of the display property of the child elements to block alternative.

.parent {
  display: inline-grid;
}

.parent::before {
  content: "";
  display: inline; /* display: block will be here */        
}

.parent::after {
  content: "";
  display: flex; /* display: flex will be here */
}
Enter fullscreen mode Exit fullscreen mode

What is the difference between the default position of the child elements in the case with the parent element with display: flex and in the case with display: grid?

The child elements inside the parent element with display: flex display one by one in line. In contrast, the elements will be displayed one below the other in the case with display: grid.

What is the computed value of the width and height properties of the .child elements?

<body>
  <div class="parent">
    <div class="child">content</div>
    <div class="child">content</div>
  </div>
</body>
Enter fullscreen mode Exit fullscreen mode
.parent { 
  display: grid; 
  width: 100rem; 
  height: 20rem; 
}
Enter fullscreen mode Exit fullscreen mode

The width property of the .child element is equal to the width property of the parent element. So the computed value of the width property is 1000px.

The height property of the child element inside of the parent with display: grid fills all space. If the parent has a few items space will be shared between them equally. So the computed value of the height property of the child element is 20rem / 2 = 10rem, i.e 10 * 16 = 160px.

I use 16px like a browser's default font size.

The margins of the .child element end up outside of the parent element in all cases. True or false?

<body>
  <div class="parent">
    <div class="child">content</div>
  </div>
</body>
Enter fullscreen mode Exit fullscreen mode
/* case #1 */
.parent {
  display: inline-flex;
}

.child {
  display: block;
  margin-block: 1rem;
}

/* case #2 */
.parent {
  display: grid;
}

.child {
  display: block;
  margin-block: 1rem;
}
Enter fullscreen mode Exit fullscreen mode

False. Margins of the child elements don't end up outside the parent element with display: flex, display: inline-flex, display: grid and display: inline-grid.

Does margin collapsing work inside elements with display: inline-flex and display: inline-grid?

No, it doesn't work. Margins will be summed up inside of the element with display: flex, display: inline-flex, display: grid and display: inline-grid.

The position of the pseudo-element is centered horizontally and vertically. True or false?

.container {
  display: grid;
  height: 100dvh;
}

.container::before {
  content: "";
  width: 1rem;
  height: 1rem;
  margin: auto;
}
Enter fullscreen mode Exit fullscreen mode

True. Browsers will share all space between the childs and the parent's borders evenly.

What is the computed value of the min-width property?

<body>
  <div class="parent">
    <div class="child">content</div>
  </div>
</body>
Enter fullscreen mode Exit fullscreen mode
body {
  display: block;
}

.parent {
  display: grid;
  /* min-width: ? */
}

.child {
  /* min-width: ? */
}
Enter fullscreen mode Exit fullscreen mode

The initial min-width value is auto. So the computed min-width value of the .child element is auto.

But if the block, inline, inline-block, table or table-* value is defined for the element the computed min-width value of its child elements is 0.

body {
  display: block;
}

.parent {
  display: grid;
  /* min-width: 0 */
}

.child {
  /* min-width: auto */
}
Enter fullscreen mode Exit fullscreen mode

How can we use the gap property to replace the margin property?

<body>
  <div class="parent">
    <div class="child">content</div>
  </div>
</body>
Enter fullscreen mode Exit fullscreen mode
.parent {
  display: inline-flex;
}

.parent::before,
.parent::after {
  content: "";
  width: 1rem;
  height: 1rem;
  background-color: #222;
} 

.parent::before {
  margin-right: 1rem;
}

.parent::after {
  margin-left: 1rem;
}
Enter fullscreen mode Exit fullscreen mode

We should define the gap property for the .parent element.

.parent {
  display: inline-flex;
  gap: 1rem;
}

.parent::before,
.parent::after {
  content: "";
  width: 1rem;
  height: 1rem;
  background-color: #222;
} 
Enter fullscreen mode Exit fullscreen mode

The computed value of the display property is block. True or false?

.container {
  position: absolute;
  display: inline;
}
Enter fullscreen mode Exit fullscreen mode

True. If the absolute or fixed value is defined browsers will transform all inline-* values of the display property to block alternatives.

.container {
  position: absolute;
  display: inline; /* display: block will be here */
}
Enter fullscreen mode Exit fullscreen mode

Why is the computed value of the height property of the .parent element equal to 0?

<body>
  <div class="parent">
    <div class="child">content</div>
  </div>
</body>
Enter fullscreen mode Exit fullscreen mode
.child {
  position: fixed;
}
Enter fullscreen mode Exit fullscreen mode

The element with position: absolute or position: fixed is removed from the normal document flow. So the parent elements don't see it. It's why the computed value of the height property is 0.

What does the isolation property do in the following example?

<body>
  <div class="parent">
    <div class="child">
      <span>content</span>
    </div>
  </div>
</body>
Enter fullscreen mode Exit fullscreen mode
.parent {
  background-color: purple;
}

.child {
  position: relative;
  isolation: isolate;
}

.child::after {
  content: "";
  background-color: green;

  position: absolute;
  inset: 0;
  z-index: -1;
}
Enter fullscreen mode Exit fullscreen mode

We should remember which stacking context is used by browsers when using the z-index property.

By default, a root stacking context is the html element. It's why the pseudo-element is behind the .parent element without isolation: isolate.

We create a new stacking context with the isolation property for the .child element. So the pseudo-element displays behind the text but in front of the .parent element.

What is the position of the pseudo-element?

.container {
  display: grid;
  place-items: center;
  position: relative;
  height: 100dvh;
}

.container::before {
  content: "";
  width: 1rem;
  height: 1rem;
  position: absolute;
  bottom: 0;
}
Enter fullscreen mode Exit fullscreen mode

First, the pseudo-elements displays in the center because place-items: center is applied.

It shifts by Y axis to the bottom parent border after position: absolute, bottom: 0 are applied because the top, right, bottom and left properties are more priority than the place-items property.

What is the computed value of the width property?

.container {
  flex-basis: 250px;
  max-width: 225px;
}
Enter fullscreen mode Exit fullscreen mode

The flex-basis property has priority over the width property, but its value must also be in the range of values of the min-width and max-width properties. So the answer is 225px.

What is the computed value of the padding property?

:root {    
  --padding-vertical-start: 1rem;
  --padding-horizontal-end: 2rem;
  --padding-vertical-end: 3rem;
}

.container {
  padding: var(--padding-vertical-start) 
           var(--padding-horizontal-end) 
           var(--padding-vertical-end) 
           var(--padding-horizontal-start);
}
Enter fullscreen mode Exit fullscreen mode

We should define all parts of the shorthand when using CSS Custom Properties. If we don't make it browsers can't apply values.

It happens in our example. The padding shorthand requires 4 values. But the developer defined only 3. Browsers can't set paddings. So the computed value is 0.

Why will the computed value of the background-color property be green for the p element?

body {
  background-color: green;
}

p {
  --background-color: inherit;
  background-color: var(--background-color, inherit);
}
Enter fullscreen mode Exit fullscreen mode

A CSS custom property inherits a value from the same custom property defined for parent elements. If a custom property is omitted browsers will use fallback.

In our example the --background-color property is omitted from parent elements. So browsers use the fallback, i.e the inherit keyword that inherits the green value from the background-color property of the body element.

Make the scroll-behavior property safe with vestibular motion disorders.

html {
  scroll-behavior: smooth;
}
Enter fullscreen mode Exit fullscreen mode

We should wrap code using the prefers-reduced-motion media feature. It'll help to display smooth scrolling only if users allow it in OS settings.

@media (prefers-reduced-motion: no-preference) {

  html {
    scroll-behavior: smooth;
  }
}
Enter fullscreen mode Exit fullscreen mode

What is the computed value of the font-size property?

html {
  font-size: calc(1rem + 1px);
}
Enter fullscreen mode Exit fullscreen mode

Default browser font size is 16px in most cases. If it isn't changed the computed value of the font-size property will be 17px.

P.S. If you wanna get more my CSS tips join to my newsletter CSS isn't magic

Top comments (8)

Collapse
 
alohci profile image
Nicholas Stimpson • Edited

Nice, interesting set of questions. Would you be interested in me pointing out a few small mistakes?

Collapse
 
melnik909 profile image
Stas Melnikov

Nicholas, sure!

Collapse
 
alohci profile image
Nicholas Stimpson • Edited

OK. Well in approximate order of fairly clear-cut to nit-picks:

How can we use the gap property to replace the margin property?
The gap in the second example should be 2rem to match the margins in the first example.

What is the computed value of the padding property?
The outcome is correct, but for the wrong reason. The padding shorthand can definitely take 3 values. But because the --padding-horizontal-start custom property is not defined, the entire declaration is invalid, and is simply ignored.

Might the computed value of the flex-basis property be more than the computed value of the max-width property?
Leaving aside that we are assuming flex-direction:row here, the answer is "yes", not "no". While the flex-basis value is eventually limited by the max-width value, it is only done so at the used value stage. not the computed value stage. The most reliable way to verify this is to test what value gets inherited if you apply flex-basis:inherit to a child element, since it is always the computed value that gets inherited.

I'm reasonably sure that the same issue applies to the What is the computed value of the min-width property? question. The box-sizing and grid specifications talk about when the resolved and used values get set to zero, not the computed value. However, it's trickier to verify this.

What will specificity be of the following selector?
The specificity of the :is(#container, .content, main) selector is 1, 0, 0, not 0, 1, 0, 0. Since your selector is using the modern construct :is() it doesn't seem correct to use a CSS2 calculation of the specificity. Since Selectors Level 3, "inline styles" have not officially been part of the specificity calculation, and from the CSS Cascade Level 5 specification, such styling has a defined place in the cascade separate from specificity called Element-Attached Styles.

Finally, not a mistake but an observation: the question What is the mistake in the following code? doesn't seem to fit here. While all the other questions have objective answers, whether specifying height and width with display:inline in a rule constitutes a mistake seems less concrete. On its own, the height and width have no effect, but in combination with rules that cause blockification or inheritance of the properties in some context, all declarations in the rule could have a useful effect. Maybe a better way to ask the question would be to provide a border and some content for the element and ask whether or not the rendered border box will be square.

Thread Thread
 
melnik909 profile image
Stas Melnikov

Nicholas, thank you so much!

The outcome is correct, but for the wrong reason. The padding shorthand can definitely take 3 values. But because the --padding-horizontal-start custom property is not defined, the entire declaration is invalid, and is simply ignored.

What is invalid declaration? A lot of people don't understand what is behind it. So I wanna balance between simplicity and terminology.

Leaving aside that we are assuming flex-direction:row here, the answer is "yes", not "no". While the flex-basis value is eventually limited by the max-width value, it is only done so at the used value stage. not the computed value stage. The most reliable way to verify this is to test what value gets inherited if you apply flex-basis:inherit to a child element, since it is always the computed value that gets inherited.

Can you share the example?

The box-sizing and grid specifications talk about when the resolved and used values get set to zero, not the computed value. However, it's trickier to verify this.

I mean the computed values is a value which can be seen in the Computed tab of devtools. Maybe I should use another name but a lof of people don't see the difference. Maybe do you have any suggestions?

Thread Thread
 
alohci profile image
Nicholas Stimpson

Here's an example:

Note that the span inherits 200px as the flex-basis, not the max-width value of 150px.

I mean the computed values is a value which can be seen in the Computed tab of devtools.

"Computed Value" and "Used Value" have very precise meanings in CSS - and strangely the Computed value doesn't always match what can be seen in the Computed tab of devtools! First of all the definitions of the various values is given in the CSS Cascade specification.

Now, the value shown in the computed tab seems to match the value you get from window.getComputedStyle(). which isn't the Computed value - it's the Resolved value. The resolved value is sometimes the Computed value and sometimes the Used value.

This confusion occurs because the definition of "Computed Value" got changed after getComputedStyle() was already in use, and the values that it returned had to maintain backward compatibility.

"Resolved value" is defined in the CSSOM specification

Thread Thread
 
melnik909 profile image
Stas Melnikov • Edited

I see. Thank you. I replaced questions. Can you check it?

Thread Thread
 
alohci profile image
Nicholas Stimpson

Yes. I think it's OK now.

Thread Thread
 
melnik909 profile image
Stas Melnikov

thank you!