cssClipHeader

I recently came across a post on one of the user forms that I visit frequently and notice a discussion on the use of the CSS clip function. Most everyone posted that they had either never used it or didn’t know about it. The comments ranged from why would you need to use the clip function to what is the clip function and how can it be used.

I personally had never used the clip function either but I started thinking about the options that it could allow for. I then started writing up a page that used the clip function for showing a smaller version of the file, ie. A thumbnail and when you rolled over it you would get a larger version. Now most of us have seen this done on sites before, the only difference being that most sites load in the new image via JavaScript or AJAX as most would call it.  Now there is nothing wrong with showing a larger version of the image by using AJAX but I thought it may be nice to only get one hit to the server by grabbing a slightly larger image and then using the clip function to only show a portion of the image until you roll over it.

On the first run I quickly noticed that this could give unfavorable images because you were just cropping in on the image. So for instance, lets say you had a picture of a person and you cropped in, you may end up w/ just a corner of their nose. Now I’m all for some abstract art but thats not exactly what we would be looking for.

That lead to a PHP function to get the image size and then divide it for a smaller height and width that we could place dynamically in the image tag thus removing the unsightly “corner of the nose” image.

Once I had everything written up I started thinking this would be even better if you could dynamically do this on a group of images and create a  photogallery. Once again, I wrote up a PHP function that would handle this as well.

I now had a way to use the clip function of a single image or on an entire folder of images. The following is a walk through of how this is accomplished.

Lets set the stage. We have a single image or a folder full of JPG files that we are wanting to shrink down and use the CSS crop function on. We’ll start out with a little bit of CSS that will define our clip states.

.clipContainer{
position:relative;
width:220px;
height:140px;
top:-18px;
left:-38px;
}
a.innerClip{
position:absolute;
clip:rect(18px 182px 115px 38px);
top:0px;
left:0px;
z-index:50 !important;
}

Lets take a look at the above code line by line.
The clipContainer is going to give our position and overall width and height. In other words a bounding box to help with placement.

clipContainer

The innerClip is what actually cuts the image off. Much like the overflow option but with control on placement. You will also notice that the format is much like margin or padding with top, right, bottom, left options but not in the fashion that we are used to using. The clip method can only be used on absolutely positioned elements an for those that use IE6 the clip function doesn’t work so we will address this later.

innerClip

Keep in mind that the starting point for your positioning always starts from the Top Left corder or 0,0. So if you had the top at 0 and the right at auto you would end up with the full width of the containerClip.

clipProperties

a:hover.innerClip{
position:absolute;
clip:rect(auto, auto, auto, auto);
top:18px;
left:38px;
z-index:100 !important;
}

We wrapped the image in an anchor tag so we can utilize the hover tag. The purpose of this is to actually show the entire image upon rollover.

I coded this up using a UL but you could use any block element you would like. I find it easier to read through a list of li tags and control the placement via CSS.

img{
border:none;
outline:none;
}

ul.imgGallery{
list-style:none;
list-style-type:none;
width:500px;
}
ul.imgGallery li{
float:left;
margin:10px;
}

So in the above code we have told all IMG tags to remove the border and outline which would have been added due to the image being wrapped in an anchor tag. We next set up the master UL container and remove the list style and add our max width. The LI tags are given a FLOAT option and PADDING to keep them from bumping into each other.

This shows how the UL will be rendered out.

hoverOFF

We can now see what would happen if you were to hover your mouse over one of the images. Without having to load any other external data you would see the full unclipped image that we reduced in size.

hoverON

Now that we have gone over the CSS portion I know your wondering how can I use this to build out a full page. Well, that portion is all handled via PHP.  We first need to start out with our main function that will search for our images.

The first thing we need to do is define a few variables. These include where we will be looking for our images, the first image to start with and what type of image we will be looking for. I have chosen to look in the current folder but this of course could be changed to any folder in your directory tree.

$dir = ‘./’;
$curImg = 1;
$imgCount = count(glob(“$dir/*.jpg”));

We then need to loop through each image found and preform the rest of our function. This is accomplished with a WHILE loop like so:

while($curImg <= $imgCount){
$newImg = “$curImg.jpg”;
getReduced($newImg,$single = “no”);
$curImg ++;
}

As you can see we are comparing the number of images found ($imgCount) with the current image that is being worked on ($curImg). We then make a call to a function that will reduce the image size. We will also increment the current image by 1 each time this loop runs until we reach the total number of images that we found.

If you noticed, we made a call to another function called getReduced() in this snippet of code. We also passed 2 variables along with it.
1.The name of the image to work on.
2.Is this a single image or multiple images.

Now, the file naming is important for this to work as we are just incrementing through a set number. We start with 1 and count up for each file found. Seems simple enough, but what happens if you remove image 5.jpg? We would end up with an error being printed out to the screen because the file that was named 5.jpg could not be found. So to keep this from happening we need to check to make sure the file actually exists. We accomplish this with the following code. If the image is found we can then check the current size of the image that was sent to this function ($newImg) and assign those values to a new variable called $img. We then divide and round off our width and height and assign them to their respected variable.

if (!file_exists($newImg)) {
echo “”;
}
else {
$img = getimagesize($newImg);
// reduce the width and height of each image
$reducedWidth = round($img[0]/1.4);
$reducedHeight = round($img[1]/1.4);
}

We now have a new smaller width and height that has kept the correct aspect ratio so we can write out the the HTML that will be used on the page.

Before we do that remember that we sent 2 variables to this function. The first was the image name and the second was to decide if we were dealing with one file or multiple files. So we need to check to see what we are suppose to work with.

If we have only one image then this statement is true and we write this information out for the browser.

// if we are running on a sigle image at a time.
if($single == “yes”){
$printImg = <<<EOL
<div>
<a href=”#”>
<img src=”$newImg” width=”$reducedWidth” height=”$reducedHeight” />
</a>
</div>
EOL;
}

If we have multiple files then this statement would be used.

// if we are running a batch process on multiple files
else{
$printImg = <<<EOL
<li>
<div>
<a href=”#”>
<img src=”$newImg” width=”$reducedWidth” height=”$reducedHeight” />
</a>
</div>
</li>
EOL;
}
print $printImg;
}

As you may have noticed, the only difference between the two statement are the LI tags. As I mentioned earlier I find it easier to put multiple images inside of an LI tag and then use CSS as shown above to control the placement of those elements.

How do I use this stuff?
Well, thats even easier then reading this tutorial.

To use this for a single image, just place the following in your document:

<?php
getReduced($newImg = “1.jpg”,$single = “yes”);
?>

As you can see, we are making a call to the getReduced() function and passing 2 variables along with it. The first if the image name and the second is to let the function know that we only want to process one image.

If you want to process multiple images, just use the following:

<ul>
<?php getNextImg(); ?>
</ul>

We wrapped the function in a UL element and the rest is handled by the code we just went over.

If you remembered, the clip doesn’t work in IE6 so to fix that we just add in a new CSS file that is IE6 only like this.

<!–[if IE 6]>
<link href=”ie.css” type=”text/css” rel=”stylesheet” />
<![endif]–>

This file will contain a different approach by using divs.
.clipContainer{
position:relative;
width:220px;
height:140px;
top:0px;
left:0px;
}
a.innerClip{
position:absolute;
top:0px;
left:0px;
width:144px;
height:99px;
display:block;
overflow:hidden;
z-index:50 !important;
}
a:hover.innerClip{
position:absolute;
top:0px;
left:0px;
width:auto;
height:auto;
display:block;
overflow:visible;
z-index:200 !important;
}

As you can see, we changed the positioning and removed the clip function all together. We replaced it with the overflow feature. While this will give use the same result, we can’t control what part of the image is viewable with this feature. We will get what ever shows up in the .innerClip starting at the top left corner.

For the full code click here.
To check out a demo, click here.

@ 3:27 pm

2 Comments »

  1. I like your site! This is my page

    Comment by loraImpargo — April 27, 2010 @ 8:02 am

  2. Hi, I’m very interested in Linux but Im a Super Newbie and I’m having trouble deciding on the right distribution for me (Havent you heard this a million times?) anyway here is my problem, I need a distribution that can switch between reading and writing in English and Japanese (Japanese Language Support) with out restarting the operating system.

    Comment by Emily N. — June 9, 2010 @ 12:31 am

RSS feed for comments on this post. TrackBack URL

Leave a comment