Dec 27 2009

css techniques: text wrap around image

The challenge: I had designed a printed page layout with a different visual element on each page to help to break up rather long narrative. The client wanted this to be a template for her website, including the text-wrapped image. Below is a (different) page mock-up using a similar visual element in the lower left corner:

To make the page look similar to the printed version, the text to had to wrap around the image, not just squarely around an image with float:left styling. However, this is not as easy as it seems. I was familiar with the “sandbox’ technique, in which a series of sandbox DIVs is defined that block out the image so that the text can flow around them. This is cumbersome and a little time-consuming. However I stumbled upon a relatively simple technique that takes advantage of the <canvas> element.

By way of explanation, the <canvas> element “creates a fixed size drawing surface that exposes one or more ‘rendering contexts’, which are used to create and manipulate the content shown.” The term “rendering context” merely refers to either a 2D or (sometime in the future) a 3D image. To “draw” something, the <canvas> element is called by a script. In this case, Jacob Seidelin has developed a script, known as prettyfloat.js (download here).

Using this small script you simply give your image a CSS class of either “sandbag-left” or “sandbag-right”, depending on how your image should float. If the browser does not support <canvas> and image data access, a fallback mechanism simply sets the CSS float property to “left” or “right”, degrading to the old rectangular text wrap.

First, save the script with your project files (in this example to the same directory as the HTML file).

The image needs to be either .png or .gif to work properly, meaning it must have transparent pixels in which the text block will flow up next to the opaque pixels. To achieve this, the open the image in Photoshop, then:

  1. Open the Layers panel
  2. Double click on the Background layer to unlock it and make it available to transparency. This will now be labeled Layer 0.
  3. Create a new layer (Layer > New > Layer…) This will be a temporary layer on which you will draw a guide.
  4. Using the Polygonal Lassso tool, draw the guide leaving enough margin for the text:
  5. Using the Magic Wand tool, select the area to be made transparent
  6. IMPORTANT: Click on Layer 0 to make it the active layer
  7. Using the arrow keys on the keyboard, nudge the selected area 1 px to the right and 1 px up so there is no chance of a border of pixels along the straight edges
  8. Press the [delete] (or [Backspace]) key to erase the pixels:
  9. Save for Web & Devices using the PNG-24 preset

Now for the code:

In the <head> section of the HTML file, call the prettyfloat.js script:

<script src=”prettyfloat.js” type=”text/javascript”></script>

(Change the URL if you store your scripts in a separate directory)

The <body> section with just the wrapped text segment of the page is as follows:

<body>
<div class=”container”>
<div style=”position:relative; width:550px; height:450px;”> <img class=”sandbag-left” src=”flowers.png”>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi commodo, ipsum sed pharetra gravida, orci magna rhoncus neque, id pulvinar odio lorem non turpis. Nullam sit amet enim. Suspendisse id velit vitae ligula volutpat condimentum. Aliquam erat volutpat. Sed quis velit. Nulla facilisi. Nulla libero. Vivamus pharetra posuere sapien. Nam consectetuer. Sed aliquam, nunc eget euismod ullamcorper, lectus nunc ullamcorper orci, fermentum bibendum enim nibh eget ipsum. Donec porttitor ligula eu dolor. Maecenas vitae nulla consequat libero cursus venenatis. Nam magna enim, accumsan eu, blandit sed, blandit a, eros.</p>
<p>Quisque facilisis erat a dui. Nam malesuada ornare dolor. Cras gravida, diam sit amet rhoncus ornare, erat elit consectetuer erat, id egestas pede nibh eget odio. Proin tincidunt, velit vel porta elementum, magna diam molestie sapien, non aliquet massa pede eu diam. Aliquam iaculis. Fusce et ipsum et nulla tristique facilisis. Donec eget sem sit amet ligula viverra gravida.</p>
</div>
</div>
</body>

A test of how this renders in different browsers (using Adobe BrowserLab–more about that later) reveals that Firefox 2.0 on Mac OS X looks as intentded:

Chrome on Windows XP renders properly:

However, as expected, IE7 on Windows XP does not, though the results are acceptable (sort of):

Most newer browsers now support the <canvas> element so this is really is a relatively painless way to achieve a layout that has the look of a printed page.


Nov 6 2009

css techniques: resizable background behind static foreground object

The last CSS Technique got me thinking about ways to keep a foreground object static as the background is resized horizontally. Again, a picture is worth 1,000 words so view the example. Be sure to resize the browser window horizontally to see the effect.

I used this for a header, which is maybe where it‘s application makes the most sense, though it is essentially just one DIV nested inside another DIV. It could be used when a horizontal navigation bar is to remain in place in front of a resizable header image; or for static text that likewise will remain in place; or both (multiple DIVs nested inside a header DIV).

Since this isn‘t intended to be instructional for Photoshop, this post is much shorter than the last one. All that you need to achieve the effect is a background image, a foreground image (or text), the HTML file and the CSS file. Some knowledge of HTML and CSS is assumed and FTP access to a server is needed.

I‘ve provided the files used in the example, which you can download along with a PDF version of these instructions.
You will need to set up a folder for this project. In it, create another folder named images.

  1. Create a header image. It should be narrower than the width of a browser window. The best effect is achieved when it contains (or appears to fade into) a solid background color to the right as the window size and (and the image) are pulled to the right. Take note of the height dimension and the hexidecimal code for the background color. They will be used in the CSS coding.

In this example (mantleObjects.jpg), I used an image that is 200 px high and contains the solid background color #C2C2C2.

  1. Save for Web & Devices optimized as appropriate for the image. Save the file in the in the images folder of your project folder.
  2. Create the static foreground image or text. The height should be less than the height of the background and the Background Contents must be transparent.
  3. Save for Web & Devices in .gif or .png file format in the images folder.

The example foreground image is fallenAngel.png.

Now for the coding:

  1. Create another new blank file for the CSS (or open a new CSS file in Dreamweaver) and save this file as style.css in your project folder.

To link the CSS file to the HTML file, add the following to the <head> section of index.html:

<link href="style.css" rel="stylesheet" type="text/css" />
Inside the <body> there will be 2 DIVs (in this example, though more may be added, as explained above).
<div class="background">
<div class="flyover"></div>
</div>

Note that the first DIV (shown in bold) wraps the second DIV.

That’s all we need for the HTML.

Open style.css.

  1. Start by styling the class: background (note: these could both be IDs instead of classes).
    1. Set the background to the color that was established from step 1.
    2. The background url will point to the header image that was created in step 1.
    3. The image will not repeat.
    4. The vertical background position can be set. In this case, I set it to top.
    5. Height should match the image.
    6. Width is set to 100%.
    7. Position is important. To work correctly, the position is set to relative.

The styling for this class:

.background {
background: #2C2C2C url(images/mantleObjects.jpg) no-repeat top;
height: 200px;
width: 100%;
position: relative;
}

Using the image files provided, when you upload and test the file, it should look like this:

As you resize the browser window the image will appear to stretch across the screen.

  1. Next, style the flyover class:
    1. The background url will point to the foreground image created in step 3.
    2. It will not repeat.
    3. Set the width and the height to match the dimensions of the image.
    4. The position is important and is set to absolute.
    5. Establish how far from the left edge and how far down from the top the image is to appear.
    6. Finally, to ensure that it is always on top, give it a z-index of 1000.

The styling for the flyover class:

.flyover {
background: url(images/fallenAngel.png) no-repeat;
height: 200px;
width: 200px;
position: absolute;
left: 600px;
top: 0px;
z-index: 1000;
}

Upload and test the file again. You should see something like this if you positioned the foreground object at 600 px from the left and 0 px from the top. As you make the browser window wider, the image will remain fixed, buy appear to float on top of the objects in the background.

Below is the same background image and a 600 px x 50 px text image used in the flyover class. As you resize the screen, the position of the text remains fixed.


Nov 4 2009

css technique: scrolling gradient over a fixed background

This is a little hard to describe, so view the example and be sure to scroll to the bottom of the page. The background is a gradient that fades into a simple graphic. As you scroll down the page, the graphic stays in the same fixed position at the bottom of your browser window, but the gradient reverses. As you approach the end of the page, the graphic changes colors, or reveals objects that were previously unseen.

I can‘t remember where I saw an explanation of the technique, but if I do I will provide credit. I thought it had many possibilities beyond the simple example that was shown, but with deadlines looming I had to store it away for another day. Finally, today I had some time to kill and I decided to see if I could reproduce the effect.

There are 3 images: 2 gradient blends and 1 graphic. The graphic consists of (at least) an area that is visible when viewed in the lightest color of the blend and another area that is the same color, and therefore invisible, in the lightest blend color. This area becomes visible in the darker blend colors.

I‘ve provided the files for the images, the basic HTML file and the CSS file which you can download.

The instructions below are detailed enough that Photoshop newbies can follow along.

The coding is reasonably simple, though some knowledge of HTML and CSS is assumed and FTP access to a server is needed.

If needed, you can download these instructions as a PDF.

You will need to set up a folder for this project. In it, create another folder named images.

In Photoshop, start with the blends:

  1. Create a new document that is 10 px wide and 500 px tall.

  2. Select a foreground color and a background color that will be the endpoints of the gradient. While in the Color Picker, remember the hexidecimal codes for the lighter color so that it can be referenced in the CSS.

    In the example, I used #333333 for the foreground color and #d6d6d6 for the background color.

  3. Create a gradient blend starting with the darkest color at the top. If you are unfamiliar with the process of creating gradients, follow the sequence in the illustration to the right.
    1. Select a foreground color and a background color that will be the endpoints of the gradient.
    2. Choose the Gradient tool.
    3. The gradient option should default to your selected foreground and background colors. If not, click the dropdown arrow and select the correct gradient from the choices.
    4. Click at the top of your image and drag to the bottom. When you release, the gradient will be drawn. Repeat if you need to adjust.
  4. Save this gradient as a medium quality JPG using Save for Web & Devices… (under the File menu).
    I used the filename bkg_33tod6.jpg with shorthand for the hex colors as a reminder and saved the file to the images folder.
  5. Flip the image vertically (Image > Image Rotation > Flip Canvas Vertical).
  6. Save the reversed gradient as above.
    I used bkg_d6to33.jpg as the filename.

Now create the graphic:

  1. For an effective, simple example, create a new image that is about 200 px tall by 300 px wide with the Background Contents set to Transparent (refer to the first figure, above).

The exact dimensions would be influenced by the width of the main content area. The narrower the area, the graphic can be more complex, though it will repeat horizontally across the bottom window. A seamless transition is therefore important.

  1. Use the same foreground and background colors that you selected for the gradient. Select All (Select > Select All) and fill with the background color (Edit > Fill and Use: Foreground Color).
  2. Create a new layer (Layer > New > Layer…) Select All and fill with the foreground color.
  3. Create another new layer and place it at the top of the layer stack. Make sure the layer with darkest color is not visible by clicking on the visibility icon (eyeball) in the layers panel or by placing it at the bottom of the layer stack. Paint or draw a graphic image using the foreground drawing color.

This color will be invisible when at the bottom of the page. Colors that are lighter will still be faintly visible. In this example, only 2 colors were used. The reflection of the trees in the water will be visible at the bottom of the page while the trees will fade away.

  1. Create another new layer and place it on top of the layer stack. Make the layer with the darkest color visible and the other 2 layers invisible.
  2. Exchange the foreground and background colors (press the ‘x‘ key).
  3. Draw or paint the object that you want to be visible at the bottom of the page.

The trick is to avoid the dark colored areas in the layer below. To do this, CMD-click (or CNTL-click) on the Layer Thumbnail layer below to cause the filled area to be selected.

  1. Then, click on the layer above to make it the active layer and begin to draw or paint using the lighter drawing color. This area will be invisible until the bottom of the scroll is reached.

In the example, I drew stars in the sky, selected the sky region and copied and pasted it (to a new layer), flipped the layer vertically (Edit > Transform > Flip Vertical) and moved it into position as a reflection of the stars in the water.

  1. When the graphic is done, make the dark fill layer (at the bottom of the layer stack) invisible and Save for Web & Devices. Since the background needs to be transparent, choose the present for PNG-24. In this example, I named the file river_frieze.png.

Now you are ready to start coding…

  1. In your favorite text editor create a new file and copy the following basic HTML structure and paste it into your file (or in Dreamweaver, open a new HTML file):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>example: scrolling gradient over a fixed background</title>
</head>
<body>
</body>
</html>

  1. Save this file as test.html in your project folder.
  2. Create another new blank file for the CSS (or open a new CSS file in Dreamweaver) and save this file as style.css in your project folder.
  3. To link the CSS file to the HTML file, add the following to the <head> section of index.html:

<link href="style.css" rel="stylesheet" type="text/css" />

  1. The <body> will be styled to hold the background color. Also, there are 4 structural components, or DIVs to this page in the following heirarchy:

A container for the background gradient at the bottom of the page
A container for the graphic image
A container for the main content of your page
The main content of your page

  1. Inside the <body> set up the 4 DIVs:

<div id="background">
<div id="graphic">
<div id="mainContainer">
<div id="mainContent">
</div>
</div>
</div>
</div>

That‘s all that is needed for the HTML side. The rest is handled by CSS. Save index.html.

Open style.css

  1. For this example, the mainContainer ID, or the content of your page is 640 px wide (width: 640px; )
  2. It has a white background (background: #FFFFFF;)
  3. It is centered in the window (margin: 0 auto; )
  4. It also has a solid, black border around all 4 sides (border: 1px solid #000000; )
  5. And, because we want to see the effect after scrolling through a long page of content, the height is 2000 px (min-height: 2000px; )

The styling for this ID is:

#mainContainer {
width: 640px;
background: #FFFFFF;
margin: 0 auto;
border: 1px solid #000000;
min-height: 2000px;
}

If you upload your files and test in your browser, the page should look like this:

A white rectangular area centered in the window. The scroll bar indicates that this is a long page.

  1. Next, style the body with the lightest color as the background (background: #d6d6d6; )
  2. The dark-to-light gradient (bkg_33tod6.jpg) will also appear in the background at the top of the window so add the url (background: #d6d6d6 url(images/bkg_33tod6.jpg); )
  3. The gradient will repeat horizontally across the width of the window (background: #d6d6d6 url(images/bkg_33tod6.jpg) repeat-x; )
  4. Since we want the background to extend to the edges of the window, the margins will be 0 px on all sides (margin: 0; )

The styling for the body:

body {
background: #d6d6d6 url(images/bkg_33tod6.jpg) repeat-x;
margin: 0;
}

Now if you upload and refresh, the window should look like this:

As you scroll down, the gradient disappears, leaving the solid background color.

  1. The background ID will only hold the light-to-dark gradient that will be anchored to the bottom and extend across the window:

    #background {
    background: url(images/bkg_d6to33.jpg) repeat-x left bottom;
    }

Now if you upload and refresh and scroll to the bottom of the page, the window should look like this:

  1. Finally, add the .png image as a background image to the graphic ID and repeat image across the window (background: url(images/river_frieze.png) repeat-x; )
  2. To hold the graphic in position at the bottom of the window, the background-attachment style must be fixed and the background-position (Y) is set to bottom.
  3. There must be a slight offset to the left (for some reason), so the background-position (X) is set to -10 px.

The styling for this ID is:

#graphic {
background: url(images/river_frieze.png) repeat-x fixed -10px bottom;
}

If you upload and refresh, the graphic should appear at the bottom of the window:

And as you scroll to the bottom of the page, the reflection in the water disappears and the stars come out.