Copyright © 2005 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark and document use rules apply.
CSS (Cascading Style Sheets) is a language for describing the rendering of structured documents (such as HTML and XML) on screen, on paper, in speech, etc. This draft contains the proposed functionality for CSS level 3 to describe borders and backgrounds, including borders consisting of images and backgrounds with multiple images. It includes and extends the functionality of CSS level 2 [CSS2], which builds on CSS level 1 [CSS1].
This module replaces two earlier drafts: CSS3 Backgrounds and CSS3 Border.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
The (archived) public mailing list www-style@w3.org (see instructions) is preferred for discussion of this specification. When sending e-mail, please put the text “css3-background” in the subject, preferably like this: “[css3-background] …summary of comment…”
This document was produced by the CSS Working Group (part of the Style Activity).
This document was produced under the 24 January 2002 CPP as amended by the W3C Patent Policy Transition Procedure. The Working Group maintains a public list of patent disclosures relevant to this document; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) with respect to this specification should disclose the information in accordance with section 6 of the W3C Patent Policy.
Members of the CSS Working Group proposed during the Clamart meeting to modularize the CSS specification.
This modularization, and the externalization of the general syntax, of CSS will reduce the size of the specification and allow new types of specifications to use selectors and/or CSS general syntax.
This specification will have its own test suite, with several tests per concept introduced in this document, as well as tests for multiple concepts used together. This test suite will not consist of full conformance tests, but is intended to ensure interoperability between implementations and will form part of the CR exit criteria.
[This section needs to be revised.]
'Background-clip', 'background-break', and 'background-origin' are new. Also there are changes to the 'background' shorthand property.
'Background-attachment' has a new value 'local'.
The background can now have multiple images. As a consequence, several properties now accept a comma-separated list of values.
(This section is informative.)
When elements are rendered according to the CSS box model [CSS3BOX], each element is either not displayed at all, or formatted as one or more rectangular boxes. Each box has a rectangular content area, a band of padding around the content, a border around the padding, and a margin outside the border. (The margin may actually be negative, but margins have no influence on the background and border, so that doesn't concern the model for borders and backgrounds.)
The child elements of an element usually create boxes of their own, that are placed inside the content area of their parent, although they may also be placed outside it.
The reason an element may result in more than one box, is that elements may be broken at the end of a line (for inline elements), at the end of a column or at the end of a page and create further boxes in the next line, column or page.
The properties of this module deal with the contents of the border area and the background of the content, padding and border areas.
That background may be fully transparent (the default), or it may be filled with a color, one or more images, or both. The background properties specify what color ('background-color') and images ('background-image') to use, where they are placed ('background-position'), whether they are repeated or scaled ('background-repeat', 'background-size'), etc.
The border can either be a predefined style (solid line, double line, dotted line, pseudo-3D border, etc.) or it can be an image. In the former case, three properties define the style of the four border sides ('border-style'), color ('border-color') and thickness ('border-width'). In the latter case, the sides and corners are taken from the sides and corners of an image specified with 'border-image'. The image can be sliced, scaled and stretched in various ways to fit the size of the border.
If an element is broken into multiple boxes, 'border-break' and 'background-break' define how the borders and background are divided over the various boxes.
There is also another kind of border-like decoration that can be added to an element: a drop shadow, via the 'box-shadow' property.
Name: | background-color |
Value: | <color> |
Initial: | transparent |
Applies to: | all elements |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | as specified |
This property sets the background color of an element. Valid color values are defined in the Color Module [CSS3COLOR].
h1 { background-color: #F00 }
Name: | background-image |
Value: | <uri> [ , <uri> ]* | none |
Initial: | none |
Applies to: | all elements |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | absolute URI(s) |
This property sets the background image(s) of an element, or 'none' for no image.
Images are drawn with the first specified one on top (closest to the user) and each subsequent image behind the previous one. The 'background-color' is painted below all the images.
See the section “Layering multiple background images” for how each image is tiled or stretched.
body { background-image: url("marble.svg") } p { background-image: none } div { background-image: url(tl.png), url(tr.png) }
Implementations may optimize by not downloading and drawing images that are not visible (e.g., because they are behind other, fully opaque images).
An image that is empty (zero width or zero height), that fails to download, or that otherwise cannot be displayed (e.g., because it is not in a supported image format) has the same effect as a non-empty transparent image.
If 'background-repeat' or 'background-position' has more comma-separated values than 'background-image', the series of values is repeated as needed.
For example, these rules
background-image: url(a), url(b); background-position: top, right, bottom, left, center; background-repeat: no-repeat, no-repeat;
have the same effect as:
background-image: url(a), url(b), url(a), url(b), url(a); background-position: top, right, bottom, left, center; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat;
It seems more intuitive to let 'background-image' determine the number of layers and truncate or extend 'background-repeat' and 'background-position' accordingly. Also because only 'background-image' has the value 'none'.
Editor's Note: Conformance properties for an image should be addressed here: MIME type image/*, require support for PNG, refer to profiles…
Name: | background-repeat |
Value: | <repeat> [ , <repeat> ]* |
Initial: | repeat |
Applies to: | all elements |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | as specified |
The value <repeat> stands for: repeat-x | repeat-y | [repeat | space | no-repeat]{1,2}.
See the section “Layering multiple background images” for how each comma-separated value is applied to each image of the 'background-image' property.
The tiling and positioning of the background image on inline elements is described under the 'background-break' property.
Should there also be values of "repeat-up", "repeat-down", "repeat-right", and "repeat-left" for this property?
Values have the following meanings:
Otherwise, if there is one value, it sets both the horizontal and vertical repeat. If there are two, the first one is for the horizontal direction, the second for the vertical one. As follows:
Unless one of the two keywords is 'no-repeat', the whole background will be tiled, i.e., not just one vertical strip and one horizontal strip.
body { background: white url("pendant.png"); background-repeat: repeat-y; background-position: center; } p { background-image: url(star.svg), url(pattern.png); background-repeat: no-repeat, repeat }
Name: | background-attachment |
Value: | scroll | fixed | local [, scroll | fixed | local]* |
Initial: | scroll |
Applies to: | all elements |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | as specified |
If background images are specified, this property specifies whether they are fixed with regard to the viewport ('fixed') or scroll along with the document ('scroll' and 'local').
See the section “Layering multiple background images” for how each comma-separated value is applied to each image of the 'background-image' property.
The difference between 'scroll' and 'local' is only visible when the element has a scrolling mechanism (see 'overflow'): in the case of 'scroll', the background does not scroll with the element's content. (It is attached to the element's border, as it were.) In the case of 'local', the background scrolls along with the element's content. In the this case, the background behind the element's border (if any) scrolls as well, even though the border itself does not scroll with the contents.
Even if the image is fixed, it is still only visible when it is in the content, padding, or border area of the element. Thus, unless the image is tiled ('background-repeat: repeat'), it may be invisible.
This example creates an infinite vertical band that remains “glued” to the viewport when the element is scrolled.
body { background: red url("pendant.gif"); background-repeat: repeat-y; background-attachment: fixed; }
User agents that do not support 'fixed' backgrounds (for example due to limitations of the hardware platform) should ignore declarations with the keyword 'fixed'. For example:
body { /* For all UAs: */ background: white url(paper.png) scroll; /* For UAs that do fixed backgrounds: */ background: white url(ledger.png) fixed; } h1 { /* For all UAs: */ background: silver; /* For UAs that do fixed backgrounds: */ background: url(stripe.png) fixed, white url(ledger.png) fixed; }
Name: | background-position |
Value: | <bg-position> [ , <bg-position> ]* |
Initial: | 0% 0% |
Applies to: | all elements |
Inherited: | no |
Percentages: | refer to the size of the box itself |
Media: | visual |
Computed value: | for <length> the absolute value, otherwise a percentage |
The <bg-position> stands for: [ [ <percentage> | <length> | left | center | right ] [ <percentage> | <length> | top | center | bottom ]? ] | [ [ left | center | right ] || [ top | center | bottom ] ]
If a background image has been specified, this property specifies its initial position. The section “Layering multiple background images” defines to which image of 'background-image' each of the comma-separated values applies.
If only one percentage or length value is given, it sets the horizontal position only, and the vertical position will be 50%. If two values are given, the horizontal position comes first. Combinations of keyword, length and percentage values are allowed, (e.g., '50% 2cm' or 'center 2cm' or 'center 10%'). For combinations of keyword and non-keyword values, 'left' and 'right' may only be used as the first value, and 'top' and 'bottom' may only be used as the second value. Negative positions are allowed.
body { background: url("banner.jpeg") right top } /* 100% 0% */ body { background: url("banner.jpeg") top center } /* 50% 0% */ body { background: url("banner.jpeg") center } /* 50% 50% */ body { background: url("banner.jpeg") bottom } /* 50% 100% */
If the background image is fixed within the viewport (see the 'background-attachment' property), the image is placed relative to the viewport. Otherwise, it is placed relative to the element's padding or border area, depending on 'background-origin'.
body { background-image: url("logo.png"); background-attachment: fixed; background-position: 100% 100%; background-repeat: no-repeat; }
In the example above, the (single) image is placed in the lower-right corner of the viewport.
Name: | background-clip |
Value: | [border | padding] [, [border | padding]]* |
Initial: | border |
Applies to: | all elements |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | same as specified value |
Determines whether the background extends into the border area or not. If the value is 'padding', the background is clipped to the padding edge and the background of the border is transparent. If the value is 'border', the background extends into the border area.
Each comma-separated value applies to one image of 'background-image'. See the section “Layering multiple background images” for how clip values and images are paired.
Editor's Note: Can the background color be placed under the border but not background images? Not currently.
Is it useful to allow separate clip values for each image, or is one value for the whole background enough?
Name: | background-origin |
Value: | [border | padding | content] [, [border | padding | content]]* |
Initial: | padding |
Applies to: | all elements |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | same as specified value |
Determines how the 'background-position' is calculated. With a value of 'padding', the position is relative to the padding edge ('0 0' is the upper left corner of the padding edge, '100% 100%' is the lower right corner). 'Border' means the position is relative to the border edge, and 'content' means relative to the content edge.
Each comma-separated value applies to one image of 'background-image'. See the section “Layering multiple background images” for how origin values and images are paired.
Note that if 'background-clip' is 'padding', 'background-origin' is 'border', and 'background-position' is 'top left' (the initial value), then the top left of the background image will be clipped.
Name: | background-size |
Value: | [ [ <length> | <percentage> | auto ]{1,2} || round ] [ [ , [ <length> | <percentage> | auto ]{1,2} ] || round ]* |
Initial: | auto |
Applies to: | all elements |
Inherited: | no |
Percentages: | see text |
Media: | visual |
Computed value: | same as specified value |
Is 'background-stretch' a better name?
Specifies the size of the background images. The section “Layering multiple background images” defines to which image of the 'background-image' property each of the comma-separated values applies.
If a comma-separated value has only one part (not counting the keyword 'round'), the second part is set to 'auto'. Of the two parts, the first one refers to the width, the second to the height of the corresponding background image. The addition of the keyword 'round' indicates that the width and height are approximate, as explained below. 'round' on its own is equivalent to 'auto auto round'.
The size of an image is established in two steps. The first step derives sizes as follows:
Negative values are not allowed. A size of zero is allowed, but causes the image not to be displayed. (The effect is the same as if it had been a transparent image.)
If the given size is accompanied by the keyword 'round', and the computed value of 'background-repeat' is repeat for the horizontal and/or vertical direction, there is a second step: The UA must reduce the width, resp., height so that the image fits a whole number of times in the background area. In the case of the width:
If X ≠ 0 is the width of the image (i.e., the specified length or percentage, or the intrinsic width if the 'background-size' is 'auto') and W is the width of the background area, then the rounded width X' = W / ceil(W / X)
The height is analogous. ceil() is a function that returns its argument if it is a whole number, otherwise the next bigger whole number.
If the width is reduced because of this formula, the aspect ratio is not retained, not even if the height was specifed as 'auto' and the vertical repeat as 'no-repeat'. Ditto if the height is reduced.
Should 'round' be specified for width and height separately? It then becoems possible to round in one direction and keep the aspect ratio in the other. E.g., instead of allowing the keyword in 'background-size', it could be one of the possible values in 'background-repeat': [ repeat | space | no-repeat | round ]{1,2}.
Is 'round' the right word? How about '~' in front of the number, or 'approx' or 'about'?
Is it better allow the size of the image to be rounded up as well as down?
Here are some examples. The first example stretches the background image independently in both directions to completely cover the content area:
div { background-image: url(plasma.png); background-size: 100%; background-origin: content}
The second example stretches the image so that exactly two copies fit horizontally. The aspect ratio is preserved:
p { background-image: url(tubes.png); background-size: 50% auto; background-origin: border}
This example forces the background image to be 15 by 15 pixels:
para { background-size: 15px; background-image: url(tile.png)}
This example uses the image's intrinsic size. Note that this is the only possible behavior in CSS level 1 and 2.
body { background-size: auto; background-image: url(flower.png)}
The following example rounds the height of the image to 25%, down from the specified value of 30%. At 30%, three images would fit entirely and a fourth only partially. After rounding, four images fit. The width of the image is 20% of the background area width and is not rounded.
p { background-image: url(chain.png); background-repeat: repeat-y; background-size: 20% 30% round; }
Name: | background-break |
Value: | bounding-box | each-box | continuous |
Initial: | continuous |
Applies to: | inline elements and block-level elements (see text) |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | same as specified value |
This property applies to inline flow elements (specifically, it does not apply to elements that are inline-block or inline-table), and to block-level elements when they are broken into several boxes (for example, across pages). The property does different things for different types of boxes.
For inline flow elements, values have the following meanings:
For block-level elements, values have the following meanings: (EDITOR'S NOTE: following needs to be checked against what was in old "background-break (open|close)" property)
The properties 'background-image', 'background-origin', 'background-clip', 'background-repeat', 'background-size', and 'background-position' may have multiple comma-separated values. Excepting the case that 'background-image' is 'none', if the values are specified as follows:
backgound-image: w1,…wM
backgound-repeat: x1,…xR
backgound-size: y1,…yS
backgound-position: s1,…sP
the number of layers is N = max(M, R, S, P) [shouldn't it be M instead?].
Each of the properties is interpreted as if it had N values, by repeating the specified values like this:
backgound-image: w1,…wM, w1,…wM, w1,… /* N values */
backgound-repeat: x1,…xR, x1,…xR, x1,… /* N values */
backgound-size: y1,…yS, y1,…yS, y1,… /* N values */
backgound-position: s1,…rP, s1,…rP, s1,… /* N values */
This set of declarations:
background-image: url(flower.png), url(ball.png), url(grass.png); background-position: center center, 20% 80%, top left; background-origin: border, content;
has exactly the same effect as this set with the origin values repeated (bolded for clarity):
background-image: url(flower.png), url(ball.png), url(grass1.png); background-position: center center, 20% 80%, top left; background-origin: border, content, border;
Likewise, this set of declarations:
background-image: url(red.png), url(blue.png); background-repeat: repeat-x, repeat-y, repeat-y; background-position: 20% 25%, 40% 10%, 50% 15%, 70% 40%, 90% 35%;
has the same effect as:
background-image: url(red.png), url(blue.png), url(red.png), url(blue.png), url(red.png); background-repeat: repeat-x, repeat-y, repeat-y, repeat-x, repeat-y; background-position: 20% 25%, 40% 10%, 50% 15%, 70% 40%, 90% 35%;
There are other ways to add missing values: repeat the last value at the end, repeat the first value at the start, fill either at the end or at the start with the initial value…
Each of the images is repeated, sized, and positioned according to the corresponding value in the other properties. The first image in the list is the layer closest to the user, the next one is painted behind the first, and so on.
If 'background-image' is 'none', there are no layers (N = 0).
Name: | background |
Value: | [ <bg-layer> , ]* <final-bg-layer> |
Initial: | see individual properties |
Applies to: | all elements |
Inherited: | no |
Percentages: | see individual properties |
Media: | visual |
Computed value: | see individual properties |
<bg-layer> stands for: <'background-image'> && [ ( <'background-size'> ) ]? && <'background-repeat'>? && <'background-position'>? && <'background-attachment'>? && [ <'background-clip'> <'background-origin'>? ]?
<final-bg-layer> stands for: <'background-image'> || ( <'background-size'> ) || <'background-repeat'> || <'background-position'> || <'background-attachment'> || [ <'background-clip'> <'background-origin'>? ] || <'background-color'>
Note that <bg-layer> requires a <uri> for an image, while an image is optional in <final-bg-layer>; a color and attachment are permitted in <final-bg-layer>, but not in <bg-layer>.
The 'background' property is a shorthand property for setting most background properties at the same place in the style sheet. It sets each of 'background-color', 'background-position', 'background-size', 'background-repeat', 'background-clip', 'background-origin', 'background-attachment' and 'background-image' to the value given, or to its initial value, if no explicit value was specified. (It does not set 'background-break'.)
Note that the ::first-line pseudo-element is like an inline-level element for the purposes of the background (see section 5.12.1 of [CSS21]). That means, e.g., that in a left-justified first line, the background does not necessarily extend all the way to the right margin.
In the first rule of the following example, only a value for 'background-color' has been given and the other individual properties are set to their initial values. In the second rule, many individual properties have been specified.
body { background: red } p { background: url("chess.png") (10em round) gray 40% repeat fixed border border}
The first rule is equivalent to:
body { background-color: red; background-position: 0% 0%; background-size: 30% 30%; background-repeat: repeat repeat; background-clip: border; background-origin: padding; background-attachment: scroll; background-image: none }
The second is equivalent to:
p { background-color: gray; background-position: 40% 50%; background-size: 10em 10em round; background-repeat: repeat repeat; background-clip: border; background-origin: border; background-attachment: fixed; background-image: url(chess.png) }
The following example shows how a both a background color (#CCC) and a background image (url(metal.jpg)) are set. The image is stretched to the full width of the element:
E { background: #CCC url("metal.jpg") (100% auto) no-repeat top left }
Another example shows equivalence:
div { background: padding url(paper.jpg) white center } div { background-color: white; background-image: url(paper.jpg); background-repeat: repeat; background-attachment: scroll; background-position: center; background-clip: padding; background-origin: padding; background-size: auto auto }
The following declaration with multiple, comma-separated values
background: url(a.png) top left no-repeat, url(b.png) center (100% 100%) no-repeat, url(c.png) white
is equivalent to
background-image: url(a.png), url(b.png), url(c.png); background-position: top left, center, top left; background-repeat: no-repeat, stretch no-repeat, repeat; background-clip: border, border, border; background-origin: padding, padding, padding; background-size: auto auto, 100% 100%, auto auto; background-attachment: scroll, scroll, scroll; background-color: white;
Note that 'background: url(foo) white' and 'background: url(foo), white' have the same effect.
Having both clip and origin in the shorthand may be confusing, since they use the same keywords and their order is thus important. Maybe a simplification (due to Fantasai) is to allow '[border | padding | content]?' only once and use it to set clip and origin to the same value (or to their defaults, if absent).
Name: | border-top-color , border-right-color, border-bottom-color, border-left-color |
Value: | <color> |
Initial: | currentcolor |
Applies to: | all elements |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | <color> |
Name: | border-color |
Value: | <color>{1,4} |
Initial: | (see individual properties) |
Applies to: | all elements |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | see individual properties |
These properties set the foreground color of the border specified by the border-style properties.
'Border-color' is a shorthand for the four 'border-*-color' properties. The four values set the top, right, bottom and left border, respectively. A missing left is the same as right, a missing bottom is the same as top, and a missing right is also the same as top.
Name: | border-top-style , border-right-style, border-bottom-style, border-left-style |
Value: | <border-style> |
Initial: | none |
Applies to: | all elements |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | specified value |
Name: | border-style |
Value: | <border-style>{1,4} |
Initial: | (see individual properties) |
Applies to: | all elements |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | see individual properties |
These properties set the style of the border, unless there is a border image (see 'border-image').
'Border-style' is a shorthand for the other four. Its four values set the top, right, bottom and left border respectively. A missing left is the same as right, a missing bottom is the same as top, and a missing right is also the same as top.
<border-style> is: none | hidden | dotted | dashed | solid | double | dot-dash | dot-dot-dash | wave | groove | ridge | inset | outset. Values have the following meanings:
Borders are drawn in front of the element's background, but behind the element's content (in case it overlaps).
Note: There is no control over the spacing of the dots and dashes, nor over the length of the dashes. Implementations are encouraged to choose a spacing that makes the corners symmetrical.
Note: This specification does not define how borders of different styles should be joined in the corner. Also note that rounded corners may cause the corners and the contents to overlap, if the padding is less than the radius of the corner.
Name: | border-top-width, border-right-width, border-bottom-width, border-left-width |
Value: | <border-width> |
Initial: | medium |
Applies to: | all elements |
Inherited: | no |
Percentages: | width* of containing block |
Media: | visual |
Computed value: | specified value |
*) if the containing block has a horizontal writing mode, otherwise the height |
Name: | border-width |
Value: | <border-width>{1,4} |
Initial: | (see individual properties) |
Applies to: | all elements |
Inherited: | no |
Percentages: | see individual properties |
Media: | visual |
Computed value: | see individual properties |
[Border-width doesn't allow percentages in CSS2; should we allow percentages (of the containing block's width) in CSS3?]
These properties set the thickness of the border.
The <border-width> is '<length> | <percentage> | thin | medium | thick'. The <length> and <percentage> may not be negative. The lengths corresponding to 'thin', 'medium' and 'thick' are not specified, but the values are constant throughout a document and thin ≤ medium ≤ thick. A UA could, e.g., make the thickness depend on the 'medium' font size: one choice might be 1, 3 & 5px when the 'medium' font size is 17px or less.
'Border-width' is a shorthand that sets the four 'border-*-width' properties. If it has four values, they set top, right, bottom and left in that order. If left is missing, it is the same as right; if bottom is missing, it is the same as top; if right is missing, it is the same as top.
Note that the initial width is 'medium', but the initial style is 'none' and therefore the used width is 0.
When the used width of the border is 0, we say that the border is absent.
Name: | border-image |
Value: | none | <uri> [<number> | <percentage>]{4} [ / <border-width>{1,4} ]? [stretch | repeat | round]{0,2} |
Initial: | none |
Applies to: | All elements, except table element when 'border-collapse' is 'collapse' |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | Specified value, with any URI made absolute |
Specifies an image to use instead of the border styles given by the 'border-style' properties and an additional background image for the element. If the value is 'none' or if the image cannot be displayed, the border styles will be used.
The four numbers or percentages immediately following the <uri> specify which part of that image is used for which part of the border. They divide the image into nine parts: four corners, four edges and a middle part. The middle part is used as an extra background image.
The first of the four values is the height of the top edge and of the two top corners. The second is the width of the right edge and the two right corners. The third is the height of the bottom edge and the two bottom corners. The fourth is the width of the left edge and the two left corners.
Percentages are relative to the size of the image. Numbers represent pixels in the image (if the image is a raster image) or CSS px units (if not). Negative values are not allowed and values bigger than the size of the image are interpreted as 100%.
The <number>s are slightly confusing. People may be tempted to write 5px instead of 5, since on most screens, 5px is the same size as 5 image pixels.
If the sum of the right and left widths is equal to or greater than the width of the image, the images for the top and bottom edge and the middle part are empty, which has the same effect as if a non-empty transparent image had been specified for those parts. Analogously for the top and bottom values.
If the slash is present in the property value, the one to four values after it are used for the width of the border instead of the 'border-width' properties (but only if the specified image can be displayed). The order of the values is the same as for 'border-width'.
At the end of the value, there may be up to two keywords, that specify how the images for the sides and the middle part are scaled and tiled. If the second is absent, it is assumed to be the same as the first. If both are absent, the effect is the same as 'stretch stretch'.
The nine images are scaled in two steps:
The two images for the top and bottom edges are made as tall as the top and bottom borders, respectively, (either using 'border-width' or the values specified after the slash) and their width is scaled proportionally.
The images for the left and right edge are made as wide as the left and right borders, respectively, and their height is scaled proportionally.
The corner images are scaled to be as wide and as tall as the two borders they are part of.
The middle part is not scaled.
If the first keyword is 'stretch', the top, middle and bottom images are further scaled to be as wide as the element's padding box. The height is not changed any further.
If the first keyword is 'round', the top, middle and bottom images are reduced in width, so that exactly a whole number of them fit in the width of the padding box, as follows:
If X ≠ 0 is the width of the image and W is the width of the padding area, then the rounded width X' = W / ceil(W / X)
The effects of 'stretch' and 'round' for the second keyword are analogous, acting on the height of the left, middle and right images.
The resulting images are placed centered in their respective parts of the border (the middle image is put in the middle of the padding area) and then tiled. All images are drawn behind the element's content, in front of the element's background.
This example creates a top and bottom border consisting of a whole number of orange diamonds and a left and right border of a single, stretched diamond. The corners are diamonds of a different color. The image to tile is as follows. Apart from the diamonds, it is transparent:
The image is 81 by 81 pixels and has to be divided into 9 equal parts. The style rules could thus be as follows:
DIV { border-image: url("border.png") 27 27 27 27 round stretch; border: double orange 1em }
The result, when applied to a DIV of 12 by 5em, will be similar to this:
The 'border-image' property does not apply to table elements in a table with 'border-collapse' set to 'collapse'.
Name: | border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-top-left-radius, border-radius |
Value: | <length> <length>? |
Initial: | 0 |
Applies to: | all elements, except table element when 'border-collapse' is 'collapse' |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | specified values |
The two length values of the 'border-radius' properties define the radii of a quarter ellipse that defines the shape of the corner (see the diagram below). The first value is the horizontal radius (or vertical if the 'writing-mode' is vertical). If the second length is omitted it is equal to the first (and the corner is thus a quarter circle). If either length is zero, the corner is square, not rounded. The border radius also causes the element's background to be rounded, even if the border is 'none'. Negative values are not allowed.
All border styles ('solid', 'dotted', 'inset', etc.) follow the curve of the border. Border images specified with 'border-image', however, are clipped at the outer edge of the curve. Or are they not affected at all?
Name: | border-break |
Value: | <'border-width'> || <border-style> || <color> |
Initial: | none |
Applies to: | elements with a border |
Inherited: | yes |
Percentages: | N/A |
Media: | visual |
Computed value: | specified value |
When a box that has a border is broken at a page break, column break, or, for inline elements, at a line break, a border and some padding can be inserted at the break, or the border can be left open.
If the style is set to 'none', no border and no padding are inserted.
Otherwise, padding is added as wide as the corresponding side of the 'padding' property and a border is added. If borders on that side would get an image, the image is used, scaled to the given width, otherwise the border gets the given style and color.
Note that, unlike for the other borders of the element, a value of 'none' suppresses any image border as well. If you want an image or nothing, use 'hidden' instead.
Is this asymmetry in the meaning of 'none' a problem? Another possibility is to have a simple on/off switch for the border at the break: 'border-break: show | hide'.
Name: | border-top, border-right, border-bottom, border-left |
Value: | <'border-width'> || <border-style> || <color> |
Initial: | See individual properties |
Applies to: | all elements |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | absolute values |
This is a shorthand property for setting the width, style, and color of the top, right, bottom, and left border of a box. Omitted values are set to their initial values.
Name: | border |
Value: | <'border-width'> || <border-style> || <color> |
Initial: | See individual properties |
Applies to: | all elements |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | absolute values |
The 'border' property is a shorthand property for setting the same width, color, and style for all four borders of a box. Unlike the shorthand 'margin' and 'padding' properties, the 'border' property cannot set different values on the four borders. To do so, one or more of the other border properties must be used.
For example, the first rule below is equivalent to the set of four rules shown after it:
p { border: solid red } p { border-top: solid red; border-right: solid red; border-bottom: solid red; border-left: solid red; }
Since, to some extent, the properties have overlapping functionality, the order in which the rules are specified is important.
Consider this example:
blockquote { border-color: red; border-left: double; color: black }
In the above example, the color of the left border is black, while the other borders are red. This is due to 'border-left' setting the width, style, and color. Since the color value is not given by the 'border-left' property, it will be taken from the 'color' property. The fact that the 'color' property is set after the 'border-left' property is not relevant.
Name: | box-shadow |
Value: | none | [ <length> <length> <length>? || <color> ] [ , <length> <length> <length>? || <color> ]+ |
Initial: | none |
Applies to: | all elements |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | absolute values |
Multiple shadows may be overkill and hard to implement. What are the use cases?
One or more drop-shadows can be attached to a box. They are drawn just outside the border edge. The property is a comma-separated list of shadows, each specified by 3 length values and a color. Omitted lengths are 0, omitted colors are equal to the computed value of the 'color' property.
Shadows do not influence the layout: they may overlap with other boxes. Like backgrounds and borders, if they overlap other boxes, they are drawn behind any text or replaced element. In terms of the stacking context, the shadow of an element is drawn immediately below the background of that element.
The 3 lengths and the color of each shadow are interpreted as follows:
If an element has multiple boxes, all of them get drop shadows, but shadows are only drawn where borders would also be drawn, see 'border-break'. If the box has a non-zero border-radius', the shadow is rounded in the same way.
Here is an example of single words with a drop shadow. Assume the words were enclosed in <span> and the style rule was
span {border: thin solid; box-shadow: 0.2em 0.2em #CCC}
The result might look like this:
This example shows a shadow on the bottom right only, even though the box is transparent. Shouldn't we see a “real” shadow, projecting exactly the opaque parts of the box? What if the opaque parts are actually semi-opaque? Will the shadow be less intense there?
The background of the root element becomes the background of the canvas and extends to cover the entire canvas, although any images are positioned and stretched relative to the root element as if they were painted for that element alone. If the root's background-color value is 'transparent', the color is UA dependent. The root element does not paint this background again.
For HTML documents, however, it is recommended that authors specify the
background for the BODY
element rather than the
HTML
element. User agents should observe the
following precedence rules to fill in the background of the canvas of HTML
documents: if the value of any of the 'background' properties on the HTML
element is different from its initial value, then
use the background of the HTML
element, else use
the background of the BODY
element. This does
not apply to XHTML documents.
According to these rules, the canvas underlying the following HTML document will have a “marble” background:
<!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.0//EN' > <html> <head> <title>Setting the canvas background</title> <style type="text/css"> body { background: url("http://example.org/marble.png") } </style> </head> <body> <p>My background is marble.</p> </body> </html>
(NOTE: Check profiles because of changes made!)
CSS1 Profile:
CSS2 Profile:
Mobile and TV Profiles (informative, see their specifications):
CSS3 Profile:
This section will define conformance with the present specification only.
The inability of a user agent to implement part of this specification due to the limitations of a particular device does not imply non-conformance.
User agents must observe the rules for handling parsing errors.
This specification will contain a test suite allowing user agents to verify their basic conformance to the specification. This test suite does not pretend to be exhaustive and does not cover all possible combined cases of W3C background functionality.
Tapas Roy was editor of the Border Module, before it was merged with the Background Module.
A set of properties for border images was initially proposed by fantasai. The current simplification (one image cut into nine parts) is due to Ian Hickson. (Though the original idea seems to originate with some anonymous Microsoft engineers.)
As described in the W3C process document, a Candidate Recommendation (CR) is a specification that W3C recommends for use on the Web. The next stage is “Recommendation,” when the specification is sufficiently implemented.
For this specification to be proposed as a W3C Recommendation, the following conditions shall be met:
There must be at least two interoperable implementations for every feature in the Module. For the purposes of this criterion, we define the following terms:
a section or subsection of the specification
passing the respective test case(s) in the CSS test suite, or, if the implementation is not a web browser, an equivalent test. Every relevant test in the test suite should have an equivalent test created if such a UA is to be used to claim interoperability. In addition if such a UA is to be used to claim interoperability, then there must one or more additional UAs which can also pass those equivalent tests in the same way for the purpose of interoperability. The equivalent tests must be made publicly available for the purposes of peer review.
a user agent which:
A minimum of sixth months of the CR period must have elapsed. This is to ensure that enough time is given for any remaining major errors to be caught.
Features will be dropped if two or more interoperable implementations are not found by the end of the CR period.
Features may/will also be dropped if adequate/sufficient (by judgment of CSS WG) tests have not been produced for those feature(s) by the end of the CR period.
Property | Values | Initial | Applies to | Inh. | Percentages | Media |
---|---|---|---|---|---|---|
background | [ <bg-layer> , ]* <final-bg-layer> | see individual properties | all elements | no | see individual properties | visual |
background-attachment | scroll | fixed | local [, scroll | fixed | local]* | scroll | all elements | no | N/A | visual |
background-break | bounding-box | each-box | continuous | continuous | inline elements and block-level elements (see text) | no | N/A | visual |
background-clip | [border | padding] [, [border | padding]]* | border | all elements | no | N/A | visual |
background-color | <color> | transparent | all elements | no | N/A | visual |
background-image | <uri> [ , <uri> ]* | none | none | all elements | no | N/A | visual |
background-origin | [border | padding | content] [, [border | padding | content]]* | padding | all elements | no | N/A | visual |
background-position | <bg-position> [ , <bg-position> ]* | 0% 0% | all elements | no | refer to the size of the box itself | visual |
background-repeat | <repeat> [ , <repeat> ]* | repeat | all elements | no | N/A | visual |
background-size | [ [ <length> | <percentage> | auto ]{1,2} || round ] [ [ , [ <length> | <percentage> | auto ]{1,2} ] || round ]* | auto | all elements | no | see text | visual |
border | <'border-width'> || <border-style> || <color> | See individual properties | all elements | no | N/A | visual |
border-break | <'border-width'> || <border-style> || <color> | none | elements with a border | yes | N/A | visual |
border-color | <color>{1,4} | (see individual properties) | all elements | no | N/A | visual |
border-image | none | <uri> [<number> | <percentage>]{4} [ / <border-width>{1,4} ]? [stretch | repeat | round]{0,2} | none | All elements, except table element when 'border-collapse' is 'collapse' | no | N/A | visual |
border-style | <border-style>{1,4} | (see individual properties) | all elements | no | N/A | visual |
border-top, border-right, border-bottom, border-left | <'border-width'> || <border-style> || <color> | See individual properties | all elements | no | N/A | visual |
border-top-color , border-right-color, border-bottom-color, border-left-color | <color> | currentcolor | all elements | no | N/A | visual |
border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-top-left-radius, border-radius | <length> <length>? | 0 | all elements, except table element when 'border-collapse' is 'collapse' | no | N/A | visual |
border-top-style , border-right-style, border-bottom-style, border-left-style | <border-style> | none | all elements | no | N/A | visual |
border-top-width, border-right-width, border-bottom-width, border-left-width | <border-width> | medium | all elements | no | width* of containing block | visual |
border-width | <border-width>{1,4} | (see individual properties) | all elements | no | see individual properties | visual |
box-shadow | none | [ <length> <length> <length>? || <color> ] [ , <length> <length> <length>? || <color> ]+ | none | all elements | no | N/A | visual |
The following properties are defined in other modules:
The following data types are defined in [CSS3VAL]: