Creating rounded corners

From Joomla! Documentation
Revision as of 16:04, 22 May 2008 by Mike dowler (Talk | contribs)

Jump to: navigation, search


Contents

Introduction

Using (X)HTML and CSS, it is easy to place rectangular borders around parts of a web page. Usually, this is done by incorporating the code for that part of the web page in <div>...</div> tags (or similar), and then applying a border to the <div> using the CSS border property.

However, it is not currently possible to create a non-rectangular border using just (X)HTML and CSS. (Non-rectangular borders are referred to in this tutorial as 'rounded corners', since that is the most common implementation. However, the corners do not need to be rounded - this technique can be used to create many different shapes and styles of border.)

In order to overcome the limitations of CSS borders, we can use one or more images to provide the border appearance. This is very easy to do when you know how big your <div> is going to be - you simply create an image of the correct size showing the border you want and set it as the background for your <div>. In general, however, we will want web page elements to change their dimensions (width, height, or both) according to their contents. This is particularly true for template designers using a CMS such as Joomla! - if we don't know what content is going to be placed on the page, we can't possibly know what size the <div> needs to be! The main focus of this tutorial is therefore on creating rounded corners that are 'fluid' - that is, that can resize to accommodate different sizes of contents.

The theory

In order to avoid the problems described above, we use separate images to provide the four corners of our rounded box. In order to ensure that the border of our rounded box is always continuous, these images need to be big enough to completely fill our container at the maximum permissible size. To provide our rounded box at sizes below this maximum, we place the images into four layers, overlapping one another, to create the illusion that the border of our rounded box is unbroken.

Rounded corners
The process is illustrated by the animation shown on the right. At each stage, an image is applied on top of the last.
  1. Firstly, a large image containing the left-hand and top borders, and the top-left rounded corner, is placed at the top left corner of our container <div> (outlined in red for clarity). The image is bigger than required for this container, and so extends beyond the bottom and right-hand edges; this is shown in partial transparency in the animation to illustrate the process, but would not be seen in practice.
  2. Next, a thin horizontal image containing the bottom border and lower-left rounded corner is placed at the bottom left corner of the the container <div>, on top of the first image. This image has been given a thin border in a darker pink to illustrate the process; this border would not normally be used. Again, it can be seen that the image extends beyond the right-hand edge of the container.
  3. Thirdly, a thin vertical image containing the right-hand border and top-right rounded corner is placed at the top right corner of the container, on top of the second image.
  4. Finally, a square image containing just the lower-right rounded corner is placed at the lower-right corner of the container.

Putting it into practice - creating the images

To create the images we need, we will use the open source vector drawing program Inkscape. Unlike raster drawing software (such as the GIMP), which deals in individual pixels, vector drawing software works with geometric shapes. This makes it much easier to create rounded corners having exactly the geometry we want.

We will use Inkscape to create a simple rounded box with a pink foreground and a white background, and a drop shadow at the lower right corner. This is the same box as shown in the animation above.

  1. Create a new Inkscape image
    To begin, we need to decide what maximum size we want for our box. As stated above, this will determine the size of image we need to use. Since a larger image will have a greater file size, and hence cause a website to load more slowly, there is no point making the image any bigger than is necessary. For the purposes of this example, we will use a maximum size of 800px wide by 600px high. We therefore create a new document in Inkscape having these dimensions. The document dimensions are set by choosing File > Document properties from the menu, and entering the correct values in the dialogue box that appears. We will also change the name of the default layer (go to Layer > Rename layer...) to "Rounded rectangle".
  2. Draw a rounded rectangle
    We will leave a 5px margin around our image. In addition, we will need 5px width of shadow on the right-hand and bottom edges of our rounded box. We therefore need to draw a rounded rectangle with a width of 785px and a height of 585px. We will also give the rounded corners a 5px radius. To do this, select the rectangle tool from the toolbar at the left, and left-click-drag anywhere within the blank document. The exact size of rectangle you draw doesn't matter at this stage. Then go to the options toolbar and enter the following settings: W:783.00 H:583.00 Rx:5.000 Ry:5.000 px. Why the difference in sizes? These dimensions don't include the width of the border. We are going to give our rectangle a 2px border, which will therefore increase each dimension by 2px.
  3. Set the fill colour
    Set the border width
    Next, we need to adjust that border, and set the colour of our rectangle. With the rectangle selected, go to Object > Fill and Stroke on the menu bar, or press Shift + Ctrl + F, to bring up the Fill and Stroke dialogue. Under the 'Fill' tab, choose the colour of the foreground fill. We are going to use the hex colour #ffd7eb, so enter 'ffd7ebff' in the RGBA input. (The final 'ff' hex value sets the alpha transparency level for the fill - in our case, completely opaque). Under the 'Stroke paint' tab we set the border colour. In our case, we want a black border, so we can leave the RGBA input at the default value of 000000ff. Finally, under the 'stroke style' tab, we set the stroke (border) width to be 2.000px.
  4. Set the position of the rectangle
    We now have our rectangle, but it is not in the correct location. Inkscape measures positions from the lower left corner of the document, so we need to place our rectangle at x=5 and y=10. Choose the selection tool from the toolbar at the left, left-click anywhere inside the rounded rectangle, and enter the position values in the options toolbar.
  5. Hide the current layer
    Create a new layer
    Next, we need to create a new layer to hold the drop shadow. First, hide the original layer ("Rounded rectangle") by clicking the eye icon at the bottom of the main window. Then, go to Layer > Add Layer... on the menu bar, and create a new layer named "Shadow" below the current layer. We can then create another rounded box in this layer. Make this one 785px wide, 585px high, with corner radii of 5px, and located at x=10 and y=5. In the 'Fill and Stroke dialogue, set the fill RGBA to '00000081', and the blur slider to '0.6'. On the 'stroke paint' tab, select the 'no paint' icon. This will produce a rounded rectangle in a grey colour, partially transparent, and with slightly blurred edges.
  6. The complete image!
    Finally, unhide the "Rounded rectangle" layer, by selecting it in the drop-down box at the bottom of the main window, and left-clicking the eye icon again. Congratulations - you can now see how your rounded box will look! You may want to save your image at this point as an Inkscape .svg file so that you can easily come back and change it later.
  7. Now we need to create the four separate images we will need, and save them in a web format. Inkscape also makes this very easy - simply go to File > Export Bitmap... and select the 'Custom' button in the dialogue box. We can export the relevant parts of our image by entering the coordinates in the x0/y0 and x1/y1 boxes. Remember that all coordinates are measured from the bottom left corner! The best place to cut the image is just before the curve of the rounded corners on the bottom and right-hand edges. As an example, to create the large top left image, we use: x0=0, y0=15, x1=785, y1=600.

Putting it into practice - Editing your template

To implement the rounded corners on a Module, we will use the 'rounded' Module chrome, by including the following <jdoc /> statement:

<jdoc:include type="modules" name="POSITION" style="rounded" />

This creates the following code in the final web page:

<div class="module_menu">
  <div>
    <div>
      <div>
        <h3>Main Menu</h3>
        <ul class="menu">
          <li><!-- various menu items --></li>
        </ul>
      </div>
    </div>
  </div>
</div>

The four nested <div>s give us the layers we need for our four images. We can use the class name of the outer <div> to ensure that we really are dealing with the correct <div>s, and then use the nesting relationship to apply the correct image to each layer.

This is most easily done using an external style sheet, having the following rules:

div.module_menu {
  background: url(../images/rounded_topleft.png) 0 0 no-repeat;
  padding: 0;
}
 
div.module_menu div {
  background: url(../images/rounded_bottomleft.png) 0 100% no-repeat;
  margin: 0;
  border: 0;
}
 
div.module_menu div div{
  background: url(../images/rounded_topright.png) 100% 0 no-repeat;
}
 
div.module_menu div div div {
  background: url(../images/rounded_bottomright.png) 100% 100% no-repeat;
}

The padding, margin and border are needed to ensure that each <div> completely fills the one above. The image URLs are specified relative to the CSS file location.

There is just one more slight problem to be aware of: CSS rules are not exhausted, they are only overridden. This means that, if our Module content includes a <div>, these CSS rules will also apply to that <div> (since it is a <div> inside a <div> inside a <div> inside a <div class="module_menu"> - regardless of the fact that there was an intervening <div>). To overcome this, we need to add another, more specific rule:

div.module_menu div div div div{
  background: none;
}

And that's it - happy coding!

Personal tools
Namespaces

Variants
Actions
Navigation
Joomla! Sites
Toolbox