Friends

Monday, November 7, 2011

From PSD to CSS/HTML in Easy Steps – Part 3

Thanks for staying with us and here we now have part 3 of 4 in our series of how to turn a psd to css/html. In part 1 and part 2 of this article we created some of the major elements that we will need in order to hold our content. This article will deal with the more difficult left column and all the content within it, as well as sorting out the. Files
Some people have pointed out that the files are missing for the original tutorials. So you can download the original PSD at the following location
PSD files
Note: its a zip file that requires downloading, so right click the above link.
As mentioned in the first article the psd, files etc are all licensed under the Creative commons licence.

psd - css tutorial continued

The current state of play can be seen in the image below and at the following location.
Figure 14
Figure 14
If we compare this to the original PSD shown in figure 15 below you can see that we still have some work to do.
Figure 15
PSD to slice
The elements we will tackle in this and the following article can be listed as follows.
1) Position the watermark image at the base of the left and right columns
2) Add the search form on top of the big image in the header section.
3) Add content to the three columns along with the associated graphical icons
4) Add the copyright message to the footer.
Most of the above is just basic CSS and the only two main problem areas that I envisage causing trouble are the watermark images that sit at the base of the left and right columns and the graphical form elements. We will of course work through the rest of the content step by step but that shouldn't cause us any problems.

Watermark

For the first task we will try and place the following image at the base of the outer columns.

Figure 16


There are a number of problems to overcome and it is good to list them so that we have an idea of what needs to be achieved.
In no particular order we must :
1) Place the image at the bottom of the column so that it always sits at the bottom no matter how long the column is.
2) Ensure the image is in the background and under the text content
3) Ensure the image is on top of the existing background fade and matches seamlessly
To accomplish Number 1 above requires a little bit of lateral thought because the columns actually have no height in reality as they are created by background images on the parent container. Therefore we will follow the example we set in part 1 of the article and we will position the watermark from an element that is below the columns which is our footer element. As the footer already has a background image in place we can't use another background image on the same element. Therefore I am going to place the images absolutely from the footer and place them with a negative top position to bring them into place.
For number 2 above we will need to ensure that each of our elements has the appropriate z-index level set so that we can control the level of the initial background, the absolutely placed watermark image and the text content. That means there are 3 levels to consider in this process. In order for z-index to take effect we must make sure that non positioned elements have position:relative applied to create a local stacking context and also allow us to place the absolute elements with respect to the current context and not the viewport.
Number 3 is a little more involved and I am not sure what is going to work here and will have to use trial and error and see what the end result looks like. As I am constructing this layout in real time (so to speak) I am allowing myself the option to change my mind later if the approach taken doesn't work out very well. I have two methods in mind and the first method is to create a transparent gif with a transparent background. The background will be green to match the current background color but will be set as the transparent color so that it hopefully hides the ragged images in our index transparent gif. If this method fails (doesn't look good) then I may need to use a transparent PNG and use the alpha image loader filter for IE as already mentioned in earlier in this article.
Tackling Number 3 first I have created this image for the left column and this image for the right column by slicing the appropriate elements from the PSD.
To position the image (numbers 1 and 2) the footer first needs to have position:relative added to create a stacking context and also to allow us to be able to set a suitable z-index. To ensure the image stays on top of the content above we will give the content above a z-index of 1 and give the footer a z-index of 2. Then we can give the actual floated columns a z-index of 3 to keep the text above the watermark image. We do not have any background images or background colors on the floated columns themselves so there is nothing to worry about there.
The CSS needed is as follows:
CSS:
  1. /* main content */
  2.     #main,#content{width:975px}
  3.     #main{
  4.     background:url(images/3col-bg.jpg) repeat-y 0 0;
  5.     position:relative;
  6.     z-index:1;
  7.     }
  8.     #content{
  9.     background:url(images/3col-top.png) no-repeat 0 0;
  10.     min-height:270px;
  11.     }
  12.     * html #content {height:270px}/* for ie6 and under*/
  13.     #col1{
  14.     width:207px;
  15.     margin:0 28px 0 18px;
  16.     display:inline;/* cure IE6 double margin bug*/
  17.     float:left;
  18.     position:relative;
  19.     z-index:3;
  20.     }
  21.     #maincol{
  22.     width:444px;
  23.     margin:0 48px 0 0;
  24.     float:left;
  25.     position:relative;
  26.     z-index:3;
  27.     }
  28.     #col2{
  29.     width:180px;
  30.     float:left;
  31.     margin:0 50px 0 0;
  32.     display:inline;/* cure IE6 double margin bug*/
  33.     position:relative;
  34.     z-index:3;
  35.     }
  36. /* footer and copyright */
  37.     #footer{
  38.     width:975px;
  39.     padding:20px 0 0 0;
  40.     background:url(images/3col-base.jpg) no-repeat 0 0;
  41.     clear:both;
  42.     position:relative;
  43.     z-index:2;
  44.     }
  45.     .watermark{
  46.     background:url(images2/flame2.gif) no-repeat 0 0;
  47.     position:absolute;
  48.     width:186px;
  49.     height:209px;
  50.     clear:both
  51.     }
  52.     .w1{left:45px;top:-189px}
  53.     .w2{
  54.     right:45px;
  55.     top:-170px;
  56.     height:176px;
  57.     background:url(images2/flame3.gif) no-repeat 0 0;
  58.     }
The extra CSS has been merged into the existing stylesheet as shown above. The only things to note are that I have used a class called "watermark" which defines a few consistent properties for the elements and then I used classes of "w1" and "w2" to provide the positional differences. This saves about 4 lines of code but is worth doing because anything that reduces code weight is good as long as readability and usability doesn't suffer. The classes are applied together using a space to separate them.
e.g. class="watermark w1"
You can use as many classes as you want in this manner as long as you separate them by a space and they will follow the normal rules of the cascade in that the later styles of same weight and origin will win out.
There are no spare elements to use for the watermarks so I am going to use two empty divs and then absolutely place the divs into position. I don't like using empty elements but sometimes there isn't a choice and I just have to grin and bear it.
The html is as follows:
HTML:
  1. <div id="footer">
  2. <div class="watermark w1"></div>
  3. <div class="watermark w2"></div>
  4. </div>
The result as seen in Firefox is shown in Figure 17.

Figure 17

Watermark
Although the images look really jaggy when viewed individually and out of context we can see that once they are placed on the background then the edges are softened and merge in with the background. Bearing in mind that most of the time there will be text content overlapping these images I'm happy to accept this level of quality. If you wanted much sharper images then you would need to use PNG images with the aforementioned hacks for IE6 and under.
The live example can be seen here for you to examine and compare.
For those of you using IE6 and under you will notice that we have a problem!
The bottom of the layout (which was previously fine) has all gone awry as seen in figure 18 and is in desperate need of help.

Figure 18

IE6 Problem
We seem to have lost the bottom part of the layout and we need to bug hunt and find out what caused IE6 to misplace this section.
The easiest way to see what's causing the problem is to retrace our footsteps and remove one element at a time until we find the trigger for this behaviour. This is why you must check your work at each stage in various browsers or you could build a whole page on this broken issue.
The first step in my bug hunt is to remove the two watermark divs from the HTML as this is the most likely culprit. Removing the 2 divs and checking again in IE shows that everything is now back to normal. Now that we know what the problem is we need to find away of doing what we want without breaking IE6. Is there a specific style that triggers the effect. To test this out we need to put back the HTML for the watermark divs and then selectively delete styles that apply to them and see if we can trigger a response. It soon becomes apparent that we can delete all the styles that refer to the watermark without finding an actual trigger for the effect.
This leads to the conclusion that the problem must be the HTML that we added. We already know that removing the HTML will set the layout back to its correct position. Fortunately I have seen this bug before and know what the solution is. IE6 doesn't like the fact that we have placed empty divs in the footer especially with all the styles currently applied to it. The solution is easy and we simply need to ensure that we have some real content in the footer and our image will return. If we add a line of text that will eventually be the copyright message we see everything jumps back to normal.
HTML:
  1. <p>This is a copyright message</p>
  2. <div class="watermark w1"></div>
  3. <div class="watermark w2"></div>
  4. </div>
IE6 now shows everything correctly and we can continue with our testing by adding content to the three columns and check that our layering is in fact correct and everything overlaps as it should. Grabbing the text content form the PSD and inserting it into the HTML (unstyled for now and unformatted) we can then test our layout so far.
Unfortunately, we must have done something wrong because our layout has overlapped incorrectly as can be seen in this live example and in the screenshot below.

Figure 19.

Incorrect z-index
We have incorrectly addressed the z-index layering of our elements and the watermark is now on top of our text content which is not a good thing.
Referring back to our original plan we set our content (#main) to have a z-index of 1 and the footer a z-index of 2 and then we gave the columns a z-index of 3. Although this may sound logical it is in fact flawed because the columns are contained within #main which only has a z-index of 1. Ultimately it is the parents z-index that determines the stacking level of all its children in relation to other elements outside our current stacking context. We could have given the columns a z-index of 100000 but it would be to no avail because #main is z-index:1 and the footer is z-index:2 and is outside of #main. Therefore the footer will always be on top of #main and any of its children no matter what their z-index may be.
One solution to this problem is to remove the z-index from #main and to bring all the children under the same roof and to have the same parent (#outer). This means that the children's z-index will be honored amongst each other and this does indeed fix the issue in most browsers as shown in the Firefox screenshot below.

Figure 20

z-index removed
Unfortunately, and once again, we have problems in IE all the way from IE7 backwards. The watermark still overlaps the text even though we have removed the z-index from #main. The problem is that IE incorrectly assigns a z-index of zero when an element is positioned instead of applying a value of "auto" as defined in the CSS specifications. This means that IE will always create a local stacking context for its children and causes the problems we are experiencing. In order to combat this behaviour we also need to remove the position:relative from #main so that a local stacking context isn't created and once again all children can live under the same roof.
Removing the position:relative from #main fixes IE and we now get the result seen in figure 20 above. The only downside is that this prohibits us from placing any absolute elements in relation to #main if we ever needed to in the future. However, for the time being we don't need to do this so we will call this a solution for now and end up with this final code which you should compare to yours if you are working along with me. Ignore for the moment the content that we pasted from Photoshop as the html needs to be tidied up and applied semantically so we will be changing it all shortly.

Column 1

Now that we have sorted the watermark and the layering issues we will turn our attention to the more mundane tasks of styling the content in the columns. We already have some dummy html in place but now we need to format it and style it correctly. As a refresher see Figure 21 for the result we want to achieve.

Figure 21

left column layout
The issues to overcome in this section are as follows.
1) Create the heading at the appropriate level and in the closest font to match the PSD (or perhaps use an image if we can't get close).
2) Slice the graphical components from the PSD. (i.e. The various icons, the faded underline, the photo of the month image) .
3) Position the elements with the correct spacing and margins to match the design.
The only slightly complicated task above will be placing the page icon that goes before the lorem ipsum text. We could use a background image for this at the start of the line but we would need to ensure the line was high enough to show the image and that content doesn't wrap over the image. Although we could do this with padding it would mean that all lines will be as high as the image which probably isn't a good idea.
A second approach would be to float the image into place in the background of an element of appropriate dimensions and this would allow the text to wrap quite nicely. All that would be needed would be to insert a span and apply the appropriate styles to it. The only downside is that all the dimensions would need to be specified and addressed correctly in order for the image to sit correctly.
A third (and my preferred) approach is simply to use an image in the html. Nine times out of ten when a designer sticks an icon in the page like the one above they also want that icon to be a link to more content. It is so much easier to use an image in the HTML as it does not incur additional code overheads or extra mark-up in order to place it correctly. As long as the image is "inline" by default we can control its vertical alignment and it can easily be turned into a link if required all without setting dimensions or much CSS at all. It also aids accessibility in that the image alt attributes are available to all unlike a background image. Therefore we will take this approach and see how it all pans out.

Headings

Let's tackle the headings first.
The first thing to note is that the designer has again used a non standard font and we need to get the closest match we can or use an image combined with image replacement techniques (or SIFR if you are into flash based alternatives). I am going to try to use Arial text in the same way that I did for the navigation because it looks quite similar to me. It is so much better to have text headings in the HTML as it is better for all and of course so much easier to work with. However if it doesn't look good then it's another matter and you will need to discuss with your client what options to take.
The results look good enough for me but I know they won't be good enough for some and this is a decision only you can make.
I am going to use Arial in an H3 heading as I think that will be the correct level for this column. It seems that this style is consistent so I will style the h3 directly without the need for a class. I also notice that column1 (#col1) is slightly misplaced so I will line it up by changing the margins a bit. The revised CSS is as follows:
CSS:
  1. #col1{
  2. width:207px;
  3. margin:0 21px 0 25px;
  4. display:inline;/* cure IE6 double margin bug*/
  5. float:left;
  6. position:relative;
  7. z-index:3;
  8. }
The extra style for the H3 element also follows:
CSS:
  1. h3{
  2. color:#fff;
  3. text-transform:uppercase;
  4. font-style: italic;
  5. font-weight:bold;
  6. font-family: Arial, Verdana, Helvetica, sans-serif;
  7. font-size:131%;
  8. margin:6px 0 10px 0;
  9. letter-spacing:-.04em;
  10. }
Once again we have let CSS turn the text into uppercase so that we don't have to type in capitals in out HTML. I have also used letter-spacing to shorten the width of the text a little bit so that it matches more closely the PSD.
Figure 22 shows a comparison between our HTML version (on top) and the original PSD heading below.

Figure 22

Heading comparison
Although there are still some differences I am happy to proceed as it is far better to use normal text than it is to have to use images and image replacement techniques.
Next we tackle the text under the heading which includes the page icon and then some text with a border that fades at the ends (refer to figure 12 above). Looking at the 3 items under the "Latest News" heading we could almost think of them as a list of topics and use a list structure. However, I feel that paragraphs are more appropriate as they are really just three paragraphs of content following each other.
The icons and the underline will have to be cut out as transparent GIFs because they are used on different backgrounds. Again you will run into the jagged image problem but if you choose your transparent colors carefully it should be good enough for the task in hand. I have created three images that we need for the next section and they can be found here.
Page Icon Page Icon
UnderlineUnderline
Photo of the month Photo of the month
The lines of text are spaced apart so we will use line-height to space them correctly and margins and padding to create space around them. I am going to put the underline in the background of the p element and place it central and at the bottom which means we will need some padding bottom on the p element to allow room for this image to display.
Although, it isn't really needed I am going to wrap the 3 paragraphs of text in a containing div so that I can apply styles to the elements inside that div without the need for lots of classes (although we will need some classes).
The html for the top section is now looking like this:
HTML:
  1. <div class="news">
  2. <h3>Latest News</h3>
  3. <p><a href="#"><img src="images2/page-icon.gif" alt="Page Icon" width="14" height="16" /></a> Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
  4. <p><a href="#"><img src="images2/page-icon.gif" alt="Page Icon" width="14" height="16" /></a> Nam magna lectus, dapibus ut, ultrices at, fermentum eget, ligula.</p>
  5. <p class="last"><a href="#"><img src="images2/page-icon.gif" alt="Page Icon" width="14" height="16" /></a> Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
  6. <p class="readmore"><a href="#">Read All News <span>&raquo;</span></a> </p>
  7. </div>
The top section is contained inside a div and the icon image is in the html. The underline is image is placed in the background of the p element as mentioned above. The » (double arrow) has been put inside a span because it needs to be styled as a white color compared to the rest of the text which is black. We can then target the span via the parents class without needing to add another class to the span. The downside of this would be if you had more span elements in that section that you didn't want styled and then you would need to use a class for the span instead. Fortunately we don't have need of another span so we can simply target it via the parent's class. e.g.
CSS:
  1. .news span{color:#fff}
For the last line in that section I have added a class of "readmore" to apply to the last line which needs to be right-aligned and bold. I could have done this without a class by targeting the anchor directly but I though it wise to create a class in this instance as the "readmore" style is likely to be used elsewhere. If you look closely at the HTML above you will also see I have applied a class called "last" to the last paragraph in that section. The reason for this is that the last paragraph doesn't have an underline so we need to remove the image from the last one. Unfortunately we cannot use the :last:child css3 selector as IE doesn't support it so we need to add another class to the element concerned. Finally, to get the text to the right only needs text-align:right applied to the p element and that more or less completes the top section.
The Full CSS for that section is as follows.
CSS
CSS:
  1. .news{
  2. width:207px;
  3. color:#252e1c;
  4. }
  5. .news p{
  6. font-size:85%;
  7. background:url(images2/underline.gif) no-repeat center bottom;
  8. padding:0 7px 8px 0;
  9. line-height:1.4em
  10. }
  11. .news p.last{
  12. background:none;
  13. padding-bottom:1px;
  14. margin:0 0 .4em 0;
  15. }
  16. .news p img{
  17. margin-right:2px;
  18. vertical-align:middle;
  19. display:inline;
  20. }
  21. .news span{color:#fff}
  22. p.readmore{
  23. font-weight:bold;
  24. text-align:right;
  25. margin:0 0 1.4em 0;
  26. background:none;
  27. }
  28. p.readmore a{
  29. text-decoration:none;
  30. color:#252e1c;
  31. }
  32. p.readmore a:hover{
  33. text-decoration:underline;
  34. }
Notice that the "page-icon" image has been declared as inline so that it behaves like text. The vertical alignment was also set to middle so that it gets positioned correctly in respect to the text.
CSS:
  1. .news p img{
  2. margin-right:2px;
  3. vertical-align:middle;
  4. display:inline;
  5. }
Although images are "inline" by default we have set all images to be block in out global stylesheet and that is the reason we needed to set them back to "inline" here. I also put a little extra right margin on the image to give a bit of breathing space.
The next task is the "Photo of the Month" section which uses the same style of heading and text as the previous section. Therefore we can re-use our "news" class in this section but also add another (space separated) class to over-ride a few differences in this section.
If you study figure 21 above you will see that the "Photo of the Month" section is actually pulled over to the left by about 7 pixels or so compared to the news section above.To move this section into line I am going to use relative positioning rather than margins (although I could have used margins also). This is to show you how relative positioning can be used without harming the layout.
These are the photo styles:
CSS:
  1. .photo{
  2. position:relative;
  3. left:-6px;
  4. }
This will shift the element 6px to the left from where it was. It will not change the flow of the document at all and will cause no ill effects in this situation. However if we had shifted the element down the page with relative positioning you would find that it would overlap other elements and be a pain to work with. The fact of the matter is that position:relative only moves elements visually and not physically. They always occupy their original place in the page but just appear to be somewhere else. As far as other elements are concerned the element has not moved at all. This is why you must be careful if you use position:relative because it's not really meant for structural layout but for more subtle effects or where you want elements to overlap without disrupting the flow of the document.
If you want to move an element then most times you would use margins because this would keep other elements away by the distance specified and cause other elements to re-flow accordingly.
In this "photo" section we have another heading the same as the news section so we will use the h3 again which is already styled correctly. The big image that follows is really content and should be in the HTML rather than a background image so I will wrap the image in a p element and insert it into the page as shown below.
HTML
HTML:
  1. <h3>Photo of the month</h3>
  2. <p><img src="images2/month1.jpg" alt="Photo of the month" width="206" height="113" /></p>
The criteria for determining whether an image should be in the background or the foreground is simply to say to yourself :
"Is the image for decoration only"?
If the answer is yes it is decoration and bears no importance to the content then it should be a background image. If on the other hand the image is important to the content (such as this photo of the month image) the it should be in the HTML and not the background. I have wrapped the image in a p element because I dislike anonymous inline boxes and always ensure that inline elements are in a suitable semantic container.
We need to cancel out a few styles that were applied via the "news" class as this bottom section doesn't have an underline image and the spacing of the H3 is slightly different. Therefore we will use the "photo" class I mentioned earlier and over-ride a few styles as follows.
CSS:
  1. .photo h3{margin-bottom:8px}
  2. .photo p {background:none}
We also have the opportunity of re-using our "readmore" class and can apply it to the "Visit Gallery " text at the bottom. Also needed is the "last" class to set the correct bottom margin.
The full html for the section is as follows:
HTML
HTML:
  1. <div class="news photo">
  2. <h3>Photo of the month</h3>
  3. <p><img src="images2/month1.jpg" alt="Photo of the month" width="206" height="113" /></p>
  4. <p class="last"><span>&curren;</span> Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
  5. <p class="readmore"><a href="#">Visit Gallery <span>&raquo;</span></a></p>
  6. </div>
We can now compare the PSD and the HTML versions side by side for this section.

Figure 23

left column comparison

There are minor pixel differences and if you wanted to spend a little more time you could make the examples even closer but I think that the above is close enough for now and looks pretty good to me. In fact its quite hard to tell which image is the original PSD..........(It's on the left).
Now would be a good time for you to compare your code with the state of play so far and to validate your code and browser check once again.
I notice in the above image that the final paragraph of the PSD is slightly more indented than mine so we can target that paragraph as it already has a class of "last" applied to it and pad it out a bit.
CSS:
  1. .photo p.last{padding-left:5px}

That wraps up the left column and we can move onto the right column in the fourth and final part of our tutorial series. I hope you are following along and enjoying the tutorials, feel free to leave questions and comments below

0 comments:

Post a Comment

#
### ###