Borders and frames in HTML

The basics about frames and borders

In principle you can put borders on all tags. It doesn't make sense to put borders on all tags, as they cannot be seen, e.g. <BR>, but since the borders are done using the attribute STYLES, you can apply borders to all tags.

There is an attribute named BORDER, that goes with the TABLE tag under HTML 4.01. Officially, HTML 5 does not support this attribute, but currently it also works with HTML 5. You don't want to use it for code for the users, but it is helpful, if you are working with a table without borders and need to get an overview of all the cells.

Borders consists of three variable that you have to specify to get the same result across the browsers:

border-style: Do you want a solid line, a dashed line, a double line, 3D effects etc.
border-width: How wide do you want the border to be?
border-color: What color do you want for the border?

You can truncate the three variables to writing border followed by the variables' values, e.g. STYLE="border: 2px solid #000000" for a black, 2 px wide, solid line as the border, but it is a bad idea, as it makes the code harder to decipher in the editing process.

All variables are also available in a version where you specify one of the sides/borders/frames, i.e. if you need to specify a border style for the top, you write STYLE="border-top-style:". Note that the position is entered in the middle, not at the end as border-style-top. This goes for both -style, -width and -color. The color on the right side then becomes STYLE="border-right-color:" and so forth. in some situations, this can be an advantage, e.g. CLASS where you have specified the border style, bur for one particular row or column, but on one or two sides, you need another color, type or width.

For border-style you have the following basic options:

noneno border.
A dotted line (IE will display this as a dashes, if the border is only one pixel wide).
A dashed line.
A solid line.
Two solid lines. Requires 3px or more in border-width to be displayed as two lines.
3D effect that looks like a groove.
3D effect that looks like a ridge.
3D effect that looks like a lowered plateau (hole).
3D effect that looks like a raised plateau.
hiddenSame effect as 'None', but only works for tables and it isn't supported by IE, and thus recommended not to use.

Border-styles can, just like margins, padding, and many other variables be combined, so you have different border types all the way around the tag, e.g. STYLE="border-style: solid double dashed ridge", which looks like this:

It is important to keep in mind that 3D are shown differently, depending on the browsers. Especially if using wide borders, the difference becomes noticeable. A part of it is due to the default color being different for the browsers, but rendering of the the beveled corners and shadow effects on the "slopes" isn't done all that well by some of the browsers. If you need to have wide borders with 3D effects, it may be better to use border-image (shown a bit further down).

The border width is specified in the same manner as the width on other elements, i.e. you can choose whether you want to use px, pt, mm or cm, e.g. a 3 px wide border: STYLE="border-width:3px". The width of the individual lines can, in the same way as the types, be specified individually, e.g. a solid line having STYLE="border-width:4px 3px 2px 1px":

Border colors are simple for 2D borders. Like width and type, the four borders can be colored individually, e.g. a solid line using STYLE="border-color:green red black blue":

For the 3D effects, the coloring can be at bit weird to look at. This is an effect of the way the browsers interpret the color changes on the four sides from the specified color, in order to generate the 3D effect. The position from which the light comes (upper left corner) becomes lighter and the shadow sides becomes darker. For the narrow frames it goes reasonably well, e.g. an outset in green (#00FF00) in 5px width:

It isn't spectacular, but you do get some sense of 3D. If you make it wider, it becomes something of a disaster, and you loose the illusion of depth. Here you have the same frame in 10px width:

A part of the problem is that the colors are pairwise the same, so by giving the two lighter sides two different nuances of green, and similarly use two different nuances on the shadow side, you can make it a bit better by specifying four colors:

Another part of the problem is the differences in the way the various browsers render the colors on the "angled" surfaces. This is the code from before as displayed by the five most common browsers:

Chrome (Version 38.0.2125.104 m)
Firefox (Version 33)
Internet Explorer (Version 11)
Opera (Version 12.17)
Safari (Version 5.1.2)

Having major differences between how the pages look, depending on the browser, is not considered a good practice, and even at its best, it isn't very good, so the recommendation here is to use another solution. It is called border-image and is demonstrated further down on the page.

Rounded corners and other border effects

Newer browsers have some additional options for effects on borders and frames. With CSS3 you currently have the following options:

border-radius: Rounded corners on borders and frames.
box-shadow: Shadow effects on borders and frames.
border-image: Borders and frames created from images.

Older browsers, that cannot use CSS3 will ignore the codes.

With border-radius you can give your borders rounded corners, and with this you get a lot of options look in regards to creating creating some really neat visual effects.

The most basic is a subtle rounding of all corners using STYLE="border-radius:5px":

This can be increased so you get round ends, in this case STYLE="border-radius:18px", for a frame with a height of 30 px:

You would expect the rounding to be limited to half the height of the frame, but that is not the case, as the horizontal bending affects the vertical and vice versa, so here you have to experiment a little to see what works. If you exceed the maximum value, nothing else happens, you cannot get the rounding bent out of shape like this. The rounding cannot be a negative number either, e.g. border-radius:-18px. This be treated as border-radius:0px

Border-radius can, as most other effects, be set for the individual corners. the variables start at the upper left corner moving clockwise. A border having STYLE="border-radius:18px 10px 5px 0px", will look like this:

If you want to, you can of course specify the individual corners. In that case, you write:


Now you can start combining e.g. like this table with 3 cells where the ends are round, using 18 px and the connecting corners are rounded using 5 px:

Cell 1 Cell 2 Cell 3

So far we have treated the rounding of each corner as symmetrical. It doesn't have to be like that, so here you have some effectful options in regards to loosening up the rigid frames, if you want to. If you specify 2 radii, you get an asymmetrical rounding.

The keep the code at a comprehensive level, we start using the code for the specific corners. It could be something like this:

border-top-left-radius: 50px 25px;
border-top-right-radius: 50px 25px;
border-bottom-right-radius: 50px 25px;
border-bottom-left-radius: 50px 25px;

This is a symmetrical shape, with asymmetrical corners, which will look like this:

Like before, where we only specified border-radius with one value, when the corners were identical, you can do the same with the asymmetrical corners. To tell the difference between values for symmetrical and asymmetrical corners, you use a slash for the asymmetrical values, so they are written STYLE="border-radius: 50px / 25px;"

There are still some limitations to the geometric shapes, as you cannot use negative values, thereby make the corners bend inwards, but is does provide some options for creating some offbeat geometries for some visually slightly different pages, e.g.:

border-top-left-radius: 7px 15px;
border-top-right-radius: 20px 40px;
border-bottom-right-radius: 15px 7px;
border-bottom-left-radius: 20px 40px;

You can write this as one line, STYLE="border-radius: 7px 20px 15px 20px / 15px 40px 7px 40px;", if you prefer this solution. Typically this is something I would recommend doing when you have found the values for bending using the corner specific notation, but it is only a matter of personal preferences.

Box-shadow is completely similar to text-shadow for text. You can create an illusion of the object being lifted, thereby casting a shadow on the surface below.

A simple grey shadow with a 5 px displacement looks like this:

The shadow effect follows the shape of the object, so with asymmetrical objects, the effect still works:

The shadow can of course be adjusted to fit the illusion of 3D you want to create. For box-shadow you have the following variables:

noneno shadow. This is default.
h-shadowRequired. Placement of the horizontal shadow.
v-shadowRequired. Placement of the vertical shadow.
blurOptional. The distance for the blurring effect.
spreadOptional. The size of the shadow.
colorOptional in principle. The color of the shadow. The browser Safari must have a color specified to display the shadow.
insetOptional. Changes the shadow from an outer to an inner shadow, e.g. for depressions (insets).
initialThe values are set to the default values.
inheritThe values are inherited from the parent element.

The construction is a bit awkward as there is no separator for the variables, so the sequence used for the variables is:

none | h-shadow v-shadow blur spread color inset | initial | inherit

so, if you don't need to use blur, but want to use spread, you still need to have a value for blur so spread occurs as the fourth value.

The displacement using h-shadow and v-shadow can, like many other variables, be specified as px, mm, cm, pt, em and %. By playing around with the two variables, you can create the illusion of the light coming from another angle. If we look at the example from before, only specifying STYLE="box-shadow: 5px 3px grey", then it looks as if the light source is a bit more to the left:

A shadow having sharp edges does not look natural, unless it is very small, but you can blur the edges using blur. You cannot specify how much blurring you want, but you can specify the size of the blurred area. Here we have the displacement in both directions set to 5px and blur to 2px, i.e. STYLE="box-shadow: 5px 5px 2px grey":

Blur makes the shadow transparent in the specified area. It cannot be seen on the white background, but here is the same shadow on a red background, where you can clearly see the blur zone:

Normal shadow has the same size as the object, but you can change the size of the shadow for new effects. The most obvious size change is aving a bigger shadow, so the object appear to be elevated even more. Remember to move/displace the shadow with the same value as you increase the size, to get the perspective right. If we want to increase the size of the shadow with blur from above with 10 px, it now becomes STYLE="box-shadow: 15px 15px 2px 10px grey":

The most interesting use of the size of the shadow is most likely for halo effects. By not displacing the shadow, but only increasing the size and having a wide blur area, you can create a halo effect. Here both blur and spread is set to 10 px and the shadow is in red, so STYLE="box-shadow: 0px 0px 10px 10px red"

You cannot control how transparent the halo should be directly, but if you need an increase in transparency, you make spread less than blur. Same halo as before, only with spread reduced to 5 px; STYLE="box-shadow: 0px 0px 10px 5px red"

To have the halo stretch out to the same size as before, you compensate by increasing blur, so if we increase blur to 15 px:

An undocumented feature (as they call it) is that you can have multiple colors. Here you have a halo consisting of a blue inner halo and a red outer halo. This is done by specifying several sets of variables for box-shadow, separated by comma, in this case STYLE="box-shadow: 0px 0px 5px 2px blue, 0px 0px 15px 10px red":

You have to be aware of the order of the colors, otherwise you may end up with one halo effect hidden under the other. Here the order of the halos have been switched around:

Not much to say about the colors. You have to specify them, so you get the same colors on all browsers, and you have to remember to adjust the color of the shadow according to the background. On a green background, the shadow isn't grey but a darker green, a red background needs a darker red, etc. Like this:

If you are working with something that is supposed to look like a groove or depression, the shadow obviously has the be placed in the hole. This is the variable inset, which is the last variable. If we start by applying it on a solid border, you can see what the effect does. This is our standard frame from before, only using inset, i.e. STYLE="box-shadow: 5px 5px 2px grey inset":

As one could expect, it doesn't look natural, so here you have the same effect, with border inset, with a green "surface", a white bottom of the insert and a lighter shadow:

Border-image is one of the newer features, that isn't supported properly by all browsers. When using border-image, you have to use a little additional tweaking, and even then it is a bit of a problem, as it wasn't until IE 11 that border-image was supported by IE. Therefore, you should give it some extra consideration, whether you want to use it or not.

For border-image you have the following variables:

border-image-sourceThe path to the image-file for the border.
border-image-sliceHow far inwards from the corners of the image (diagonally) to be used. Specified in %.
border-image-widthThe width of the borders to be shown.
border-image-outsetThe amount by which the border image area extends beyond the border box.
border-image-repeatWhether the border has to be repeated (repeat), rounded (round) or stretched (stretch).
initialProperties are set to default values.
inheritProperties are inherited from the parent element.

To make border-image work as well as possible, you don't just insert it as STYLE="". You can do that, but then a major part of the backwards compatibility vanishes. Instead you create a class in your stylesheet. Here we call it ImageBorder and the file we want to use is called BorderImage1.png, placed in the directory Graphics. The image itself looks like this:

Note: In the next section, you can only see the examples if you use a browser that supports border-image!

The first part to address, to make it work, is the type and size of the borders, just like before with type, width and color. For browsers not supporting border-image, this is the borders that will be shown instead, and the parameters must be specified to make border-image work.

The next thing to specify is where the file for border-image-source is placed, the diagonal distance for the section of the image to be used (border-image-slice) and whether the image should be repeated, rounded or stretched.

The difference only makes sense when looking at some examples. If we start with border-image-repeat, the effects looks like this:


For some browsers there is no visible difference between round and repeat. Round will round off and adjust the repeating unit, so the number of repeating units will be an integer, whereas repeat blot just repeats the unit as many times as the space allows, and if there is room for e.g. half a unit, it will be shown as two quarter units at each en so it looks symmetrical.

The section of the image to be used, i.e. border-image-slice, is the percentage, diagonally across the image. Here shown with stretch and four different percents, where 38% is the distance matching the diagonal distance across the blue sqares:


If you specify border-image-slice to more than 100%, or use another unit, e.g. px or pt, border-image-slice is automatically set to 100%.

As STYLE the frame with the 38% looks like this:

STYLE="border-style: solid; border-width: 15px; border-color: transparent; border-image-source: url(../Graphics/BorderImage1.png); border-image-slice: 38%; border-image-repeat: stretch;"

As a CLASS called ImageBorder it will look like this:

.ImageBorder {
border-style: solid;
border-width: 15px;
border-color: transparent;
border-image-source: url(Graphics/BorderImage1.png);
border-image-slice: 38%;
border-image-repeat: stretch;

You don't need to have only one value for border-image-slice. If you have an asymmetrical border, or just a border where the sides are pairwise the same, you can accomodate for this. Here we try using border-image-slice: 38% 25% 10% 5%, to demonstrate the principle:

border-image for older browsers
If you want to make the code compatible with older browsers, to the extent that is possible, you need to add a few lines. This code only has the variables -source, -slice and -repeat as shown above, and most importantly, the code uses the distance from the side instead of the corner, so what was 38% for border-image-slice needs to be 18% here. The full code now looks like this:

.ImageBorder {
-moz-border-image: url(Graphics/BorderImage1.png) 18 stretch; /* Firefox before 3.5*/
-webkit-border-image: url(Graphics/BorderImage1.png) 18 stretch; /* Safari 3.1-5.x Chrome 4-15 */
-o-border-image: url(Graphics/BorderImage1.png) 18 stretch; /* Opera 11-14 */
border-style: solid;
border-width: 15px;
border-color: transparent;
border-image-source: url(Graphics/BorderImage1.png);
border-image-slice: 38%;
border-image-repeat: stretch;

Note: There is no border-image for Internet Explorer. Before IE 11, the browser cannot in any way support border-image.

Note: The code for older browsers comes first. This way it is only used if the browser cannot use the new border-image. If the code is placed at the end, the new browsers will use this code too (browsers use the last code they see, and they still know how to read and use the old type of code).

If we look a the three versions of -repeat again, only this time using CLASS="ImageBorder", they should be visible for users, using older browsers (except IE):


As with the new distances, you need new percentages for how much of the frame you need to use. Note that since the cut-off is done in two different ways, you cannot always get the same effects when using the two ways of specifying borders. Also, there is a difference in how the various browsers interpret the percents, so you need to specify the individual percentages for the three types of browsers:


In the same manner as with border-image, you can, of course, specify distance from all four borders as needed.