The end of the fall semester was particularly disappointing, at least in regards to my second year students . While the usual factors were at play – lack of attention to detail (or lack of any kind of attention at all), tiredness, stress, and rushed, last-minute work – there was something else missing in the final project. I saw a lack of creativity that reflected not just those factors, but a general lack of confidence and fluency in CSS itself.
In response, I started the last winter semester in the completely opposite direction from normal, breaking out multicoloured poster boards and glitter pens and glue, and giving the students only one command: “design!”
Again, some of the results were disappointing (mostly because of lack of innate talent, or because they were terrified of (or unfamiliar with) holding a pen in their hand and being asked to draw), but less so than the efforts of the previous semester.
As part of the goal to inspire and free up their designs, I showed both classes draft pages of my portfolio website – which were inspired, in turn, by their own portfolio sites, and the entirely justified goading of the 1st years to “show us what you can do.” You can see a mockup of the basic design to the left: essentially, I wanted the large portfolio images to appear like Polaroids in a scrapbook. My goal in sharing this with the class was to emphasize that not everything in web design has to be at rigid right angles, or standard top-left navigation configuration, if the changes were logical, consistent, and warranted.
Of course, some of the students took this a little too literally, and started to design everything on their pages at an angle, but on the whole the experiment seems to have been a success. After SAIT’s reading week, my goal is to critique those designs, then turn them into PhotoShop work, and from there explore the CSS and markup necessary to turn them into full web sites.
In the meantime, I continued to work on my own portfolio site. It occurred to me very quickly that the technology behind the design was crude and inefficient. For each image, I was forced to go into PhotoShop, rotate the image, stroke the outside to place a border on it, generate a drop shadow, and place “Scotch tape” layers on the corners, before slicing and exporting it. Of course, PhotoShop actions could automate part of this process, but not all – I wanted the rotation to be essentially random, within a range of 4 degrees positive or negative. Naturally, in order to gain the full effect and preserve the background image in the body behind it, the portfolio image had to be exported as a 24-bit PNG, which ramped up file sizes dramatically.
Considering the problem, I knew I could generate the photo border easily enough with a CSS border property. I also knew that CSS3 supported box-shadow, albeit implemented slightly differently between Safari and Firefox, while the spec remains in draft. I wasn’t sure that drop-shadow would take into account the border (as it turns out, it did), but my first real problem was rotating the image in the browser.
A glance at a mention of “CSS transforms” and a little research revealed that CSS3 is also pushing towards scale, skew and rotational transforms of elements. Again, easy enough to implement as a fixed style:
- <img src="assets/images/milk-and-cookies.jpg"
- style="-moz-transform:rotate(5deg); -webkit-transform:rotate(5deg);" />
The visual quality of the rotation in the browser was not as good as doing the same routine in PhotoShop, but it was close enough – and the difference in file size (since I could now save just the portfolio image as a JPEG, without border, Scotch tape or drop-shadow) and workflow efficiency was huge.
But I wanted the rotation to be random, to avoid the website looking predictable and staid. Well, it was easy enough to generate a random number in JavaScript, in this case between -4 and 4:
- var obj = document.getElementById('biopic');
- // large image always has an id of "biopic"
- var min = -4; // maximum negative rotation of the picture
- var max = 4; // maximum positive rotation of the picture
- var randomRot = Math.floor(Math.random()*(max-min+1)+min);
- // provides a random number between -4 and 4.
The problem then became applying the transformation to the element via JavaScript, rather than CSS. I could have used a library like JQuery to speed things up, but I was determined to do it myself, in just a few lines of code, and this is what I found:
- var rotate = "rotate(" + randomRot + "deg)";
- // formats the rotate amount for the CSS
- obj.style.webkitTransform = rotate;
- // transform for Safari
- obj.style.MozTransform = rotate;
- // transform for Firefox
Success! I could now watch the portfolio image happily twist from side to side with each page refresh. Then, I had to put the Scotch tape in the corners. This proved to be the challenging part. There is talk of future CSS specs allowing element position based on calculation from another element, but that is still very much in draft, and not implemented in any browser that I’m aware of. Lacking that, I needed to find a whole bunch of information about the position of the large portfolio image - it’s height, width, left and right - via JavaScript.
This was made more complicated by the fact that I did not have the large image absolutely positioned: keeping with the tenets of fluid design, I wanted it relative to the list of smaller thumbnails beside it. Future design revisions could also see it nested inside elements, or below others. A little bit of web crawling brought me to this page, which provided a function, which under most (but not all) circumstances, would find the left and top of any element on a page. I also used getPropertyValue to gain the width and height. (And if you’re interested, the width, height, left and right of an object do not change just because an element is rotated – JavaScript draws its data from the original box of the object).
- var yPos = findPosY(obj);
- // finds the vertical position of the big picture
- var xPos = findPosX(obj);
- // finds the horizontal position of the big picture
- var height = parseInt(document.defaultView.getComputedStyle(obj,null).
- getPropertyValue("height")); // height of the big pic
- var width = parseInt(document.defaultView.getComputedStyle(obj,null).
- getPropertyValue("width")); // width of the big pic
With that known data – the top and left of an object, along with its width and height - I could quickly calculate the corners of the large image (pre-rotation), and absolutely position Scotch tape images in those locations (as a test, I used vector rectangles exported as PNGs from PhotoShop).
The result was great if the portfolio image only rotated a degree or so, but the Scotch tape was visibly out of place if the large image was rotated to its maximum extent. I knew the rotation amount, but the problem was that all transformations happen from the visual centre of an object by default. In other words, the Scotch tape images would rotate like a propeller if the same transformation was applied to them – I needed rotation around the centre of the large portfolio image.
After a silly moment of working out the trigonometry to achieve this, I realized that the wizards of CSS do allow for repositioning the transformation origin of an element anywhere. There are a bunch of keywords for positioning the origin inside the element, but I wanted it outside, in the center of the large image. I knew the width and height of the image, so finding its midpoint was easy:
- var bigoriginy = (height/2);
- var bigoriginx = (width/2);
- // gets the center of the pic horizontally and vertically
Then, I just needed to set the origin of the Scotch tape pieces appropriately and rotate them the same amount as the large image.
The script I had written thus far worked for my test cases of the top left and bottom right pieces of Scotch tape, but repeating lines of code for each transformation would be wasteful. Instead, I made an array based on the ids of the scotch tape pieces. Based on this, a logical naming scheme, and a search to find appropriate words in the id values of the elements, I then had the ability to apply the transformations I needed in a single for loop:
- var tape =
- new Array('top_left_corner_tape', 'top_right_corner_tape',
- 'bottom_left_corner_tape', 'bottom_right_corner_tape');
- for (var i = 0; i < tape.length; i++ ) {
- // do this to all the pieces of tape
- thistape = document.getElementById(tape[i]);
- if (tape[i].match("left")) {
- // if element ID has the word "left" in it,
- calculate left of tape as being close to left of the pic
- thistape.style.left = (xPos - 30)+"px";
- var originx = bigoriginx;
- // the x distance of the origin for pieces of tape on the left
- is the horizontal midpoint of the pic
- }
- if (tape[i].match("right")) {
- // if element ID has the word "right" in it, calculate left of tape
- as being close to right of the pic
- thistape.style.left = (xPos + width - 40)+"px";
- var originx = "-" + bigoriginx;
- // the x distance of the origin for pieces of tape on the right
- is the horizontal midpoint of thebiopicc
- }
- if (tape[i].match("top")) {
- // if element ID has the word "top" in it,
- calculate top of tape as being close to top of the pic
- thistape.style.top = (yPos - 40)+"px";
- var originy = bigoriginy;
- // the y distance of the origin for pieces of tape at the top
- is the vertical midpoint of thebiopicc
- }
- if (tape[i].match("bottom")) {
- // if element ID has the word "bottom" in it,
- calculate top of tape as being close to bottom of the pic
- thistape.style.top = (yPos + height - 20)+"px";
- var originy = "-" + bigoriginy;
- // the y distance of the origin for pieces of tape at the bottom
- is the vertical midpoint of the pic, signed negative
- }
- thistape.style.MozTransformOrigin =
- originx + "px " + originy + "px"; // origin format for Mozilla
- thistape.style.webkitTransformOrigin =
- originx + "px " + originy + "px"; // origin format for Webkit
- thistape.style.webkitTransform = rotate;
- // rotate the tape by the same amount as the pic, for Webkit
- thistape.style.MozTransform = rotate;
- // rotate the tape by the same amount as the pic, for Mozilla
- }
There are a few improvements I’d like to make: obviously, this only works for recent versions of Firefox and Safari.
Finally, CSS3 also adds the

Backgrounds are not always perfectly tiled repetitions of images. Sometimes they are single images, such as the background image we used in the fixed-width example in the last entry.
Haha, that is actually incredibly clever.
![Prometheus: Collector's Edition (Bilingual) [Blu-ray 3D + Blu-ray + DVD + Digital Copy] Prometheus: Collector's Edition (Bilingual) [Blu-ray 3D + Blu-ray + DVD + Digital Copy]](http://ecx.images-amazon.com/images/I/5192I1rtYnL._SL160_.jpg)

