• Skip to main content
  • Select language
  • Skip to search
MDN Web Docs
  • Technologies
    • HTML
    • CSS
    • JavaScript
    • Graphics
    • HTTP
    • APIs / DOM
    • WebExtensions
    • MathML
  • References & Guides
    • Learn web development
    • Tutorials
    • References
    • Developer Guides
    • Accessibility
    • Game development
    • ...more docs
Learn web development
  1. MDN
  2. Learn web development
  3. CSS
  4. Styling boxes
  5. Advanced box effects

Advanced box effects

In This Article
  1. Box shadows
    1. A simple box shadow
    2. Multiple box shadows
    3. Other box shadow features
  2. Filters
  3. Blend modes
    1. background-blend-mode
    2. mix-blend-mode
  4. -webkit-background-clip: text
  5. Active learning: experiment with some effects
  6. Summary
Previous Overview: Styling boxes Next

 

This article acts as a box of tricks, providing an introduction to some of the advanced features available for styling boxes that don't fit into the other categories above — like box shadows, blend modes and filters.

Prerequisites: HTML basics (study Introduction to HTML) and an idea of how CSS works (study Introduction to CSS.)
Objective: To get an idea about how to use advanced box effects, and know about some of the nascent styling tools that are appearing in the CSS language.

Box shadows

Back in our Styling text module, we looked at the text-shadow property, which allows you to apply one or more drop shadows to the text of an element. Well, an equivalent property exists for boxes — box-shadow allows you to apply one or more drop shadows to an actual element box. Like text shadows, box shadows are supported pretty well across browsers, but only in IE9+. Your users of older IE versions might just have to cope with no shadows, so just test your designs to make sure your content is legible without them.

You can find the examples in this section at box-shadow.html (see the source code too).

A simple box shadow

Let's look at a simple example to get things started. First, some HTML:

<article class="simple">
  <p><strong>Warning</strong>: The thermostat on the cosmic transcender has reached a critical level.</p>
</article>

Now the CSS:

p {
  margin: 0;
}
article {
  max-width: 500px;
  padding: 10px;
  background-color: red;
  background-image: linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,0.25));
}  
.simple {
  box-shadow: 5px 5px 5px rgba(0,0,0,0.7);
}

This gives us the following result:

You'll see that we've got four items in the box-shadow property value:

  1. The first length value is the horizontal offset — the distance to the right the shadow is offset from the original box (or left, if the value is negative).
  2. The second length value is the vertical offset — the distance downwards that the shadow is offset from the original box (or upwards, if the value is negative).
  3. The third length value is the blur radius — the amount of blurring applied to the shadow.
  4. The color value is the base color of the shadow.

You can use any length and color units that would make sense to do so to define these values.

Multiple box shadows

You can also specify multiple box shadows in a single box-shadow declaration, by separating them with commas:

<article class="multiple">
  <p><strong>Warning</strong>: The thermostat on the cosmic transcender has reached a critical level.</p>
</article>
p {
  margin: 0;
}
article {
  max-width: 500px;
  padding: 10px;
  background-color: red;
  background-image: linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,0.25));
}  
.multiple {
  box-shadow: 1px 1px 1px black,
              2px 2px 1px black,
              3px 3px 1px red,
              4px 4px 1px red,
              5px 5px 1px black,
              6px 6px 1px black;
}

Now we get this result:

We've done something fun here by creating a raised box with multiple coloured layers, but you could use it in any way you want, for example to create a more realistic look with shadows based on multiple light sources.

Other box shadow features

Unlike text-shadow, box-shadow has an inset keyword available — putting this at the start of a shadow declaration causes it to become an inner shadow, rather than an outer shadow. Let's have a look and see what we mean.

First, we'll go with some different HTML for this example:

<button>Press me!</button>
button {
  width: 150px;
  font-size: 1.1rem;
  line-height: 2;
  border-radius: 10px;
  border: none;
  background-image: linear-gradient(to bottom right, #777, #ddd);
  box-shadow: 1px 1px 1px black,
              inset 2px 3px 5px rgba(0,0,0,0.3),
              inset -2px -3px 5px rgba(255,255,255,0.5);
}
button:focus, button:hover {
  background-image: linear-gradient(to bottom right, #888, #eee);
}
button:active {
  box-shadow: inset 2px 2px 1px black,
              inset 2px 3px 5px rgba(0,0,0,0.3),
              inset -2px -3px 5px rgba(255,255,255,0.5);
}

This gives us the following result:

Here we've set up some button styling along with focus/hover/active states. The button has a simple black box shadow set on it by default, plus a couple of inset shadows, one light and one dark, placed on opposite corners of the button to give it a nice shading effect.

When the button is pressed in, the active state causes the first box shadow to be swapped for a very dark inset shadow, giving the appearance of the button being pressed in.

Note: There is another item that can be set in the box-shadow value — another length value can be optionally set just before the color value, which is a spread radius. If set, this causes the shadow to become bigger than the original box. It is not very commonly used, but worth mentioning.

Filters

CSS Filters provide a way to apply filters to an element in the same way as you might apply a filter to a layer in a graphics package like Photoshop. There are a number of different options available, and you can read all about them in greater detail on the filter reference page. In this section, we'll explain to you the syntax, and show you how much fun the results can be.

Basically, a filter can be applied to any element, block or inline — you just use the filter property, and give it a value of a particular filter function. Some of the filter options available do very similar things to other CSS features, for example drop-shadow() works in a very similar way and gives a similar effect to box-shadow or text-shadow.  The really nice thing about filters however, is that they work on the exact shapes of the content inside the box, not just the box itself as one big chunk, which can look nicer, although it may not always be what you want. Let's use a simple example to illustrate what we mean:

First, some simple HTML:

<p class="filter">Filter</p>
<p class="box-shadow">Box shadow</p>

And now some CSS to a apply a drop shadow to each:

p {
  margin: 1rem auto;
  padding: 20px;
  width: 100px;
  border: 5px dashed red;
}
.filter {
  -webkit-filter: drop-shadow(5px 5px 1px rgba(0,0,0,0.7));
  filter: drop-shadow(5px 5px 1px rgba(0,0,0,0.7));
}
.box-shadow {
  box-shadow: 5px 5px 1px rgba(0,0,0,0.7);
}

This gives us the following result:

As you can see, the filter drop-shadow follows the exact shape of the text and border dashes. The box shadow just follows the square of the box.

Some other things to note:

  • Filters are very new — they are supported in most modern browsers, including Microsoft Edge, but they are not supported in Internet Explorer at all. If you use filters in your designs, you should therefore make sure your content is usable without the filters.
  • You'll see that we've included a version of the filter property with -webkit- prefixed. This is called a Vendor Prefix, and is used sometimes by a browser before it finalizes its implementation of a new feature, to support that feature and experiment with it while not clashing with the non-prefixed version. Vendor prefixes were never intended to be used by web developers, but they do get used sometimes on production pages if experimental features are really desired. In this case, the -webkit- version of the property is currently required for Chrome/Safari/Opera support, while Edge and Firefox use the final, non-prefixed version.

Note: If you do decide to use prefixes in your code, make sure you include all the prefixes required as well as the non-prefixed version, so the maximum number of browsers possible can use the feature, and when browsers later drop the prefixes, they can use the non-prefixed version too. Also be warned that these experimental features might change, so your code might break. It is really best to just experiment with these features until the prefixes are removed.

You can see some other filter examples at filters.html (also see the source code).

Blend modes

CSS blend modes allow us to add blend modes to elements that specify a blending effect when two elements overlap — the final color shown for each pixel will be the result of a combination of the original pixel color, and that of the pixel in the layer underneath it. Blend modes are again very familiar to users of graphics applications like Photoshop.

There are two properties that use blend modes in CSS:

  • background-blend-mode, which blends together multiple background images and colors set on a single element.
  • mix-blend-mode, which blends together the element it is set on with elements it is overlapping — both background and content.

You can find a lot more examples than are available here in our blend-modes.html example page (see source code), and on the <blend-mode> reference page.

Note: Blend modes are also very new, and slightly less well supported than filters. There is no support as yet in Edge, and Safari only supports some of the blend mode options.

background-blend-mode

Again, let's look at some examples so we can understand this better. First, background-blend-mode — here we'll show a couple of simple <div>s, so you can compare the original with the blended version:

<div>
</div>
<div class="multiply">
</div>

Now some CSS — we are adding two background images to the <div>s: a linear gradient and a png:

div {
  width: 280px;
  height: 130px;
  padding: 10px;
  margin: 10px;
  display: inline-block;
  background: url(https://mdn.mozillademos.org/files/13090/colorful-heart.png) no-repeat center 20px;
  background-color: green;
}
.multiply {
  background-blend-mode: multiply;
}

The result we get is this — you can see the original on the left, and the multiply blend mode on the right:

mix-blend-mode

Now let's look at mix-blend-mode. Here we'll present the same two <div>s, but each one is now sat on top of a simple <div> with a purple background, to show how the elements will blend together:

<article>
  No mix blend mode
  <div>
  </div>
  <div>
  </div>
</article>
<article>
  Multiply mix
  <div class="multiply-mix">
  </div>
  <div>
  </div>
</article>

Here's the CSS we'll style this with:

article {
  width: 300px;
  height: 180px;
  margin: 10px;
  position: relative;
  display: inline-block;
}
div {
  width: 250px;
  height: 130px;
  padding: 10px;
  margin: 10px;
}
article div:first-child {
  position: absolute;
  top: 10px;
  left: 0;
  background: url(https://mdn.mozillademos.org/files/13090/colorful-heart.png) no-repeat center 20px;
  background-color: green;
}
article div:last-child {
  background-color: purple;
  position: absolute;
  bottom: -10px;
  right: 0;
  z-index: -1;
}
.multiply-mix {
  mix-blend-mode: multiply;
}

This gives us the following results:

You can see here that the multiply mix blend has blended together not only the two background images, but also the color from the <div> below it too.

Note: Don't worry if you don't understand some of the layout properties above, like position, top, bottom, z-index, etc. We will cover these in great detail in our CSS Layout module.

-webkit-background-clip: text

Another nascent feature we thought we'd mention briefly before moving on (currently supported in Chrome, Safari, and Opera, and being implemented in Firefox) is the text value for background-clip. When used along with the proprietary -webkit-text-fill-color: transparent; feature, this allows you to clip background images to the shape of the element's text, making for some nice effects. This is not an official standard, but has been implemented across multiple browsers, as it is popular, and used fairly widely by developers. When used in this context, both of the properties would require a -webkit- vendor prefix, even for Non-Webkit/Chrome-based browsers:

.text-clip {
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

So why have other browsers implemented a -webkit- prefix? Mainly for browser compatibility — so many web developers have started implementing web sites with -webkit- prefixes that it started to look like the other browsers were broken, whereas in actual fact they were following the standards. So they were forced to implement a few such features. This highlights the danger of using non-standard and/or prefixed CSS features in your work — not only do they cause browser compatibility issues, but they are also subject to change, so your code could break at any time. It is much better to stick to the standards.

If you do want to use such features in your production work, make sure to test across browsers thoroughly and check that, where these features don't work, the site is still usable.

Note: For a full -webkit-background-clip: text code example, see background-clip-text.html (see also the source code).

Active learning: experiment with some effects

Now it's your turn. For this active learning, we want you to experiment with some of the effects you've read about above, using the provided code below.

If you make a mistake, you can always reset the example using the Reset button.

Playable code
<div class="body-wrapper" style="font-family: 'Open Sans Light',Helvetica,Arial,sans-serif;">
  <h2>HTML Input</h2>
  <textarea id="code" class="html-input" style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;"><div class="style-me">
</div></textarea>
  <h2>CSS Input</h2>
  <textarea id="code" class="css-input" style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;">.style-me {
  width: 280px;
  height: 130px;
  padding: 10px;
  margin: 10px;
  display: inline-block;
  background-color: red;
  background: url(https://mdn.mozillademos.org/files/13090/colorful-heart.png) no-repeat center 20px,
              linear-gradient(to bottom right, #f33, #a33);
} </textarea>
  <h2>Output</h2>
  <div class="output" style="width: 90%;height: 15em;padding: 10px;border: 1px solid #0095dd;overflow:hidden;"></div>
  <div class="controls">
    <input id="reset" type="button" value="Reset" style="margin: 10px 10px 0 0;">
  </div>
</div>
var htmlInput = document.querySelector(".html-input");
var cssInput = document.querySelector(".css-input");
var reset = document.getElementById("reset");
var htmlCode = htmlInput.value;
var cssCode = cssInput.value;
var output = document.querySelector(".output");
var styleElem = document.createElement('style');
var headElem = document.querySelector('head');
headElem.appendChild(styleElem);
function drawOutput() {
  output.innerHTML = htmlInput.value;
  styleElem.textContent = cssInput.value;
}
reset.addEventListener("click", function() {
  htmlInput.value = htmlCode;
  cssInput.value = cssCode;
  drawOutput();
});
htmlInput.addEventListener("input", drawOutput);
cssInput.addEventListener("input", drawOutput);
window.addEventListener("load", drawOutput);

Summary

We hope this article has proved to be fun — playing with shiny toys generally is, and it is always interesting to see what kinds of tools are just becoming available in cutting edge browsers. You've reached the end of the Styling boxes articles, so next up you'll test your box syling skills with our assessments.

Previous Overview: Styling boxes Next

 

Document Tags and Contributors

Tags: 
  • Article
  • Beginner
  • Blend modes
  • box shadows
  • Boxes
  • CodingScripting
  • CSS
  • effects
  • Filters
  • Styling
 Contributors to this page: qdirks, y0u-s, chrisdavidmills, kiriakosv, richardzacur, Sebastianz
 Last updated by: qdirks, Jun 10, 2017, 11:22:52 PM
See also
  1. Complete beginners start here!
  2. Getting started with the Web
    1. Getting started with the Web overview
    2. Installing basic software
    3. What will your website look like?
    4. Dealing with files
    5. HTML basics
    6. CSS basics
    7. JavaScript basics
    8. Publishing your website
    9. How the Web works
  3. HTML — Structuring the Web
  4. Introduction to HTML
    1. Introduction to HTML overview
    2. Getting started with HTML
    3. What's in the head? Metadata in HTML
    4. HTML text fundamentals
    5. Creating hyperlinks
    6. Advanced text formatting
    7. Document and website structure
    8. Debugging HTML
    9. Assessment: Marking up a letter
    10. Assessment: Structuring a page of content
  5. Multimedia and embedding
    1. Multimedia and embedding overview
    2. Images in HTML
    3. Video and audio content
    4. From object to iframe — other embedding technologies
    5. Adding vector graphics to the Web
    6. Responsive images
    7. Assessment: Mozilla splash page
  6. HTML tables
    1. HTML tables overview
    2. HTML table basics
    3. HTML Table advanced features and accessibility
    4. Assessment: Structuring planet data
  7. CSS — Styling the Web
  8. Introduction to CSS
    1. Introduction to CSS overview
    2. How CSS works
    3. CSS syntax
    4. Selectors introduction
    5. Simple selectors
    6. Attribute selectors
    7. Pseudo-classes and pseudo-elements
    8. Combinators and multiple selectors
    9. CSS values and units
    10. Cascade and inheritance
    11. The box model
    12. Debugging CSS
    13. Assessment: Fundamental CSS comprehension
  9. Styling text
    1. Styling text overview
    2. Fundamental text and font styling
    3. Styling lists
    4. Styling links
    5. Web fonts
    6. Assessment: Typesetting a community school homepage
  10. Styling boxes
    1. Styling boxes overview
    2. Box model recap
    3. Backgrounds
    4. Borders
    5. Styling tables
    6. Advanced box effects
    7. Assessment: Creating fancy letterheaded paper
    8. Assessment: A cool-looking box
  11. CSS layout
    1. CSS layout overview
    2. Introduction
    3. Floats
    4. Positioning
    5. Practical positioning examples
    6. Flexbox
    7. Grids
  12. JavaScript — Dynamic client-side scripting
  13. JavaScript first steps
    1. JavaScript first steps overview
    2. What is JavaScript?
    3. A first splash into JavaScript
    4. What went wrong? Troubleshooting JavaScript
    5. Storing the information you need — Variables
    6. Basic in JavaScript — Numbers and operators
    7. Handling text — Strings in JavaScript
    8. Useful string methods
    9. Arrays
    10. Assessment: Silly story generator
  14. JavaScript building blocks
    1. JavaScript building blocks overview
    2. Making decisions in your code — Conditionals
    3. Looping code
    4. Functions — Reusable blocks of code
    5. Build your own function
    6. Function return values
    7. Introduction to events
    8. Assessment: Image gallery
  15. Introducing JavaScript objects
    1. Introducing JavaScript objects overview
    2. Object basics
    3. Object-oriented JavaScript for beginners
    4. Object prototypes
    5. Inheritance in JavaScript
    6. Working with JSON data
    7. Object building practise
    8. Assessment: Adding features to our bouncing balls demo
  16. Accessibility — Make the web usable by everyone
  17. Accessibility guides
    1. Accessibility overview
    2. What is accessibility?
    3. HTML: A good basis for accessibility
    4. CSS and JavaScript accessibility best practices
    5. WAI-ARIA basics
    6. Accessible multimedia
    7. Mobile accessibility
  18. Accessibility assessment
    1. Assessment: Accessibility troubleshooting
  19. Tools and testing
  20. Cross browser testing
    1. Cross browser testing overview
    2. Introduction to cross browser testing
    3. Strategies for carrying out testing
    4. Handling common HTML and CSS problems
    5. Handling common JavaScript problems
    6. Handling common accessibility problems
    7. Implementing feature detection
    8. Introduction to automated testing
    9. Setting up your own test automation environment
  21. Server-side website programming
  22. First steps
    1. First steps overview
    2. Introduction to the server-side
    3. Client-Server overview
    4. Server-side web frameworks
    5. Website security
  23. Django web framework (Python)
    1. Django web framework (Python) overview
    2. Introduction
    3. Setting up a development environment
    4. Tutorial: The Local Library website
    5. Tutorial Part 2: Creating a skeleton website
    6. Tutorial Part 3: Using models
    7. Tutorial Part 4: Django admin site
    8. Tutorial Part 5: Creating our home page
    9. Tutorial Part 6: Generic list and detail views
    10. Tutorial Part 7: Sessions framework
    11. Tutorial Part 8: User authentication and permissions
    12. Tutorial Part 9: Working with forms
    13. Tutorial Part 10: Testing a Django web application
    14. Tutorial Part 11: Deploying Django to production
    15. Web application security
    16. Assessment: DIY mini blog
  24. Express Web Framework (node.js/JavaScript)
    1. Express Web Framework (Node.js/JavaScript) overview
    2. Express/Node introduction
    3. Setting up a Node (Express) development environment
    4. Express tutorial: The Local Library website
    5. Express Tutorial Part 2: Creating a skeleton website
    6. Express Tutorial Part 3: Using a database (with Mongoose)
    7. Express Tutorial Part 4: Routes and controllers
    8. Express Tutorial Part 5: Displaying library data
    9. Express Tutorial Part 6: Working with forms
    10. Express Tutorial Part 7: Deploying to production
  25. Further resources
  26. Advanced learning material
    1. WebGL: Graphics processing
  27. Common questions
    1. HTML questions
    2. CSS questions
    3. JavaScript questions
    4. How the Web works
    5. Tools and setup
    6. Design and accessibility
  28. How to contribute