CSS: Effects

CSS: Effects



color property defines the foreground color of an element (in general). It is generally used for text but could also apply to borders or outlines for instance when their respective border-color or outline-color hasn't been specified.

h1 {
    color: #4457ff;

color is automatically inherited by child elements, except for <a> elements.

A color value can be defined in various formats:

  • color keyword: red, blue, purple, ... (full list here)
  • hex value: #FFAB01 (or shorthand notation #ffcc00 same as #fc0)
  • rgb value: rgb(255, 0, 2) or rgb(50%, 0%, 5%)
  • [CSS3] rgba (see below)
  • [CSS3] hsl (or hue, saturation and lightness) or hsla (same as rgba but for hsl)


CSS3 has introduced a new way to specify a color with transparency with rgba.

div {
    /* the alpha parameter here controls the the transparency from 0 (transparent) to 1 (opaque) */
    background: rgba(10, 200, 100, 0.5);

CSS3 has also introduced opacity to control the transparency of any element in the page.

img.choice {
    /* Value between 0 (transparent) to 1 (opaque) */
    opacity: 0.6;

Note that the transparency applied with rgba does not affect child elements whereas using opacity does.


CSS3 introduced an easy solution to generate smooth gradients of colors.

body {
    /* Top to bottom color gradient */
    background: linear-gradient(blue, green);
    /* Left to right color gradient */
    background: linear-gradient(to right, blue, green); /* or with angle: (90deg, blue, green)
    /* Diagonal color gradient */
    background: linear-gradient(to top right, blue, green);
    /* Top to bottom gradient with more colors */
    background: linear-gradient(blue, green, yellow);
    /* Top to bottom gradient with positionnal colors stops */
    background: linear-gradient(blue, green 25%, yellow 70%);

You can also repeat a gradient with repeating-linear-gradient (same syntax) or use radial-gradient for concentric gradients.


CSS has several properties to style the background of an element.

body {
    /* Set the background color of an element.
     * The definition of the color value respects the rules as for `color` property.
     * As opposed to `color`, `background-color` is not inherited by child elements 
     * but since the default value is `transparent`, the parent's background color will 
     * still be visible by default. */
    background-color: #4457ff;
    /* Set an image as a background of an HTML element. 
     * Several additional properties are available to tune the rendering (see below) */
    background-image: url("images/tile.png");
    /* By default, the image is repeated horizontally and vertically to fill the entire 
     * area of an element. `background-repeat` lets you change this behavior.
     * `repeat` (default) : repeats on x and y
     * `repeat-x` (default) : repeats on x only
     * `repeat-y` (default) : repeats on y only
     * `no-repeat` (default) : no repeat, a single image is displayed and doesn't fill the page (unless big enough) */
    background-repeat: no-repeat;
    /* By default, the image is displayed at coordinates (0,0). With `background-position` 
     * you can set another location. The position is defined with 2 values : first for horizontal, 
     * second for vertical. The values can be expressed with keywords (`left|right|top|bottom`), 
     * percents (`10% 0;`) or any length value (`px`, `em`, ...). */
    background-position: right top;
    /* Determines whether the image is fixed with regard to the viewport or scrolls along the containing block. */
    background-attachment: fixed;

    /** CSS3 **/

    /* Adjust the size of the background image.
     * 'contain': scale as large as possible by keeping original image ratio
     * 'cover': scale to the smallest possible size to fill the container (with repeat) by keeping
     *          original image ratio
     * 'auto': scales automatically by keeping original image ratio
     * <length value or percentage>: stretches the width of the image (height becomes auto)
     * <2 length values or 2 persentages> : stretches the width and the length of the image */
    background-size: 1.5em;

    /* Delimitates where the background is applied in the Box Model
     * 'border-box' : applies to all layers of the Box Model (except margin)
     * 'padding-box' : applies to content area and padding layers (border is excluded)
     * 'content-box' : applies to content area (padding and border are excluded) */
    background-clip: content-box;

    /* Define where the image origin (x:0, y:0) should be positionned in the Box Model.
     * Values are identical to 'background-clip' (border-box, padding-box and content-box) */
    background-origin: border-box;


Since adding every background- property to the CSS is verbose, you have the option to use the shorthand notation:

/* background: color image repeat attachment position; */
body {
    background: #f0e68c url("images/smiley.png") no-repeat fixed 250px 25px;

    /** CSS3 **/

    /* Use layering to display images on top of each others to compose the
     * background image. You can have as many layers as you like. */
    background: url("images/cheese.png") no-repeat center, /* top layer */
                url("images/ham.png") no-repeat center,
                url("images/sauce.png") no-repeat center,
                url("images/dough.png") no-repeat center, /* bottom layer */
                lightblue; /* background color */


CSS provides several properties to set a font.

body {
    /* Select the font and specify fallback fonts with ',' */
    font-family: Arial, Helvetica, "Times New Roman", sans-serif;
    /* Define if the text should be normal, italic or oblique 
    * 'italic' uses an italic version of the font whereas 'oblique' 
    * skews the 'normal' font*/
    font-style: italic;
    /* Set font size with pixels, percents, any length value ('px', 'em',..), 
       special keywords (xx-small, x-small, small, medium, large, x-large, xx-large)
       or viewport units 'vw', 'vh'.
       It is recommended to use percents or 'em' */
    font-size: 14px;
    /* Set he boldness of the font with either keywords (normal, bold, bolder,
     * lighter) or numeric values (100-900) */
    font-weight: 400; /* same as 'normal' */
    /* Pick the small caps variation where the lowecase characters are displayed
     * as smaller versions of the corresponding upper case characters */
    font-variant: small-caps;

Font size techniques

em is a unit relative to the parent element. 1em equals to the font size defined in the parent's element, 2em is two times the parent's font size and so on.
CSS3 introduced rem which is a unit relative to the root element (<html>). A popular technique mixes percents and rem to easily convert em to pixels.

html {
    /* The default font-size is 16 px */
    font-size: 62.5%;    /* font-size becomes 10px (1rem) */
/* remaining sizes are then easy to convert */
p {
    font-size: 1.4rem;    /* 1.4rem = 14px */
p span {
    font-size: 2rem;    /* 2rem = 20px (not 28px) */


Box shadow

With CSS3 you have a simple syntax to add one (or multiple, comma-separated) shadows to your box.

div {
    /* Add a shadow under the div, shifed by x=7px and y=8px, with a blur radius of 10px
     * in gray. The syntax is <offset x> <offset y> <blur radius> <color>.
     * Blur radius defines how sharp the edges of the shadow are. The higher, the smoother. */
    box-shadow: 7px 8px 10px gray;

Text shadow

On the same principle, you can also add a shadow on a text.

h3 {
    /* Same syntax as 'box-shadow' */
    text-shadow: 7px 8px 10px blue;

Geometrical Transforms

In CSS3, you can simply apply 2D or 3D effects on your elements, such as rotating, moving or skewing. The edited element will not occupy more space on the page as its Box will remain as if no effect was applied but it can overlap with its siblings.

h1 {
    /* Shift an element on X and Y axes.
     * If the second parameter (y) isn't specified, it is considered to be 0.
     * See also translateX and translateY */
    transform: translate(10px, 60px); 
    /* The 3d variant lets you specify a shift value along Z axis. However,
     * the effect on Z is only meaningful if it is combined with 'perspective' or 
     * 'perspective-origin' that modify the size of the element as it goes higher on Z.
     * See also translateZ. */
    transform: translate3d(10px, 60px, 60px); 
    /* Rotate an element around it origin.
     * Negative values are supported.
     * See also rotateX and rotate Y */
    transform: rotate(30deg); 
    /* The 3d variant accepts [x,y,z] vectors as inputs and an angle.
     * It rotates the element around the selected axes with the given magnitude and the specified angle 
     * See also rotateZ. */
    transform: rotate3d(0, 1, 2, 30deg); /* rotates 2x more on z axis than on y */
    /* Increase or decrease the size of an element proportionnally on x and y 
     * If the second parameter (y) isn't specified, it is considered to be 0.
     * See also scaleX and scaleY */
    transform: scale(1.2, 0.3);
    /* The 3d variant accepts [x,y,z] vectors as inputs. The scaling is applied with the 
     * provided magnitudes along each axis. 
     * See also scaleZ. */
    transform: scale3d(1, 4, 1);
    /* Skew the element along x and y yith the specified angle.
     * If the second parameter (y) isn't specified, it is considered to be 0.
     * See also skewX and skewY */
    transform: skew(10deg);
    /* And of course, you can chain several effect */
    transform: translate(10px, 60px) rotate(30deg) skew(10deg);


In CSS3, Transitions allow you to add delays and effects when the styling of an element gets updated (usually triggered with user interaction). The result is that instead of seeing the visual appearance changing instantly, it will smoothly occur over a specified amount of time.

Any property with a value that is a number, length, percentage or color should be animatable.

button {
    background: pink;
    border-color: green;
    /* To apply a transition, you first need to select the properties for which
     * you want to add a transition. 
     * Note that we're using shorthand properties here which means that the transition will apply 
     * to all underlying css properties */
    transition-property: background, border;
    /* Then you need to set a duration for the transition (in seconds 's' or milliseconds 'ms')
     * Note that the coma separates the duration for each property 
     * specified above.*/
    transition-duration: 1s, 500ms;
    /* Optionnally, you can set a start delay so that the transition does not 
     * start immediately (in seconds 's' or milliseconds 'ms') */
    transition-delay: 0.1s, 0s;
    /* Optionnally, you can pick from different transition styles which differ in how
     * the value change is applied. By default, the transition is linear, meaning that the 
     * value changes gradually over time but you have several other options.
     * 'linear' (default)
     * 'ease': value changes quickly at the beginning and slows down at the middle
     * 'ease-in': value changes slowly at the beginning and accelerates at the end
     * 'ease-out': value changes quickly at the beginning and slows down at the end
     * 'ease-in-out': value changes slowly at the beginning, accelerates at the middle and slows down at the end
     * 'cubci-bezier(n, n, n, n)': manual speed curve with values from 0 to 1 */
    transition-timing-function: ease-out;
button:hover {
    background: red;
    border-color: blue;


All transition properties can be set at once with the shorthand notation.

button {
    /* Syntax is : property duration timing-function delay 
    * As usual, if a value is missing its default value is used instead. The default value
    * for 'property' is 'all', meaning that all css properties will be affected */
    transition: background 1s ease-out 0.1s;


Transitions are great for simple animations but when you need more granularity on what property should change at a given moment in the transition, animation offer all the flexibility you need. Animations consist of @keyframes which describe the style to apply at a given time of the animation.

h1 {
    /* Animations only apply to non-static positions */
    position: absolute;
    /* Each animation is identified with a name. You can see the declaration
     * of the animation further below */
    animation-name: moveright;
    /* Just like 'transitions', animation have a duration in 's' or 'ms' */
    animation-duration: 3s;
    /* [Optional] Same as 'transition-timing-function */
    animation-timing-function: ease;
    /* [Optional] Same as 'transition-delay */
    animation-delay: 200ms;
    /* [Optional] Set the number of times the animation should play (each iteration 
     * will last for 3s here). Note that you could also use 'infinite' so that the 
     * animation never ends */
    animation-iteration-count: 3;
    /* [Optional] If the number of iteration is superior to 1, the direction let you 
    * chose in which direction the animation should play.
    * 'normal' (default)
    * 'reverse': starts at the end and ends at the beginning
    * 'alternate': plays forward on first cycle and reverse in second and continues alternating
    * 'alternate-reverse': same as alternate but in reverse order */
    animation-direction: alternate;
    /* [Optional] Specifies if the styles defined in the animation applies to the element 
    * before the beginning of the animation and/or after the end of the animation.
    * 'none' (default)
    * 'forwards': The final style applied by the animation is persisted on the element. In this example,
    *             the text would stick to the right after third iteration.
    * 'backwards': The initial style of the animation is applied to the element before the animation starts
    *             (only visible if you've set a delay)
    * 'both': combination of 'forwards' and 'backwards' */
    animation-fill-mode: none;
    /* [Optional] This is mostly for javascript as it lets you pause or run the animation 
    * Values: 'running' (default) or 'paused': */
    animation-play-state: running;

/* An animation is an 'at-statement' with entries describing the style 
 * at each step. In the example below, we use 'from' and 'to' for the beginning
 * and end states but you could have chosen to use percentage (0% and 100%) instead.
 * You get the idea, with percentage you can add additional moment (25%, 53%, ...)
 * and fine-tune your animation.
 * This animation will move the title from left to right for 3 seconds. The final position of the text
 * will be the one it occupies in the normal flow which means that here, the text will come back
 * to where it started.*/
@keyframes moveright {
    from { left: 0 };
    to { right: 60% }


You can pass all properties at once for more consistency.

h1 {
    /* Syntax: name duration timing-function delay count direction */
    animation: moveright 3s ease 200ms 3 alternate;