- July 18, 2021
- Posted by: team SOUTECH
- Category: Blog, Blogging, Development, Professional Website Design Free Training, Responsive Web Design, Web Development Training, Website Design Service Abuja, Website Design Training
The aesthetically focused features of CSS are so useful in responsive web design because using CSS lets us replace images in many situations. This saves you time, makes your code more maintainable, and results in less page “weight” for the end user.
Vendor prefixes
When implementing experimental CSS, just remember to add relevant vendor prefixes via a tool, rather than by hand. This ensures the broadest cross-browser compatibility and also negates you adding in prefixes that are no longer required. I’m mentioning Autoprefixer (https://github.com/postcss/autoprefixer) in most chapters as, at the time of writing, I think it’s the best tool for the job.
Text shadows with CSS
Let’s make a start by looking at text shadows. Text shadows are a fairly simple way to change the aesthetics of text, and therefore provide a good starting point. Support for text-shadow is also ubiquitous. Let’s first consider the basic syntax:
.element {   text-shadow: 1px 1px 1px #ccc; }
Remember, the values in shorthand rules always go right and then down (or think of it as clockwise if you prefer). Therefore, the first value is the amount of shadow to the right, the second is the amount down, the third value is the amount of blur (the distance the shadow travels before fading to nothing), and the final value is the color. Shadows to the left and above can be achieved using negative values. For example:
.text { text-shadow: -4px -4px 0px #dad7d7; }
The color value doesn’t need to be defined as a hex value. It can just as easily be HSL(A) or RGB(A):
text-shadow: 4px 4px 0px hsla(140, 3%, 26%, 0.4);
You can also set the shadow values in any other valid CSS length units such as em, rem, ch, rem, and so on. Personally, I rarely use em or rem units for text-shadow values. As the length values tend to be low, using 1px or 2px generally looks good across all viewports.
Thanks to media queries, we can easily remove text shadows at different viewport sizes too. The key here is the none value:
.text { text-shadow: 2px 2px 0 #bfbfbf; } @media (min-width: 30rem) { .text { text-shadow: none; } }
It’s worth knowing that, in CSS, where a value starts with a zero, such as 0.14s, there is no need to write the leading zero: .14s is exactly the same.
Omit the blur value when it’s not needed
If there is no blur to be added to a text shadow, the value can be omitted from the declaration. For example:
.text { text-shadow: -4px -4px #dad7d7; }
That is perfectly valid. The browser assumes that the first two values are for the offsets if no third value is declared.
Multiple text shadows
It’s possible to add multiple text shadows by comma separating two or more shadows. For example:
.multiple { text-shadow: 0px 1px #fff, 4px 4px 0px #dad7d7; }
Also, as CSS is forgiving of whitespace, you can lay out the values like this if it helps with readability:
</pre> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">.text {</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> font-size: calc(100vmax / 40); /* 100 of vh or vw, whichever is larger divided by 40 */</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> text-shadow:</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> 3px 3px #bbb, /* right and bottom */</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> -3px -3px #999; /* left and top */</p> <pre><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">} </span>
You can read the W3C specification for the text-shadow property here: http://www.w3.org/TR/css3-text/#text-shadow.
So, that’s how you create shadows around text. What about when you want a shadow on a containing element?
Box shadows
Box shadows allow you to create a box-shaped shadow around the outside or inside of an element. Once you understand text shadows, box shadows are a piece of cake. Principally, they follow the same syntax: horizontal offset, vertical offset, blur, spread (we will get to spread in a moment), and color. Only two of the four length values are required. In the absence of the last two length values, a value of zero is assumed. Let’s look at a simple example:
</pre> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">.shadow {</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> box-shadow: 0px 3px 5px #444;</p> <pre><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">} </span>
The default box-shadow is set on the outside of the element. Another optional keyword, inset, allows the box shadow to be applied inside the element.
Inset shadow
The box-shadow property can also be used to create an inset shadow. The syntax is identical to a normal box shadow, except that the value starts with the keyword inset:
</pre> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">.inset {</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> box-shadow: inset 0 0 40px #000;</p> <pre><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">} </span>
Everything functions as before, but the inset part of the declaration instructs the browser to set the effect on the inside.
Multiple shadows
Like text shadows, you can apply multiple box shadows. Separate the box-shadow declarations with a comma. They are applied bottom to top (last to first) as they are listed. Remind yourself of the order by thinking that the declaration nearest to the top in the rule (in the code) appears nearest to the “top” of the order when displayed in the browser. As with text-shadow declarations, you may find it useful to use whitespace to visually stack the different box-shadow declarations:
box-shadow:
inset 0 0 30px hsl(0, 0%, 0%),
inset 0 0 70px hsla(0, 97%, 53%, 1);
Stacking longer, multiple values, one under the other in the code, has an added benefit when using version control systems; it makes it easy to spot differences when you compare, or “diff,” two versions of the same file. It can be useful to stack selectors one under the other for that same reason.
Understanding spread
I’ll be honest, for literally years I didn’t truly understand what the spread value of a box-shadow actually did. I don’t think the name “spread” is useful. Think of it more as an offset. Let me explain.
Look at the box on the left in example_07-02. This has a standard box shadow applied, with no spread. The one on the right has a negative spread value applied. It’s set with the fourth value. Here is the relevant code that deals with each shadow:
</pre> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">.no-spread {</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> box-shadow: 0 10px 10px;</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">}</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">.spread {</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> box-shadow: 0 10px 10px -10px;</p> <pre><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">} </span>
Here is the effect of each (element with a spread value on the right):
The spread value lets you extend or contract the shadow in all directions by the amount specified. In this example, a negative value is pulling the shadow back in all directions. The result is that we can just see the shadow at the bottom of the right example, instead of seeing the blur “leak” out on all sides.
You can read the W3C specification for the box-shadow property here: http://www.w3.org/TR/css3-background/#the-box-shadow.
Right, so that’s shadows. We will go on to deal with more shadows when we look at drop-shadow as part of CSS filters. For now, let’s move on to gradients.
Background gradients
In days gone by, to achieve a background gradient on an element, it was necessary to tile a thin graphical slice of the gradient. As graphics resources go, it’s quite an economical tradeoff. An image, only a pixel or two wide, isn’t going to break the bandwidth bank and on a single site, it can be used on multiple elements.
However, if we need to tweak the gradient, it still requires round trips to the graphics editor. Plus, occasionally, content might “break out” of the gradient background, extending beyond the image’s fixed size limitations. This problem is compounded with a responsive design, as sections of a page may increase at different viewports.
With a CSS background-image gradient, however, things are far more flexible. As part of the CSS Image Values and Replaced Content Module Level 3, CSS enables us to create linear and radial background gradients. Let’s look at how we can define them.
The specification for CSS Image Values and Replaced Content Module Level 3 can be found at http://www.w3.org/TR/css3-images/.
Linear-gradient notation
The linear-gradient notation, in its simplest form, looks like this:
.linear-gradient {</pre> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> background: linear-gradient(red, blue);</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">}</p> <pre>
This will create a linear gradient that starts at red (the gradient starts from the top by default) and fades to blue.
Specifying gradient direction
Now, if you want to specify a direction for the gradient, there are a couple of ways to do this. The gradient will always begin in the opposite direction to where you are sending it. However, when no direction is set, a gradient will always default to a top to bottom direction. For example:
</pre> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">.linear-gradient {</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> background: linear-gradient(to top right, red, blue);</p> <pre><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">} </span>
In this instance, the gradient heads to the top right. It starts red in the bottom left corner and fades to blue at the top right.
If you’re more mathematically minded, you may believe it would be comparable to write the gradient like this:
</pre> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">.linear-gradient {</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> background: linear-gradient(45deg, red, blue);</p> <pre><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">} </span>
However, keep in mind that on a rectangular box, a gradient that heads “to top right” (always the top right of the element it’s applied to) will end in a slightly different position than “45deg” (always 45 degrees from its starting point).
It’s worth knowing you can also start gradients before they are visible within a box. For example:
</pre> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">.linear-gradient {</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> background: linear-gradient(red -50%, blue);</p> <pre><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">} </span>
This would render a gradient as if it had started before it was even visible inside the box.
We actually used a color stop in the previous example to define a place where a color should begin and end, so let’s look at those more fully.
Color stops
Perhaps the handiest thing about background gradients is color stops. They provide the means to set which color is used at which point in a gradient. With color stops, you can specify something as complex as you are likely to need. Consider this example:
</pre> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">.linear-gradient {</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> margin: 1rem;</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> width: 400px;</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> height: 200px;</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> background: linear-gradient(</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> #f90 0,</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> #f90 2%,</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> #555 2%,</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> #eee 50%,</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> #555 98%,</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> #f90 98%,</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> #f90 100%</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> );</p> <pre><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">} </span>
Here’s how that linear-gradient renders:
In this example, a direction has not been specified, so the default top to bottom direction applies.
Color stops inside a gradient are written comma separated and defined by giving first the color, and then the position of the stop. It’s generally advisable not to mix units in one notation, but you can. You can have as many color stops as you like and colors can be written as a keyword, hex, RGBA, or HSLA value.
Note that there have been a number of different background gradient syntaxes over the years, so this is one area that is particularly difficult to write fallbacks for by hand.
At the risk of sounding like a broken record (kids, if you don’t know what a “record” is, ask Mom or Dad), make your life easier with a tool like Autoprefixer. This lets you write the current W3C standard syntax (as detailed previously) and it will automatically create the prior versions for you.
You can read the W3C specification for linear background gradients at http://www.w3.org/TR/css3-images/#linear-gradients.
Having covered linear background gradients, let’s now check out radial background gradients.
Radial background gradients
It’s equally simple to create a radial gradient in CSS. These typically begin from a central point and spread out smoothly in an elliptical or circular shape.
Here’s the syntax for a radial background gradient:
</pre> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">.radial-gradient {</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> margin: 1rem;</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> width: 400px;</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> height: 200px;</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> background: radial-gradient(12rem circle at bottom, yellow, orange, red);</p> <pre><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">} </span>
Breakdown of radial gradient syntax
After specifying the property (background:), we begin the radial-gradient notation. To start with, before the first comma, we define the shape or size of the gradient and the position. We used 12rem circle for the shape and size previously, but consider some other examples:
- 5em would be a circle 5em in size. It’s possible to omit the circle part if giving just a size.
- circle would be a circle the full size of the container (the size of a radial gradient defaults to farthest-corner if omitted—more on sizing keywords shortly).
- 40px 30px would be an ellipse as if drawn inside a box 40px wide by 30px tall.
- ellipse would create an ellipse shape that would fit within the element.
Next, after the size and/or shape, we define the position. The default position is center, but let’s look at some other possibilities and how they can be defined:
- at top right starts the radial gradient from the top right.
- at right 100px top 20px starts the gradient 100px from the right edge and 20px from the top edge.
- at center left starts it halfway down the left side of the element.
We end our size, shape, and position “parameters” with a comma and then define any color stops, which work in exactly the same manner as they do with linear gradients.
To simplify the notation: size, shape, and position before the first comma, then as many color stops as needed after it (with each stop separated with commas).
When it comes to sizing things such as gradients, CSS provides some keywords that are often a better choice than hardcoded values, especially with responsive designs.
Handy “extent” keywords for responsive sizing
For responsive work, you may find it advantageous to size gradients proportionally rather than using fixed pixel dimensions. That way, you know you are covered (both literally and figuratively) when the size of elements change. There are some handy sizing keywords that can be applied to gradients.
You would write them like this, in place of any size value:
background: radial-gradient(closest-side circle at center, #333, blue);
Here is what each of them does:
- closest-side: The shape meets the side of the box nearest to the center (in the case of circles), or meets both the horizontal and vertical sides that are closest to the center (in the case of ellipses).
- closest-corner: The shape meets exactly the closest corner of the box from its center.
- farthest-side: The opposite of closest-side, in that rather than the shape meeting the nearest size, it’s sized to meet the one farthest from its center (or both the furthest vertical and horizontal side in the case of an ellipse).
- farthest-corner: The shape expands to the farthest corner of the box from the center.
- cover: Identical to farthest-corner.
- contain: Identical to closest-side.
You can read the W3C specification for radial background gradients at http://www.w3.org/TR/css3-images/#radial-gradients.
The cheat’s way to perfect CSS linear and radial gradients
If defining gradients by hand seems like hard work, there are some great online gradient generators. My favorite is http://www.colorzilla.com/gradient-editor/. It uses a graphics editor style GUI, allowing you to pick your colors, stops, gradient style (linear and radial gradients are supported), and even the color space (hex, RGB(A), HSL(A)) you’d like the final gradient in. There are also loads of preset gradients to use as starting points. Still not convinced? How about the ability to generate a CSS gradient based on the gradient values in an existing image? Thought that might swing it for you.
Repeating gradients
CSS also gives us the ability to create repeating background gradients. Let’s take a look at how it’s done:
</pre> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">.repeating-radial-gradient {</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> background: repeating-radial-gradient(black 0px, orange 5px, red 10px);</p> <pre><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">} </span>
Here’s how that looks (don’t look for long, it may cause nausea):
Firstly, prefix the linear-gradient or radial-gradient with repeating-. It then follows the same syntax as a normal gradient. Here, I’ve used pixel distances between the black, orange, and red colors (0px, 5px, and 10px, respectively), but you could also choose to use percentages.
You can read the W3C information on repeating gradients at http://www.w3.org/TR/css3-images/#repeating-gradients.
There’s one more way of using background gradients I’d like to share with you.
Background gradient patterns
Although I’ve often used subtle linear gradients in designs, I’ve found less practical use for radial gradients and repeating gradients. However, clever folks out there have harnessed the power of gradients to create background gradient patterns. Let’s look at an example from CSS Ninja, Lea Verou’s collection of CSS background patterns, available at http://lea.verou.me/css3patterns/:
</pre> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">.carbon-fibre {</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> margin: 1rem;</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> width: 400px;</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> height: 200px;</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> background: radial-gradient(black 15%, transparent 16%) 0 0, radial-gradient(</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> black 15%,</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> transparent 16%</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> ) 8px 8px,</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> radial-gradient(rgba(255, 255, 255, 0.1) 15%, transparent 20%) 0 1px, radial-gradient(</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> rgba(255, 255, 255, 0.1) 15%,</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> transparent 20%</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> ) 8px 9px;</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> background-color: #282828;</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> background-size: 16px 16px;</p> <pre><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">} </span>
Here’s what that gives us in the browser, a carbon fiber background effect:
How about that? Just a few lines of CSS and we have an easily editable, responsive, and scalable background pattern.
You might find it useful to add background-repeat: no-repeat at the end of the rule to better understand how it works.
As ever, thanks to media queries, different declarations can be used for different responsive scenarios. For example, although a gradient pattern might work well at smaller viewports, it might be better to go with a plain background at larger ones:
</pre> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">@media (min-width: 45rem) {</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> .carbon-fibre {</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> background: #333;</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> }</p> <pre><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">} </span>
So far, we have looked at many ways of creating background images using just CSS; however, whether that is linear gradients, radial gradients, or repeating gradients, it is still just one background image. What about when you want to deal with more than one background image at the same time?
Multiple background images
Although a little out of fashion at the moment, it used to be a fairly common design requirement to build a page with a different background image at the top of the page than at the bottom. Or perhaps to use different background images for the top and bottom of a content section within a page. Back in the day, with CSS 2.1, achieving this effect typically required additional markup (one element for the header background and another for the footer background).
With CSS, you can stack as many background images as you need on an element.
Here’s the syntax:
.bg {</pre> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> background: url('../img/1.png'), url('../img/2.png'), url('../img/3.png');</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">}</p> <pre>
As with the stacking order of multiple shadows, the image listed first is layered nearest to the top, or closer to the user, in the browser. You can also add a general color for the background in the same declaration if you wish, like this:
.bg {</pre> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> background: url('../img/1.png'), url('../img/2.png'),</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;"> url('../img/3.png') left bottom, black;</p> <p style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; white-space: normal;">}</p> <pre>
Specify the color last and this will show up below every image specified in the preceding code snippet.
With the multiple background images, as long as your images have transparency, any partially transparent background images that sit on top of another will show through below. However, background images don’t have to sit on top of one another, nor do they all have to be the same size.