Archive | CSS RSS feed for this section

Text-Shadow Exposed: Make cool and clever text effects with css text-shadow

29 Sep

The aim of this article is to give you a quick introduction of a css property named text-shadow which was first included in CSS2 (but it’s not implemented in all browsers yet). Nevertheless you can make some cool effects with it, which could only be done before by photoshopping text and rendering it as an image.

Because it’s included in Safari since version 1.1(!) Mac users should be aware of various effects done by this property. In fact, most companys and persons with mac users as their main target audience use this effect on their websites.

This article describes how text-shadow works, what you can do with it and which browsers currently support it. At the end of this article I’ve made up some examples and provide a list of useful resources.

 

Here’s an overview of the headlines in this article. As you can see it’s rather complex and long. Be sure to get a delicious fresh cup of coffee or tea before reading on:

  1. What text-shadow is good for
  2. Which browsers support it
  3. Cross-browser compatibility
  4. How does it work and how to use it
  5. Examples with code & demos
  6. Hack: Safari Text Rendering
  7. More articles and resources

1. What text-shadow is good for

kremalicious navbar

subtle glow in my navigation

The main goal of this property is to give designers and css coders a tool to make text effects, which could only be done before by rendering text as images with all the side effects. Text rendered as an image isn’t searchable and therefore very undelicious for search engines. Another side effect is the fact that images can be way more bigger as one small line of code in terms of file size. As you may know most css-files, which contain the whole layout of a website, are smaller than one image on most websites. So it’s really clever to use a css function instead of images for reducing unnecessary traffic.

text-shadow used on apple.com

text-shadow on Apple.com

Utilizing text-shadow to simulate engraved or stenciled text is widely used on websites. Apple did it everywhere in Mac OS X not just since Leopard (just look at the titlebars). So if you design a website for Mac users you can increase the sexyness of your website, because this particular usage of text-shadow integrates very well with the overall look of Mac OS X. I will explain how to achieve this engraved-text-on-metal effect later on in this article.

2. Which browsers support it?

Safari iconOpera icon
Firefox iconGoogle Chrome iconIn fact, text-shadow is not a new property since it was first defined with CSS2 in 1998 but it was just implemented by the KHTML/WebKit-folks. But it’s available in Safari since version 1.1 (2003), in Konqueror since version 3.4 (I believe, not sure) and Opera9.5. Furthermore it’s also supported by Firefox 3.1/3.5 and finallyGoogle Chrome 2 adds full support for the text-shadow property after they had stripped this from the first version of Chrome.

On the Mac platform WebKit is also used in various other programs with a browser included like Coda from Panic, CSSedit from MacRabbit or NetNewsWire from NewsGator. Also every browser which is powered by the WebKit engine is able to render the text-shadow property, like ShiiraOmniWeb or Epiphany which are either for Mac or Linux.

But with Safari 3.1, the beta release of Opera 9.5, Firefox 3.1 and Google Chrome 2 the text-shadow property is finally finding it’s way to the Windows desktop after 10 years of it’s birth and Opera is the first non-WebKit browser which supports text-shadow.

Here’s a list of some browsers and their compatibilty for the text-shadow property to give you an overview:

Safari 3.1 (Mac/Win) yes, but no multiple shadows
Safari 4 (Mac/Win) yes, full support
Opera 9.5 (Mac/Win/Lin) yes, full support
Firefox 2/3 (Mac/Win/Lin) no
Firefox 3.1/3.5 (Mac/Win/Lin) yes, full support
Google Chrome 1 (Win) no
Google Chrome 2 (Win) yes, full support
IE 7/8 (Win) no
Shiira (Mac) yes, but no multiple shadows
Konqueror (Lin/Mac/Win) yes, full support
iCab (Mac) yes, but no multiple shadows
Epiphany (Lin) yes, since April 2008
Safari on iPhone yes, but no multiple shadows
Nokia Symbian-Smartphones (Series 60) yes
Opera Mini 4.1 yes, no blur radius

But wait, regarding Safari on Mac OS X there’s one more (bad) thing to remember. The Mac OS X 10.5.2 update resulted in minor changes of the WebKit text-shadow rendering. It seems that with this update text-shadow is finally rendered correctly as WebKit added one extra pixel to the shadow offset on 10.4.11 and 10.5.1.

3. Any chance of cross-browser compatibility?

So the major browser Internet Explorer doesn’t support it yet but just don’t count on Internet Explorer. I guess they are happy withcoding their own non-standard version of CSS for IE9 and making shadows with those DXImageTransform.Microsoft.Shadow-stuffwhich in the end just looks horrible. So even IE 9 won’t have it included.

But with Firefox 3.1 including text-shadow all major browsers except Internet Explorer are now supporting it. So you can start using it all around your next projects just with a lot of other techniques which in the end aren’t available in Internet Explorer.

One cross-browser trick would be to use conditional tags and serve Internet Explorer users different stylesheets with either a cross-browser compatible hack or via the old school way with text rendered as images. If you don’t need the blur radius value for your desired effect than there’s a nice idea on Design Meme for this problem which includes producing a shadow with the css pseudo-element :before.

Now that you’re aware of it’s compatibility with the various browsers we can take a look at the syntax of the text-shadow property.

4. How does it work and how to use it

When defined in a css-stylesheet the property syntax should look like this:

p { text-shadow: 1px 1px 1px #000; }

The first two values specify the length of the shadow offset. The first value specifies the horizontal distance and the second specifies the vertical distance of the shadow. The third value specifies the blur radius and the last value describes the color of the shadow:

1. value = The X-ccordinate
2. value = The Y-coordinate
3. value = The blur radius
4. value = The color of the shadow

Using positive numbers as the first two values ends up with placing the shadow to the right of the text horizontically (first value) and placing the shadow below the text vertically (second value).

The third value, the blur radius, is an optional value which can be specified but don’t have to. It’s the amount of pixels the text is stretched which causes a blur effect. If you don’t use the third value it is threated as if you sepcified a blur radius of zero.

Alternatiely, for WebKit-based browsers, you can use rgba values instead of hex code colors as the fourth value. The last number stands for transparency and can be set between 0.0 and 1.0 so you can make the text-shadow more subtle:

p { text-shadow: 1px 1px 1px rgba(255,255,255, .5); }

Of course the effects done by this property often depend on the colors of your text and your background, so let’s take a look at what we can do with all those combinations.

5. Examples with code & demos

I’ve made up some examples to show you the possibilities of this css property. Every example code follows a text example which is rendered by your browser. Below that you’ll find a screenshot of the described effect rendered in Safari 3.1 on Mac OS X 10.5.2 so the non-WebKit and non-Opera Internet Explorer users can see the effect.

5.1 Simple drop shadow

With the following lines of css code you get black text on white background with a smooth black drop shadow.The shadow is placed 2 pixels right and 2 pixels below the text and has a blur radius of 3:

color: #000;
background: #fff;
text-shadow: 2px 2px 3px #000;
I’m a text with a smooth shadow

image

Or you can make it not so smooth but also good looking by ignoring the blur radius and setting a lighter color for the shadow:

color: #000;
background: #fff;
text-shadow: 2px 2px #000;
I’m a text with no smooth shadow

image

Using some negative values you can make the shadow look like it’s lightsource is placed below the text:

color: #000;
background: #fff;
text-shadow: 2px -2px 3px #000;
I’m a text with a smooth shadow

image

Of course you can make it more funky and horrible to read:

color: #33cc33;
background: #fff;
text-shadow: 2px 2px 2px #ff3300;
I’m funky colored text

image

5.2 Apple style (engraved text on metal)

With those lines you get this engraved-text-on-metal effect often used by Apple. You should use a grey background and a very dark text color for this. It’s nothing more than a white or light grey shadow which is placed 1px below the text. You can use a blur of 1 to make it look more round. I’ve used bold text to make the effect more visible:

color: #000;
background: #666;
text-shadow: 0px 1px 1px #fff;
I’m engraved text

image

This even works the other way around on a black background with grey text by adjusting only the color values:

color: #666;
background: #000;
text-shadow: 0px 1px 0px #ccc;
I’m engraved text on black

image

Or you can make this one which looks like the text stands out from the background:

color: #fff;
background: #666;
text-shadow: 0px 1px 1px #000;
I’m on top of the background

image

5.3 Make your text glow

By utilizing the blur radius we can achieve some interesting effects. Here’s some subtle glowing white text on a black background:

color: #fff;
background: #000;
text-shadow: 1px 1px 6px #fff;
I’m subtle glowing text

image

You can also make the whole text blurry by using the same color for text and shadow with no offset:

color: #fff;
background: #666;
text-shadow: 0px 0px 3px #fff;
I’m also glowing but more blurry

image

We can make it quite mysterious by using the same color for text and background and make the text just visible through text-shadow. Remember that the same color for text and background can be bad for usability…:

color: #000;
background: #000;
text-shadow: 1px 1px 4px #fff;
I’m pretty mysterious looking text

image

Or the other way around to make it look light and… milky:

color: #fff;
background: #fff;
text-shadow: 1px 1px 4px#000;
I’m pretty milky looking text

image

5.4 Dublicate your text

With text-shadow you can make pixel-perfect dublicates of any text. Just add some pixels to your font-size and use it as a value for the vertical description of the shadow offset:

color: #000;
background: #fff;
text-shadow: 0px 20px #000;
Which line is text, which is shadow?

image

5.5 Multiple shadows

Sadly Safari 3 isn’t able to render more than one shadow on one element. It just renders the first property description and will ignore all others. But using multiple shadows looks awesome. So currently the following will only work in Opera 9.5 beta or Konqueror. Just have a look at the screenshot below the example if you’re not using these browsers. Due to the lack of support for this in Safari the screenshot below the example is rendered in Opera 9.5 beta on Mac OS X 10.5.2. For no reason Opera 9.5 beta doesn’t render the background color:

color: #000;
background: #000;
text-shadow: 0 0 4px #ccc, 0 -5px 4px #ff3, 2px -10px 6px #fd3, -2px -15px 11px #f80, 2px -18px 18px #f20;
Isn’t this awesome?

image

6. Hack: Avoid jagged light-on-dark text rendering in Safari

sub-pixel rendering

sub-pixel rendering (click to zoom)

More than a hack than an effect but it addresses the poor light-on-dark text rendering in Safari. This is caused by the sub-pixel rendering of OS X’s Quartz 2D layer as a part of the Core Graphics framework. Also Safari 3.1 on Windows uses sub pixel rendering instead of plain anti-aliasing.

anti-alias rendering through text-shadow

anti-alias rendering through text-shadow (click to zoom)

In most situations this improves the legibility and smoothness of all 2D-text rendered throughout the Mac OS X interface which makes everything look so gorgeous. But it has some rough problems with light text on dark backgrounds in Safari This problem doesn’t exist when using anti-aliasing.

And since 24ways’ and Cameron’s discovery we know that Safari renders all text-shadow-styled text with plain anti-aliasing instead of sub-pixels. So we can add a text-shadow with an offset of 0px to the desired text style:

text-shadow: 0 0 0 #000;

This causes Safari 3 to use anti-aliasing and make your text on dark backgrounds more legible with it.

But this won’t work with the new Safari 4 (public beta) as John pointed out in the comments. To just cite him:

Apparently if your shadow has no blur, then the text will be sub-pixel rendered. But more than 1px blurred uses the anti-alias rendering like “usual.”

But fear not. Rogie King already came up with a solution for this which you can read here:

CSS text shadows and background sizing

14 Feb

Introduction

CSS3 offers advancements in how Web designers can apply design touches to their designs. One of the most often wished for properties – text-shadow, which allows easy creation of drop shadows – looks to be popular as new versions of popular browsers are starting to support the property.

I will also look at background-size – this is a CSS property that will let Web designers set the backgrounds of elements so that the background images can stretch or fill the entire background image, if widely implemented.

Together both CSS properties can add unique twists to everyday Web design with minimal effort. In this article I will explore both of these, showing how they work with some simple examples. (you can download the code examples here.)

Bringing Light to Text Shadows

Text shadows were first seen in the CSS 2 specification, but they didn’t make into the 2.1 specification since browsers weren’t supporting the property. Within the CSS 3 specification however the text-shadow property has made a reappearance.

Let’s take a look at a CSS rule that utilizes the text-shadow property to get a better idea of the values it accepts:

h1 { text-shadow: #555 3px 3px 2px; }

The first value sets the color for the shadow. In the example shown in Figure 1 (text-shadows01.html), the shortcut for the value #555555 is being used.

A text shadow applied to the heading

Figure 1: The text-shadow property applied to a heading.

The second value sets the x-coordinates for the shadow. The greater the value, the further away from the right of the text the shadow is placed. A negative value pulls the shadow to the left.

In the Figure 2 (text-shadows02.html), a value of 20 pixels is used for the x-coordinate – this pulls the shadow to the right:

h1 { text-shadow: #555 20px 3px 2px; }

The text shadow has moved to the right of the text

Figure 2: The shadow moves to the right.

The third value sets the y-coordinates for the shadow. The greater the value, the further below the text the shadow is placed. A negative value pulls the shadow above the text.

In the Figure 3 (text-shadows03.html), a value of 20 pixels is used for the y-coordinate – this pulls the shadow down below the text:

h1 { text-shadow: #555 3px 20px 2px; }

The text shadow has moved below the text

Figure 3: The shadow moved to the bottom.

The last value sets the blur radius of the shadow. The greater the value, the more diffuse the blur effect. In Figure 4 (text-shadows04.html), a value of 20 pixels is used for the blur radius:

h1 { text-shadow: #555 3px 3px 20px; }

More blur on the text shadow

Figure 4: A large diffuse drop shadow.

While the text-shadow property allows for an easy addition of a graphic effect to a Web page, some restraint should be applied.

For starters, the Web is two-dimensional medium. You shouldn’t overdo it – adding cheesy Photoshop effects like beveling or shadows forces elements on a page to appear three dimensional. The greater the bevel or length of the drop shadow, the greater the trespass in the design, as these effects draw attention to the elements rather than letting the design as a whole communicate to the reader.

I’d recommend one to two pixels depth at most for effects like text shadow. This touch gives a slight lift off the Web page, but doesn’t attract too much attention to itself, letting the overall design of the page work as a whole.

Lastly, make sure to bulletproof your design so that it takes into account browsers that don’t support text-shadow. For example, don’t set the color of the headline text to be the same as the background otherwise browsers that don’t support the text-shadow property will appear to display a blank area, as shown in Figure 5, leaving your site’s visitors without legible text.

No text shadow in Firefox

Figure 5: The heading appears gone in the Firefox browser.

Support for Text-Shadow

Modern browsers are including support for text-shadow includes Safari 3 and Opera 9.5.

There are methods discussed elsewhere that go into detail on how to get a cross-browser support for text-shadow in other browsers like Firefox and Mozilla through a mixture of CSS hacks, pseudo-elements and proprietary filters. Those methods however seem rather excessive for such a simple effect and not as graceful as a cut and dry CSS3 property.

The Story on Background Sizing

As Web designers, it’s important to make sure every image is properly optimized and sized before a site goes live. These extra steps help to keep file sizes low and speeds browser rendering times, but the Web isn’t a pixel perfect medium.

As elements can be resized, perfectly sized background images can show their edges. These are times when stretching or filling an element’s background image would be most helpful as shown in Figure 6 (background-sizing01.html.)

This background image is overrun by text

Figure 6: The background image is overrun by text.

In CSS3, there’s a property that can help do just that: background-size. It should probably be called “background-stretching” instead, since it can expand an image to fill the background of an element as shown in Figure 7 (background-sizing02.html):

div { background-image: url(bkgd_col.png); background-size: 100% auto; background-repeat: repeat-y; border: 1px solid #466900; }

The image resizes to the width of the element

Figure 7: The background image resizes to the width of the element.

The first value for the background-size property sets the width and the second one sets the height. If there is only one value, its value is applied to both the width and height. The background-size property accepts percentage and length values as well as auto.

An interesting effect is to tile out the images perfectly in the background. In this example, the backgrounds are set to place two copies of the image side-by-side as shown in Figure 8 (background-sizing03.html).

body { background-image: url(starstripes.png); background-size: 50% auto; background-repeat: repeat-x; margin-top: 30%; }

Background sizing in action

Figure 8: Perfectly placing two images in the background.

What’s happening is that the first value of background-size splits the width of an element in half and tells the browser to showcase two images in the available space. The second value of auto tells the browser to use as much space as needed for the height so that the aspect ratio of the image is kept in place.

A word of warning: when using raster images like GIF, JPEG or PNGs, images will start to look jagged as they resize. (One day all browsers will support SVG and it will be a beautiful thing.)

Support for Background Size

Currently, support for background-size is limited to Safari 3 and Opera 9.5. And in order to use the property in those browsers, proprietary CSS property values need to be used: -o-background-size and -webkit-background-size. The following declaration block would be used in order to get the greatest support from browsers side by side at present:

body { background-image: url(starstripes.png); background-size: 50% auto; -o-background-size: 50% auto; -webkit-background-size: 50% auto; background-origin: border; background-repeat: repeat-x; margin-top: 30%; }

As the CSS3 spec solidifies, the proprietary values should be removed, and replaced with the single standard value.

In Conclusion

While not fully supported in most browsers, the future of CSS3 holds much promise. With the adoption of new CSS3 properties, Web designers can look to making their designs more visually interesting and, hopefully, a little easier to produce.

Tracking Upload Progress with PHP and JavaScript

14 Feb

A problem that has plagued web developers for years is how to add real-time information to their applications, such as a progress bar for file uploads. Users are impatient; they don’t want to sit and wait while the browser is doing something and wonder whether it has frozen or if they have a slow connection. Providing a progress indicator gives users useful information and lets them know exactly what’s going on.

At first thought, you might think accomplishing this can be done easily by first obtaining the file’s size from the user’s computer and then performing some simple calculations against the directory on the server where the file is being uploaded to. On second thought, you’d find things aren’t quite that simple.

JavaScript can access a file’s name, type, and even the width and height of a local image, but it wasn’t until HTML5 that it could access a file’s size. Unfortunately, HTML5 still isn’t a completed standard yet and isn’t uniformly supported across all browsers. An alternate solution is to rely on a Flash, Java, or ActiveX plugin; no thanks, I’ll pass. Yet another solution is to install the Alternative PHP Cache extension, but that may not be available depending on your hosting environment and it seems like overkill for such a small task such as this.

It would seem as though all the options are fraught with nuisances and the task has quickly become a headache. But in the words of Yoda, “No… There is another.”

One of the many reasons I love PHP is that it makes seemingly difficult tasks easy. As of PHP 5.4, they’ve done it again with a new set of configuration directives, session.upload_progress.

In this article I’ll show you how this feature can be used to create a simple upload progress bar without any external libraries or browser dependencies. I’ll first discuss how it works, and then I’ll walk you through creating the four files needed to accomplish the task (an upload form, some JavaScript, a little CSS, and a file to return the status of the upload).

Session Upload Progress

Besides the usual requirements to allow file uploads, there are two more to track the progress. The session.upload_progress.enabled directive must be enabled and there must be a hidden field in your web form with the name specified by the session.upload_progress.name directive. When session.upload_progress.enabled is true (as it is by default in PHP 5.4 and presumably beyond) and $_POST[session.upload_progress.name] is sent during an upload, information about the file transfer is made available in the $_SESSION superglobal array.

The print_r() output of the $_SESSION array will look similar to the following during a file transfer:

Array
(
    [upload_progress_myForm] => Array
        (
            [start_time] => 1323733740
            [content_length] => 721127769
            [bytes_processed] => 263178326
            [done] =>
            [files] => Array
                (
                    [0] => Array
                        (
                            [field_name] => userfile
                            [name] => ubuntu-10.04.3-desktop-i386.iso
                            [tmp_name] =>
                            [error] => 0
                            [done] =>
                            [start_time] => 1323733740
                            [bytes_processed] => 263178026
                        )
                )
        )
)

When you are developing either locally or on a fast network and upload small files, you won’t be able to visually observe the progress because the transfer happens so fast. In this case, you might want to try transferring a large file. Make sure the settings in your php.ini file allow large uploads, specifically the post_max_size and upload_max_filesize directives, and then verify they are sane values when you go to production.

Create the Form

The first file I’ll present is the upload form. Just to keep things as simple as possible, the example will post to itself and only handle one file upload at a time. Additionally, I won’t bother saving the file after it has been uploaded.

Here’s the code for form.php:

01 <?php
02 if ($_SERVER["REQUEST_METHOD"] == "POST" && !empty($_FILES["userfile"])) {
03     // move_uploaded_file()
04 }
05 ?>
06 <html>
07  <head>
08   <title>File Upload Progress Bar</title>
09   <link rel="stylesheet" type="text/css" href="style.css"/>
10  </head>
11  <body>
12   <div id="bar_blank">
13    <div id="bar_color"></div>
14   </div>
15   <div id="status"></div>
16   <form action="<?php echo $_SERVER["PHP_SELF"]; ?>" method="POST"
17    id="myForm" enctype="multipart/form-data" target="hidden_iframe">
18    <input type="hidden" value="myForm"
19     name="<?php echo ini_get("session.upload_progress.name"); ?>"/>
20    <input type="file" name="userfile"/><br/>
21    <input type="submit" value="Start Upload" />
22   </form>
23   "hidden_iframe" name="hidden_iframe" src="about:blank">
24   <script type="text/javascript" src="script.js"></script>
25  </body>
26 </html>

In the example the code to actually process the file has been omitted to keep things simple. If you’re interested in what such code should look like, check out the article File Uploads with PHP by Timothy Boronczyk.

After the head section which provides the page’s title and includes the stylesheet, you’ll notice a small collection of div elements. The div with the ID “bar_blank” is the container for the progress bar. The div with the ID “bar_color” will be dynamically updated as the file upload progresses. The “status” div will display the numeric value of the percent uploaded.

The form is set to submit to the same URL and its target attribute points to a hidden iframe element. Submitting a form to a hidden frame allows you to keep the visitor on the same page while the work is being done in the background. In fact, this is a common practice when doing “Ajax file uploads” since it isn’t possible to send the contents of a file directly using JavaScript’s XmlHttpRequest object.

Within the form, the special hidden field needed to populate the $_SESSION array appears, followed by a file upload input and submit button. Submitting the form will trigger a JavaScript function named startUpload() which will be defined by the included JavaScript file.

At the bottom of the page is the hidden frame to which the form will post and the import of the script.js file.

Add Some Style

The next file, style.css, is pretty straight-forward. I’ve defined the size of the progress bar container and given it a 1px black border, the color of the progress bar as it’s loading, and both the iframe and the progress bar are hidden.

01 #bar_blank {
02   border: solid 1px #000;
03   height: 20px;
04   width: 300px;
05 }
06
07 #bar_color {
08   background-color: #006666;
09   height: 20px;
10   width: 0px;
11 }
12
13 #bar_blank, #hidden_iframe {
14   display: none;
15 }

Client-Side Functionality

The script.js file is the largest of the group of files. It contains six functions which I will discuss below. Many people like to use jQuery to provide some of the functionality here, and you are certainly free to do so if you wish, but I personally prefer the old-school approach. Similar to how the Japanese place a higher value on hand crafted goods, I just feel more passionate about the code if it is my own.

01 function toggleBarVisibility() {
02     var e = document.getElementById("bar_blank");
03     e.style.display = (e.style.display == "block") ? "none" : "block";
04 }
05
06 function createRequestObject() {
07     var http;
08     if (navigator.appName == "Microsoft Internet Explorer") {
09         http = new ActiveXObject("Microsoft.XMLHTTP");
10     }
11     else {
12         http = new XMLHttpRequest();
13     }
14     return http;
15 }
16
17 function sendRequest() {
18     var http = createRequestObject();
19     http.open("GET", "progress.php");
20     http.onreadystatechange = function () { handleResponse(http); };
21     http.send(null);
22 }
23
24 function handleResponse(http) {
25     var response;
26     if (http.readyState == 4) {
27         response = http.responseText;
28         document.getElementById("bar_color").style.width = response + "%";
29         document.getElementById("status").innerHTML = response + "%";
30
31         if (response < 100) {
32             setTimeout("sendRequest()", 1000);
33         }
34         else {
35             toggleBarVisibility();
36             document.getElementById("status").innerHTML = "Done.";
37         }
38     }
39 }
40
41 function startUpload() {
42     toggleBarVisibility();
43     setTimeout("sendRequest()", 1000);
44 }
45
46 (function () {
47     document.getElementById("myForm").onsubmit = startUpload;
48 })();

The toggleBarVisibility() function sets an appropriate style on the “bar_blank” div to show or hide the progress bar as needed. Initially it starts out hidden, but will be displayed once an upload starts and hidden again when an upload finishes.

The createRequestObject() function creates an XMLHttpRequest or ActiveXObject object based on the user’s browser. This is probably the function most people would look to jQuery or some other JavaScript framework to provide.

The sendRequest() function requests the progress.php file with a GET request, and then invokes the handleResponse() function to handle the returned data.

The handleResponse() function handles the response from progress.php which will be a number between 1-100 depending on the file upload progress. I also update the “status” div with the appropriate value. If the current percent is below 100 then I call JavaScript’s native setTimeout() function to send another request for an update after 1 second (you may want to adjust this value as appropriate), otherwise I hide the progress bar again and set the status to “Done.”

The startUpload() function makes the upload bar visible and sends a request for an update after a delay of 1 second. This small delay is needed in order to give the upload time to start.

The final function is a self-executing anonymous function which registers startUpload() with the form’s submit event.

Real-Time Progress

The last file that brings everything together is the progress.php file:

01 <?php
02 session_start();
03
04 $key = ini_get("session.upload_progress.prefix") . "myForm";
05 if (!empty($_SESSION[$key])) {
06     $current = $_SESSION[$key]["bytes_processed"];
07     $total = $_SESSION[$key]["content_length"];
08     echo $current < $total ? ceil($current / $total * 100) : 100;
09 }
10 else {
11     echo 100;
12 }

The script performs some simple math on the current number of bytes transferred divided by the total file size, multiplied by 100 and rounded off to give a percent.

Information about the transfer is keyed with a concatenation of the session.upload_progress.prefix directive’s value and the hidden session.upload_progress.name field’s value. Because my form passed “myForm”, the session’s key is determined with ini_get("session.upload_progress.prefix") . "myForm".

Here’s a screenshot of the progress bar in action:

upload progress bar

Fine-Tuning the Behavior

PHP provides some additional directives to help fine-tune the behavior of session uploads you should be aware of. For example, session.upload_progress.cleanup, which is set to 1 by default, cleans up the extra session data immediately after the upload has finished. You need to be careful to avoid a potential race condition.

Take a look again at the code in progress.php and you’ll notice that I check to see if $_SESSION[$key] is empty or not before proceeding. My JavaScript functions fire off every second as long as the result returned from progress.php is less than 100. If session.upload_progress.cleanup is enabled and my script fetches 99% of the upload and a 1/2-second later the upload finishes, $_SESSION[$key] would not exist for the next check. If I didn’t take that into consideration then my JavaScript function might keep firing, even after the upload finished.

Another two directives are session.upload_progress.freq and session.upload_progress.min_freq which both determine how often the session should be updated. The value of freq can be given in either bytes (i.e., 100) or the percentage of total bytes (i.e., 2%). The value of min_freq is given in seconds and indicates the minimum number of seconds between updates. Obviously if min_freq was set to update every 1 second, it would be pointless for your JavaScript to check every 100 milliseconds.

Summary

You should now have a solid grasp on how to create a progress bar for file uploads using the session upload progress feature. Moving forward, I encourage you to experiment with uploading multiple files, giving the option to cancel an upload in progress using $_SESSION[$key]["cancel_upload"], or whatever other ideas your mind can muster. Please share in the comments your experiences and improvements you’ve made for others to benefit from and enjoy as well!

The 30 CSS Selectors you Must Memorize

14 Feb

So you learned the base id, class, and descendant selectors – and then called it a day? If so, you’re missing out on an enormous level of flexibility. While many of the selectors mentioned in this article are part of the CSS3 spec, and are, consequently, only available in modern browsers, you owe it to yourself to commit these to memory.


1. *

  1. * {
  2.  margin: 0;
  3.  padding: 0;
  4. }

Let’s knock the obvious ones out, for the beginners, before we move onto the more advanced selectors.

The star symbol will target every single element on the page. Many developers will use this trick to zero out the margins and padding. While this is certainly fine for quick tests, I’d advise you to never use this in production code. It adds too much weight on the browser, and is unnecessary.

The * can also be used with child selectors.

  1. #container * {
  2.  border: 1px solid black;
  3. }

This will target every single element that is a child of the #container div. Again, try not to use this technique very much, if ever.

View Demo

Compatibility

  • IE6+
  • Firefox
  • Chrome
  • Safari
  • Opera

2. #X

  1. #container {
  2.    width: 960px;
  3.    margin: auto;
  4. }

Prefixing the hash symbol to a selector allows us to target by id. This is easily the most common usage, however be cautious when using id selectors.

Ask yourself: do I absolutely need to apply an id to this element in order to target it?

id selectors are rigid and don’t allow for reuse. If possible, first try to use a tag name, one of the new HTML5 elements, or even a pseudo-class.

View Demo

Compatibility

  • IE6+
  • Firefox
  • Chrome
  • Safari
  • Opera

3. .X

  1. .error {
  2.   color: red;
  3. }

This is a class selector. The difference between ids and classes is that, with the latter, you can target multiple elements. Use classes when you want your styling to apply to a group of elements. Alternatively, use ids to find a needle-in-a-haystack, and style only that specific element.

View Demo

Compatibility

  • IE6+
  • Firefox
  • Chrome
  • Safari
  • Opera

4. X Y

  1. li a {
  2.   text-decoration: none;
  3. }

The next most comment selector is the descendant selector. When you need to be more specific with your selectors, you use these. For example, what if, rather than targeting all anchor tags, you only need to target the anchors which are within an unordered list? This is specifically when you’d use a descendant selector.

Pro-tip – If your selector looks like X Y Z A B.error, you’re doing it wrong. Always ask yourself if it’s absolutely necessary to apply all of that weight.

View Demo

Compatibility

  • IE6+
  • Firefox
  • Chrome
  • Safari
  • Opera

5. X

  1. a { color: red; }
  2. ul { margin-left: 0; }

What if you want to target all elements on a page, according to their type, rather than an id or classname? Keep it simple, and use a type selector. If you need to target all unordered lists, use ul {}.

View Demo

Compatibility

  • IE6+
  • Firefox
  • Chrome
  • Safari
  • Opera

6. X:visited and X:link

  1. a:link { color: red; }
  2. a:visted { color: purple; }

We use the :link pseudo-class to target all anchors tags which have yet to be clicked on.

Alternatively, we also have the :visited pseudo class, which, as you’d expected, allows us to apply specific styling to only the anchor tags on the page which have been clicked on, or visited.

View Demo

Compatibility

  • IE7+
  • Firefox
  • Chrome
  • Safari
  • Opera

7. X + Y

  1. ul + p {
  2.    color: red;
  3. }

This is referred to as an adjacent selector. It will select only the element that is immediately preceded by the former element. In this case, only the first paragraph after each ul will have red text.

View Demo

Compatibility

  • IE7+
  • Firefox
  • Chrome
  • Safari
  • Opera

8. X > Y

  1. div#container > ul {
  2.   border: 1px solid black;
  3. }

The difference between the standard X Y and X > Y is that the latter will only select direct children. For example, consider the following markup.

  1. <div id=”container”>
  2.    <ul>
  3.       <li> List Item
  4.         <ul>
  5.            <li> Child </li>
  6.         </ul>
  7.       </li>
  8.       <li> List Item </li>
  9.       <li> List Item </li>
  10.       <li> List Item </li>
  11.    </ul>
  12. </div>

A selector of #container > ul will only target the uls which are direct children of the div with an id of container. It will not target, for instance, the ul that is a child of the first li.

For this reason, there are performance benefits in using the child combinator. In fact, it’s recommended particularly when working with JavaScript-based CSS selector engines.

View Demo

Compatibility

  • IE7+
  • Firefox
  • Chrome
  • Safari
  • Opera

9. X ~ Y

  1. ul ~ p {
  2.    color: red;
  3. }

This sibling combinator is similar to X + Y, however, it’s less strict. While an adjacent selector (ul + p) will only select the first element that is immediately preceded by the former selector, this one is more generalized. It will select, referring to our example above, any p elements, as long as they follow a ul.

View Demo

Compatibility

  • IE7+
  • Firefox
  • Chrome
  • Safari
  • Opera

10. X[title]

  1. a[title] {
  2.    color: green;
  3. }

Referred to as an attributes selector, in our example above, this will only select the anchor tags that have a title attribute. Anchor tags which do not will not receive this particular styling. But, what if you need to be more specific? Well…

View Demo

Compatibility

  • IE7+
  • Firefox
  • Chrome
  • Safari
  • Opera

11. X[href=”foo”]

  1. a[href=”http://net.tutsplus.com”%5D {
  2.   color: #1f6053; /* nettuts green */
  3. }

The snippet above will style all anchor tags which link to http://net.tutsplus.com; they’ll receive our branded green color. All other anchor tags will remain unaffected.

Note that we’re wrapping the value in quotes. Remember to also do this when using a JavaScript CSS selector engine. When possible, always use CSS3 selectors over unofficial methods.

This works well, though, it’s a bit rigid. What if the link does indeed direct to Nettuts+, but, maybe, the path is nettuts.com rather than the full url? In those cases we can use a bit of the regular expressions syntax.

View Demo

Compatibility

  • IE7+
  • Firefox
  • Chrome
  • Safari
  • Opera

12. X[href*=”nettuts”]

  1. a[href*=”tuts”] {
  2.   color: #1f6053; /* nettuts green */
  3. }

There we go; that’s what we need. The star designates that the proceeding value must appear somewhere in the attribute’s value. That way, this covers nettuts.com, net.tutsplus.com, and even tutsplus.com.

Keep in mind that this is a broad statement. What if the anchor tag linked to some non-Envato site with the string tuts in the url? When you need to be more specific, use ^ and &, to reference the beginning and end of a string, respectively.

View Demo

Compatibility

  • IE7+
  • Firefox
  • Chrome
  • Safari
  • Opera

13. X[href^=”http”]

  1. a[href^=”http”] {
  2.    background: url(path/to/external/icon.png) no-repeat;
  3.    padding-left: 10px;
  4. }

Ever wonder how some websites are able to display a little icon next to the links which are external? I’m sure you’ve seen these before; they’re nice reminders that the link will direct you to an entirely different website.

This is a cinch with the carat symbol. It’s most commonly used in regular expressions to designate the beginning of a string. If we want to target all anchor tags that have a href which begins with http, we could use a selector similar to the snippet shown above.

Notice that we’re not searching for http://; that’s unnecessary, and doesn’t account for the urls that begin with https://.

Now, what if we wanted to instead style all anchors which link to, say, a photo? In those cases, let’s search for the end of the string.

View Demo

Compatibility

  • IE7+
  • Firefox
  • Chrome
  • Safari
  • Opera

14. X[href$=”.jpg”]

  1. a[href$=”.jpg”] {
  2.    color: red;
  3. }

Again, we use a regular expressions symbol, $, to refer to the end of a string. In this case, we’re searching for all anchors which link to an image — or at least a url that ends with .jpg. Keep in mind that this certainly won’t work for gifs and pngs.

View Demo

Compatibility

  • IE7+
  • Firefox
  • Chrome
  • Safari
  • Opera

15. X[data-*=”foo”]

  1. a[data-filetype=”image”] {
  2.    color: red;
  3. }

Refer back to number eight; how do we compensate for all of the various image types: png, jpeg,jpg, gif? Well, we could create multiple selectors, such as:

  1. a[href$=”.jpg”],
  2. a[href$=”.jpeg”],
  3. a[href$=”.png”],
  4. a[href$=”.gif”] {
  5.    color: red;
  6. }

But, that’s a pain in the butt, and is inefficient. Another possible solution is to use custom attributes. What if we added our own data-filetype attribute to each anchor that links to an image?

  1. <a href=”path/to/image.jpg” data-filetype=”image”> Image Link </a>

Then, with that hook in place, we can use a standard attributes selector to target only those anchors.

  1. a[data-filetype=”image”] {
  2.    color: red;
  3. }
View Demo

Compatibility

  • IE7+
  • Firefox
  • Chrome
  • Safari
  • Opera

16. X[foo~=”bar”]

  1.  a[data-info~=”external”] {
  2.    color: red;
  3. }
  4. a[data-info~=”image”] {
  5.    border: 1px solid black;
  6. }

Here’s a special one that’ll impress your friends. Not too many people know about this trick. The tilda (~) symbol allows us to target an attribute which has a spaced-separated list of values.

Going along with our custom attribute from number fifteen, above, we could create a data-info attribute, which can receive a space-separated list of anything we need to make note of. In this case, we’ll make note of external links and links to images — just for the example.

  1. “<a href=”path/to/image.jpg” data-info=”external image”> Click Me, Fool </a>

With that markup in place, now we can target any tags that have either of those values, by using the ~ attributes selector trick.

  1. /* Target data-info attr that contains the value “external” */
  2. a[data-info~=”external”] {
  3.    color: red;
  4. }
  5. /* And which contain the value “image” */
  6. a[data-info~=”image”] {
  7.   border: 1px solid black;
  8. }

Pretty nifty, ay?

View Demo

Compatibility

  • IE7+
  • Firefox
  • Chrome
  • Safari
  • Opera

17. X:checked

  1. input[type=radio]:checked {
  2.    border: 1px solid black;
  3. }

This pseudo class will only target a user interface element that has been checked – like a radio button, or checkbox. It’s as simple as that.

View Demo

Compatibility

  • IE9+
  • Firefox
  • Chrome
  • Safari
  • Opera

18. X:after

The before and after pseudo classes kick butt. Every day, it seems, people are finding new and creative ways to use them effectively. They simply generate content around the selected element.

Many were first introduced to these classes when they encountered the clear-fix hack.

  1. .clearfix:after {
  2.     content: “”;
  3.     display: block;
  4.     clear: both;
  5.     visibility: hidden;
  6.     font-size: 0;
  7.     height: 0;
  8.     }
  9. .clearfix {
  10.    *display: inline-block;
  11.    _height: 1%;
  12. }

This hack uses the :after pseudo class to append a space after the element, and then clear it. It’s an excellent trick to have in your tool bag, particularly in the cases when the overflow: hidden; method isn’t possible.

For another creative use of this, refer to my quick tip on creating shadows.

According to the CSS3 Selectors specification, you should technically use the pseudo element syntax of two colons ::. However, to remain compatible, the user-agent will accept a single colon usage as well. In fact, at this point, it’s smarter to use the single-colon version in your projects.

Compatibility

  • IE8+
  • Firefox
  • Chrome
  • Safari
  • Opera

19. X:hover

  1. div:hover {
  2.   background: #e3e3e3;
  3. }

Oh come on. You know this one. The official term for this is user action pseudo class. It sounds confusing, but it really isn’t. Want to apply specific styling when a user hovers over an element? This will get the job done!

Keep in mind that older version of Internet Explorer don’t respond when the :hover pseudo class is applied to anything other than an anchor tag.

You’ll most often use this selector when applying, for example, a border-bottom to anchor tags, when hovered over.

  1. a:hover {
  2.  border-bottom: 1px solid black;
  3. }

Pro-tipborder-bottom: 1px solid black; looks better than text-decoration: underline;.

Compatibility

  • IE6+ (In IE6, :hover must be applied to an anchor element)
  • Firefox
  • Chrome
  • Safari
  • Opera

20. X:not(selector)

  1. div:not(#container) {
  2.    color: blue;
  3. }

The negation pseudo class is particularly helpful. Let’s say I want to select all divs, except for the one which has an id of container. The snippet above will handle that task perfectly.

Or, if I wanted to select every single element (not advised) except for paragraph tags, we could do:

  1. *:not(p) {
  2.   color: green;
  3. }
View Demo

Compatibility

  • IE9+
  • Firefox
  • Chrome
  • Safari
  • Opera

21. X::pseudoElement

  1. p::first-line {
  2.    font-weight: bold;
  3.    font-size: 1.2em;
  4. }

We can use pseudo elements (designated by ::) to style fragments of an element, such as the first line, or the first letter. Keep in mind that these must be applied to block level elements in order to take effect.

A pseudo-element is composed of two colons: ::

Target the First Letter of a Paragraph

  1. p::first-letter {
  2.    float: left;
  3.    font-size: 2em;
  4.    font-weight: bold;
  5.    font-family: cursive;
  6.    padding-right: 2px;
  7. }

This snippet is an abstraction that will find all paragraphs on the page, and then sub-target only the first letter of that element.

This is most often used to create newspaper-like styling for the first-letter of an article.

Target the First Line of a Paragraph

  1. p::first-line {
  2.    font-weight: bold;
  3.    font-size: 1.2em;
  4. }

Similarly, the ::first-line pseudo element will, as expected, style the first line of the element only.

“For compatibility with existing style sheets, user agents must also accept the previous one-colon notation for pseudo-elements introduced in CSS levels 1 and 2 (namely, :first-line, :first-letter, :before and :after). This compatibility is not allowed for the new pseudo-elements introduced in this specification.” – Source

View Demo

Compatibility

  • IE6+
  • Firefox
  • Chrome
  • Safari
  • Opera

22. X:nth-child(n)

  1. li:nth-child(3) {
  2.    color: red;
  3. }

Remember the days when we had no way to target specific elements in a stack? The nth-child pseudo class solves that!

Please note that nth-child accepts an integer as a parameter, however, this is not zero-based. If you wish to target the second list item, use li:nth-child(2).

We can even use this to select a variable set of children. For example, we could do li:nth-child(4n) to select every fourth list item.

View Demo

Compatibility

  • IE9+
  • Firefox 3.5+
  • Chrome
  • Safari

23. X:nth-last-child(n)

  1. li:nth-last-child(2) {
  2.    color: red;
  3. }

What if you had a huge list of items in a ul, and only needed to access, say, the third to the last item? Rather than doing li:nth-child(397), you could instead use the nth-last-child pseudo class.

This technique works almost identically from number sixteen above, however, the difference is that it begins at the end of the collection, and works its way back.

View Demo

Compatibility

  • IE9+
  • Firefox 3.5+
  • Chrome
  • Safari
  • Opera

24. X:nth-of-type(n)

  1. ul:nth-of-type(3) {
  2.    border: 1px solid black;
  3. }

There will be times when, rather than selecting a child, you instead need to select according to the type of element.

Imagine mark-up that contains five unordered lists. If you wanted to style only the third ul, and didn’t have a unique id to hook into, you could use the nth-of-type(n) pseudo class. In the snippet above, only the third ul will have a border around it.

View Demo

Compatibility

  • IE9+
  • Firefox 3.5+
  • Chrome
  • Safari

25. X:nth-last-of-type(n)

  1. ul:nth-last-of-type(3) {
  2.    border: 1px solid black;
  3. }

And yes, to remain consistent, we can also use nth-last-of-type to begin at the end of the selectors list, and work our way back to target the desired element.

Compatibility

  • IE9+
  • Firefox 3.5+
  • Chrome
  • Safari
  • Opera

26. X:first-child

  1. ul li:first-child {
  2.    border-top: none;
  3. }

This structural pseudo class allows us to target only the first child of the element’s parent. You’ll often use this to remove borders from the first and last list items.

For example, let’s say you have a list of rows, and each one has a border-top and a border-bottom. Well, with that arrangement, the first and last item in that set will look a bit odd.

Many designers apply classes of first and last to compensate for this. Instead, you can use these pseudo classes.

View Demo

Compatibility

  • IE7+
  • Firefox
  • Chrome
  • Safari
  • Opera

27. X:last-child

  1. ul > li:last-child {
  2.    color: green;
  3. }

The opposite of first-child, last-child will target the last item of the element’s parent.

Example

Let’s build a simple example to demonstrate one possible use of these classes. We’ll create a styled list item.

Markup

  1. <ul>
  2.    <li> List Item </li>
  3.    <li> List Item </li>
  4.    <li> List Item </li>
  5. </ul>

Nothing special here; just a simple list.

CSS

  1. ul {
  2.  width: 200px;
  3.  background: #292929;
  4.  color: white;
  5.  list-style: none;
  6.  padding-left: 0;
  7. }
  8. li {
  9.  padding: 10px;
  10.  border-bottom: 1px solid black;
  11.  border-top: 1px solid #3c3c3c;
  12. }

This styling will set a background, remove the browser-default padding on the ul, and apply borders to each li to provide a bit of depth.

Styled List

To add depth to your lists, apply a border-bottom to each li that is a shade or two darker than the li‘s background color. Next, apply a border-top which is a couple shades lighter.

The only problem, as shown in the image above, is that a border will be applied to the very top and bottom of the unordered list – which looks odd. Let’s use the :first-child and :last-child pseudo classes to fix this.

  1. li:first-child {
  2.     border-top: none;
  3. }
  4. li:last-child {
  5.    border-bottom: none;
  6. }
Fixed

There we go; that fixes it!

View Demo

Compatibility

  • IE9+
  • Firefox
  • Chrome
  • Safari
  • Opera

Yep – IE8 supported :first-child, but not :last-child. Go figure.


28. X:only-child

  1. div p:only-child {
  2.    color: red;
  3. }

Truthfully, you probably won’t find yourself using the only-child pseudo class too often. Nonetheless, it’s available, should you need it.

It allows you to target elements which are the only child of its parent. For example, referencing the snippet above, only the paragraph that is the only child of the div will be colored, red.

Let’s assume the following markup.

  1. <div><p> My paragraph here. </p></div>
  2. <div>
  3.    <p> Two paragraphs total. </p>
  4.    <p> Two paragraphs total. </p>
  5. </div>

In this case, the second div‘s paragraphs will not be targeted; only the first div. As soon as you apply more than one child to an element, the only-child pseudo class ceases to take effect.

View Demo

Compatibility

  • IE9+
  • Firefox
  • Chrome
  • Safari
  • Opera

29. X:only-of-type

  1. li:only-of-type {
  2.    font-weight: bold;
  3. }

This structural pseudo class can be used in some clever ways. It will target elements that do not have any siblings within its parent container. As an example, let’s target all uls, which have only a single list item.

First, ask yourself how you would accomplish this task? You could do ul li, but, this would target all list items. The only solution is to use only-of-type.

  1. ul > li:only-of-type {
  2.    font-weight: bold;
  3. }
View Demo

Compatibility

  • IE9+
  • Firefox 3.5+
  • Chrome
  • Safari
  • Opera

30. X:first-of-type

The first-of-type pseudo class allows you to select the first siblings of its type.

A Test

To better understand this, let’s have a test. Copy the following mark-up into your code editor:

  1. <div>
  2.    <p> My paragraph here. </p>
  3.    <ul>
  4.       <li> List Item 1 </li>
  5.       <li> List Item 2 </li>
  6.    </ul>
  7.    <ul>
  8.       <li> List Item 3 </li>
  9.       <li> List Item 4 </li>
  10.    </ul>
  11. </div>

Now, without reading further, try to figure out how to target only “List Item 2”. When you’ve figured it out (or given up), read on.

Solution 1

There are a variety of ways to solve this test. We’ll review a handful of them. Let’s begin by using first-of-type.

  1. ul:first-of-type > li:nth-child(2) {
  2.    font-weight: bold;
  3. }

This snippet essentially says, “find the first unordered list on the page, then find only the immediate children, which are list items. Next, filter that down to only the second list item in that set.

Solution 2

Another option is to use the adjacent selector.

  1. p + ul li:last-child {
  2.    font-weight: bold;
  3. }

In this scenario, we find the ul that immediately proceeds the p tag, and then find the very last child of the element.

Solution 3

We can be as obnoxious or as playful as we want with these selectors.

  1. ul:first-of-type li:nth-last-child(1) {
  2.    font-weight: bold;
  3. }

This time, we grab the first ul on the page, and then find the very first list item, but starting from the bottom! 🙂

View Demo

Compatibility

  • IE9+
  • Firefox 3.5+
  • Chrome
  • Safari
  • Opera

Conclusion

If you’re compensating for older browsers, like Internet Explorer 6, you still need to be careful when using these newer selectors. But, please don’t let that deter you from learning these. You’d be doing a huge disservice to yourself. Be sure to refer here for a browser-compatibility list. Alternatively, you can use Dean Edward’s excellent IE9.js script to bring support for these selectors to older browsers.

Secondly, when working with JavaScript libraries, like the popular jQuery, always try to use these native CSS3 selectors over the library’s custom methods/selectors, when possible. It’ll make your code faster, as the selector engine can use the browser’s native parsing, rather than its own.

Thanks for reading, and I hope you picked up a trick or two!

200718 Sep Liquid faux columns with background-size

14 Feb

Until the Advanced Layout and Grid Layout modules are implemented, we have to get by with the existing tricks of the trade. One of those is the use of faux columns, a background image which simulates equal-height columns. This is a good technique, but the drawback is that it only works with fixed-width columns.

That problem was overcome with the advent of liquid faux columns, which uses some background-position trickery and a bit of maths to create a variable-width effect.

With the (tentative) introduction of background-size in Safari and Opera, however, faux columns are about to become a lot easier; all you need to do is create a background image and assign a percentage value to background-size, allowing the image to expand or contract with its containing box.

Take a look at this example (only tested in Safari 3 and Opera 9.5; may work in Konqueror 3.5.7 also). If you resize your browser window, the text and columns should maintain their proportions.

The way this is done is with a simple PNG image; I’ve made it 1000px wide, with two coloured columns of 250px each, so that it’s easier to calculate column widths (25%,50%,25%).

I’ve set this as the background-image on the html element, which has been assigned a width of 90%. Inside this there is a container div with a width of 100%, and my three columns with the widths set at the same ratio as the background image:

<div id="container">
	<div id="one">
	</div>
	<div id="two">
	</div>
	<div id="tre">
	</div>
</div>

#container {
position: relative;
width: 100%;
}
#one {
margin: 0 25%;
}
#two, #tre {
position: absolute;
top: 0;
width: 25%;
}
#two { left: 0; }
#tre { right: 0; }

The html element has the background-size declaration applied to it, with a percentage value to make it liquid, using the browser-specific prefixes followed by the proposed declaration (for safety):

html {
background-image: url('opera_bg.png');
-khtml-background-size: 100%;
-o-background-size: 100%;
-webkit-background-size: 90%;
background-size: 100%;
background-position: 50% 0;
background-repeat: repeat-y;
width: 90%;

You’ll notice that the Webkit value is different from the others; during this test, it seems that Webkit obtains its width from the entire browser window, not from the containing element; therefore, we have to set this value to be equal to the width of the containing element. I haven’t tested this thoroughly yet, so I’m not sure if this is a persistent bug or if there’s something I’m doing wrong. Anyway, Opera 9.5 behaves as expected.

After that I’ve added the background-position and background-repeat declarations; background-repeat to tile the image down the page, and background-position because Webkit seems to ignore the margin values and puts the image at top left of the browser window; this is only necessary if you’re centre-aligning your page.

Apart from a little tidying up, that’s it; once the module becomes a recommendation and the browser-specific prefixes are dropped, it will require only a few lines of code for the simple effect. In the meantime, remember that this is for experimentation purposes only and shouldn’t be used in a live environment. This is just a sketch of the technique at the moment, and requires more testing.

You can skip to the end and leave a response.

Rounded Corner Boxes the CSS3 Way

14 Feb

If you’ve been doing CSS for a while you’ll know that there are approximately 3,762 ways to create a rounded corner box. The simplest techniques rely on the addition of extra mark-up directly to your page, while the more complicated ones add the mark-up though DOM manipulation. While these techniques are all very interesting, they do seem somewhat of a kludge. The goal of CSS is to separate structure from presentation, yet here we are adding superfluous mark-up to our code in order to create a visual effect. The reason we are doing this is simple. CSS2.1 only allows a single background image per element.

Thankfully this looks set to change with the addition of multiple background images into the CSS3 specification. With CSS3 you’ll be able to add not one, not four, but eight background images to a single element. This means you’ll be able to create all kinds of interesting effects without the need of those additional elements.

While the CSS working group still seem to be arguing over the exact syntax, Dave Hyatt went ahead and implemented the currently suggested mechanism into Safari. The technique is fiendishly simple, and I think we’ll all be a lot better off once the W3C stop arguing over the details and allow browser vendors to get on and provide the tools we need to build better websites.

To create a CSS3 rounded corner box, simply start with your box element and apply your 4 corner images, separated by commas.

  1. .box {
  2. background-image: url(top-left.gif), url(top-right.gif), url(bottom-left.gif), url(bottom-right.gif);
  3. }
  4. Source: /code/rounded-corners-the-css3-way/multiple-backgrounds.txt

We don’t want these background images to repeat, which is the normal behaviour, so lets set all their background-repeat properties to no-repeat.

  1. .box {
  2. background-image: url(top-left.gif), url(top-right.gif), url(bottom-left.gif), url(bottom-right.gif);
  3. background-repeat: no-repeat, no-repeat, no-repeat, no-repeat;
  4. }
  5. Source: /code/rounded-corners-the-css3-way/no-repeat.txt

Lastly, we need to define the positioning of each corner image.

  1. .box {
  2. background-image: url(top-left.gif), url(top-right.gif), url(bottom-left.gif), url(bottom-right.gif);
  3. background-repeat: no-repeat, no-repeat, no-repeat, no-repeat;
  4. background-position: top left, top right, bottom left, bottom right;
  5. }
  6. Source: /code/rounded-corners-the-css3-way/position.txt

And there we have it, a simple rounded corner box with no additional mark-up.

As well as using multiple background images, CSS3 also has the ability to create rounded corners without the need of any images at all. You can do this by setting the border-radius property to your desired value as seen in the next example.

  1. .box {
  2. border-radius: 1.6em;
  3. }
  4. Source: /code/rounded-corners-the-css3-way/radius.txt

This technique currently works in Firefox/Camino and creates a nice, if somewhat jagged rounded corner. If you want to create a box that works in both Mozilla and WebKit based browsers, why not combine both techniques and see what happens.

%d bloggers like this: