Lessons from the IDE — :root, Boxes, and SRCSETs

Welcome to Lessons from the IDE, a recap of successes, failures, and glitches (so, so many glitches) from my daily coding. This article was originally posted at bret.design

Today I started working through one of the free challenges from Frontend Mentor, the “Stats preview card component.” It was listed as a “newbie” difficulty, so I thought as a newbie, it wouldn’t cause too much of a problem. Spoiler: I was wrong.

That said, the value of any project is locating gaps of knowledge. In this case, I found quite a few gaps in my understanding of CSS and divs. I’ve been trying to strengthen my Grid and Flexbox skills over the past few days, so setting up the initial card wasn’t too painful.

Oh, and I almost forgot. Today marks my first entry for #100DaysOfCode

Let’s get to the :root of it

I’ve seen them most commonly used for setting up a color palette (or dark/light mode color options), but if there’s a particular margin or padding setup you plan to use across various elements, you can also declare those in a variable.

They look something like this:

After establishing the variables, they can be dropped elsewhere in the stylesheet, which is incredibly helpful if you decide to change your colors later on. If you apply the --accent-color in three different places, then you don't need to hunt down each of those instances in the code. Change the global variable and your work is done.

Here’s a look at variables in action:

main {
background-color: var(--secondary-color);
padding: var(--card-padding);
}
a {
color: var(--accent-color);
}

Quick Headache Prevention

Many programmers suffered for this fix, so I give my obligatory thanks here:

html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}

This did seem to make aligning the two main divs of the project simpler. But, as I said before, glitches are part of life. And not all content plays nicely.

Boxes and boxes of fun

This works, but you can’t just apply a color for some reason. It needs to be a linear gradient, even if you’re looking for a solid fill color…

#image-container {
background: linear-gradient(var(--image-tint-color), var(--image-tint-color)), url(images/image-header-desktop.jpg);
}

But, there’s a bit of an unintended side-effect. If you’re not interested in responsive fluid resizing, you can set the width and height of the div and you'll be all set. However, you need to use fixed values like pixels, or else the div registers as empty and doesn't render properly.

I saw a solution for this involving setting the padding of the div to a percentage representing the ratio of the background-image, but I also decided to see if there was another way to tint an image.

Yes, there is.

You can plug in an old fashioned image into a div container and set the container’s background color to appear in front of the container’s items through the object-fit: cover property. From there, use an rgba color assignment to select a semi-transparent fill color and you've got a basic image tint. Voila.

.image-container {
background-color: rgba(165, 62, 255, 0.536);
object-fit: cover;
overflow: hidden;
}

However, I did run into one final issue that took a bit of Googling to fix. The image in my div wasn’t exactly aligned with the boundaries of the div itself. I learned that an <img> tag automatically displayed in-line has a phantom line-height value attached to it. So the fix for my pixel-imperfect alignment was to set my image to display as a block.

I’m noting this because I can see it causing me a lot of stress in the future if I were to forget this simple fact.

img {
display: block;
}
Photo by Jackson So on Unsplash

Curse you gods of responsive images…

I know, this stinks of newbie problems, but I spent longer than I’d care to admit looking at several different templates to get responsive images to work and serve different images to different screen resolutions. I’m not even sure my current solution is optimized as it stands, but this did the trick for my project.

<picture
><source
srcset="images/image-header-desktop.jpg"
media="(min-width:1000px)"
/>
<source
srcset="images/image-header-mobile.jpg"
media="(max-width: 999px)"
/>
<img src="images/image-header-desktop.jpg" alt="Please, just work!" />
</picture>

The two source tags list the images that are part of the srcset and the media property determines how those images are displayed. In this instance, the larger of my images, image-header-desktop.jpg will display any time a user's browser resolution is greater than 1000 pixels.

If the user’s browser resolution is lower than 1000 pixels, the second source tag sets it so that they will be served the smaller image-header-mobile.jpg instead.

I’m going to have to investigate this further, but it worked for my current purposes, so I’m going to call this a tentative success on the day. I’m somewhat spoiled because I let the eleventy-img package take care of this on my personal site rather than having to handcode it.

Lessons to Remember

  1. Don’t assume the first solution you find is the best solution. I tried working with image-tinting the background-image of a div for a long time before discovering the object-fit approach for a standard <img /> tag.
  2. Images need to be displayed as a block in order to correctly fill a div!
  3. srcsets are powerful, but I’d be lying if I said I fully understood the intricacies of the syntax since I believe I’m missing a few properties here…

Conclusion

Thanks for reading and I’ll be back tomorrow with more Lessons from the IDE.

Scholar of Rhetoric and Composition. Artist and Writer.