Saturday, January 8, 2011

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

 

This is the first in our 4 part series on how to take a PSD file and convert it into a fully CSS based html page. These are the first in a series of tutorials in which we build a fully working Photography site, all in clean Xhtml and CSS. All the code, templates and files are available for you to play with, and we encourage you to download and play with what is provided. The design template is licenced under the creative commons licence.

Lets get on with the tutorial!

One of the hardest parts of converting a PSD design into a well structured and semantic CSS/HTML layout is first knowing where to start. Although that may sound simplistic and obvious, it really does matter how you begin and that you build on strong foundations to start with. In this series of articles I will take you step by step through the conversion process and look at decisions that need to made on the way and how those decisions may need to adapt as things progress. The article will not address any specific graphic techniques (e.g. slicing and optimising) as this varies from paint package to package and is not the subject of the article. You will of course need to know how to do these things and I am assuming that you already have this basic knowledge.

For a starting point we are going to assume that you have just been handed a PSD by your clients graphic designer and asked to turn it into valid and workable CSS/HTML. (Obviously it would be better if you had input on the design before the "fait accomplis" was handed to you but for the purposes of the tutorial we will just accept that this is the case.)

Here is a smaller image of the layout we are going to eventually produce.

PSD Layout

Step 1

At first sight the layout looks quite straightforward but before we begin we should take a closer look at the elements and identify possible problem areas. At this early stage you may need to make important design decisions so you must have a clear idea of how the design can be achieved from the very start. If you identify areas that are impossible to create on a living web page or would cause to many browser issues then its best to locate them now and notify the client before you begin.

It is also worth mentioning at this point that you should have already agreed with your client exactly what work you are doing and exactly what they are paying for. If you don't define the exact parameters of the job in hand you will find that the client will take advantage of this and ask for every possible addition under the sun and expect support forever all for a pittance.(Some clients are not like this but there are a number who will be very sharp.)

Fixed, Fluid or em based

With the disclaimers out of the way we can get on with the job in hand and look at initial issues and then break the layout down into more manageable chunks. The first question that needs to be asked is whether this is a fixed with layout or a fluid width layout where each column can stretch. Of course you should consult with your client on these matters but for the purposes of this first tutorial we will assume that it's a fixed pixel width layout. Later on in the series we will explore how to convert the example to a fluid layout or an em based layout. But for the first article we will stick with pixels to make the process slightly easier to begin with.

My initial thoughts on looking at the PSD before even coding a line of html is that the designer has provided a lot of gradient and shadow effects in various places and also added rounded corners to some of the design elements. For example the background of the design has a vertical fade that fades from #282f27 - to #000000 over a 880 pixel range. That is no problem in itself in that we can repeat a vertical slice on the x-axis of the body while at the same time setting the body's background color to the finishing color of the fade (#000). This will allow the layout to extend vertically forever without problem. The complications will arise in that the header elements have a a slight background fade placed around them that varies with the body's fade.

We have two options here:

1) Create the fade around the element using PNG transparency for the fade so that the body's faded background can show through the opaque PNG image. Although this is fine for most browsers there are severe issues with IE6 and under that won't render the transparent PNG properly. We could use the proprietary alpha-image loader filter to compensate for IE5 and 5.5 if we have no other choice but that also comes with a number of associated problems and should only be used when there is no alternative.

2) Slice the elements background with the gradient shadow in place and match it up to the body's gradient background. As the header elements are a fixed height then this should work fine. Of course should text be resized and the elements allowed to grow then the fade may become mismatched. However, I thinks that's a small price to pay to keep the code simpler. Therefore this is the approach we will use for this method and if we find out later that its not good enough then we may have to think again.

Wire Frame

To roughly see what elements you need for the whole page you can create a wire-frame view of your site (either in your mind or just draw it on paper). Here is a quick mock up of the basic structure of our page.

Wire Frame

Although I am not going to build this wire frame for real it does give you a good visual clue as to what needs to be done and also provides some logical order to the proceedings. Some people will actually construct the wire frame version but I find this often gets in the way during development so we will do this my way and work our way through the page one element at a time and from the top down to the bottom.

Each area will present its own little problems but the basic structure can be seen to be a centred layout with three full width static horizontal sections followed by three columns that will need to be floated across the screen. The main part of the site will be the three floated columns and the big issues we will need to overcome are the three apparently equalising columns. This can be accommodated quite easily in our fixed with layout by using a repeating background image that creates the three columns automatically when we repeat it on a parent that is holding the 3 columns.

There will be additional issues to overcome in the main section because there are also vertical gradients and images aligned to the bottom to consider and we may need to adapt our design as we go. But for now it's good enough to have realised this and considered what the options are. If at this point you believe something to be impossible as not all designs can be transcribed to the web you should contact your client and seek alternative strategies should the design need to be changed, Better to raise issues now rather that have the client say "it must be like this" when you have finished.

After identifying the main issues and ratifying any design changes its time to start on the real work and actually do some coding and slicing.

As mentioned above I like to work on one element at a time in a logical fashion so we tackle each of these issues in turn and the process will look like this.

1) Grab font sizes, font families and basic colors from the PSD and set up up CSS defaults for these including your favourite Reset CSS snippet. Also set up the default font-size structure that will allow for text to be resized in IE6 and under. In fact this is such a common process that you should already have a template set up so that you can start work straight away and allows you just to change the font family and colours and off you go.

2) Measure the layout so that we can create a wrapper for the content as the page needs to be centred so all content can be within the wrapper. However some designers will use a width on the body element instead of using an inner wrapper but this presents problems in older IE browsers and I recommend leaving the body alone. However it is an option if you want to be really minimalist.

I find that I am often giving PSDs of 800px width because the graphic designer has been told that it is for a 800 x 600 page and doesn't realise that 800px is too wide for an 800px page due to chrome and scrollbar issues. The design would need to be about 760px wide (depending on browser) so as not to trigger a horizontal scrollbar. This is something you will get used to and need to look out for.

3) Start at the top and work down.

Working logically helps you break the job down into sections so that you can work on one thing at a time and plan the work accordingly. You always have to have an eye on what's coming next but concentrating on one thing at a time will focus your efforts and give you a sense of accomplishment when each element is completed rather that having half finished elements everywhere.

In our PSD we have the navigation at the top followed by the logo and tag line. Then follows a header image with search box. Finally we have three columns and a small footer with copyright message.

I like to use logical names for the sections and although there is some debate about what to use for each element it does help if your naming convention allows for the fact that maybe your html will be arranged at a later date and that your element names still make sense. If for instance your left column is called #leftcol and the at a later date you switch it using CSS to be the right column then it could be very confusing. It's better to use a more generic but functional name such as #sidebar1 for the left column and #sidebar2 for the right column or even #col1 and #col2. However you could move the sidebar to the middle and then it wouldn't be a sidebar anymore so think carefully about your names but don't go overboard with names that are so generic that you don't know what they refer to.

For our layout we will use the following id's:

#outer - hold all page content

#header - contains nav and other header elements such as logo and search.

#nav - main top navigation

#tagline - logo and tagline

#search - Search box and background image

#main - This is a wrapper that holds all three columns

#col1 - left column

#maincol - main centre column

#col3 - right column

#footer - Footer

For other internal elements we will use classes. Remember that IDs must be unique and can't be used more than once per page.

Basic Structure

We now have enough to write our very basic html structure and set up some default stylesheets so that we are ready to roll.

HTML:

PLAIN TEXT

HTML:

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

  2. <html xmlns=”http://www.w3.org/1999/xhtml”>

  3. <head>

  4. <meta http-equiv=”Content-Type” content=”text/html; charset=iso-8859-1″ />

  5. <title>Sanke Photography</title>

  6. <link href=”main.css” rel=”stylesheet” media=”screen, projection” type=”text/css” />

  7. <link href=”print.css” rel=”stylesheet” media=”print” type=”text/css” />

  8. <!–[if IE ]>

  9. <link href=”iecss.css” rel=”stylesheet” media=”screen,projection” type=”text/css” />

  10. <![endif]–>

  11. </head>

  12. <body id=”home”>

  13. <div id=”outer”>

  14. <div id=”header”>

  15. <ul id=”nav”>

  16. <li><a href=”#”>About Us</a></li>

  17. <li><a href=”#”>Gallery</a></li>

  18. <li><a href=”#”>Contact Us</a></li>

  19. <li><a href=”#”>Events</a></li>

  20. <li><a href=”#”>News</a></li>

  21. </ul>

  22. <div id=”tagline”></div>

  23. <div id=”search”></div>

  24. </div>

  25. <div id=”main”>

  26. <div id=”col1″></div>

  27. <div id=”maincol”></div>

  28. <div id=”col2″></div>

  29. </div>

  30. </div>

  31. </body>

  32. </html>

Main CSS:

PLAIN TEXT

CSS:

  1. /* main CSS Document */

  2. /* general styling first */

  3. /* reset css styles individually instead of universal selector. */

  4. /* based on http://meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/ */

  5. html, body{

  6. margin: 0;

  7. padding: 0;

  8. font-weight: inherit;

  9. font-style: inherit;

  10. font-size: 100%;

  11. font-family: inherit;

  12. vertical-align: baseline;

  13. border-left:0;

  14. }

  15. div, span, applet, object, iframe,

  16. h1, h2, h3, h4, h5, h6, p, blockquote, pre,

  17. a, abbr, acronym, address, big, cite, code,

  18. del, dfn, em, font, img, ins, kbd, q, s, samp,

  19. small, strike, sub, sup, tt, var,

  20. dl, dt, dd, ol, ul, li,

  21. fieldset, form, label, legend,

  22. table, caption, tbody, tfoot, thead, tr, th, td {

  23. margin: 0;

  24. padding: 0;

  25. border: 0;

  26. font-weight: inherit;

  27. font-style: inherit;

  28. font-size: 100%;

  29. font-family: inherit;

  30. vertical-align: baseline;

  31. }

  32. body {

  33. line-height: 1;

  34. color: black;

  35. background: white;

  36. font-family: Verdana,Arial, Helvetica, sans-serif;

  37. }

  38. ol, ul {list-style: none;}

  39. table {

  40. border-collapse: separate;

  41. border-spacing: 0;

  42. }

  43. caption, th, td {

  44. text-align: left;

  45. font-weight: normal;

  46. }

  47. /* end reset styles */

  48. /* clearing technique *

  49. .clearfix:after {

  50. content:".";

  51. display:block;

  52. height:0;

  53. clear:both;

  54. visibility:hidden;

  55. }

  56. .clearfix {display:inline-block;}

  57. /* mac hide */

  58. * html .clearfix {height: 1%;}

  59. .clearfix {display: block;}

  60. /* End hide */

  61. /*........... do not change or amalgamate the above clearfix styles ......*/

  62. p,h1,h2,h3,h4,h5,h6,ul,ol {margin-bottom:.5em}

  63. a img,img{border:none;display:block;}

  64. a{

  65. text-decoration:none;

  66. color:#252e1c;

  67. }

  68. h1,h2,h3,h4,h5,h6{

  69. font-weight:bold;

  70. }

  71. h1{font-size:197%}/* 26px */

  72. h2{font-size:182%}/* 24px */

  73. h3{font-size:167%}/* 22px */

  74. h4{font-size:152%}/* 20px */

  75. h5{font-size:136%}/* 18px */

  76. h6{font-size:122%}/* 16px */

  77. body{

  78. font-size: 13px;

  79. text-align:center; /* for ie5.+*/

  80. }

IE only CSS served from CSS file via conditional comments:

PLAIN TEXT

CSS:

  1. /* IE CSS Document */

  2. body {font-size:x-small;font-size:small}/*ie5 and 5.5. that are one size out*/

  3. body table{font-size:x-small;font-size:small}

This will be served as follows:

PLAIN TEXT

HTML:

  1. <!--[if IE ]>

  2. <link href="iecss.css" rel="stylesheet" media="screen,projection" type="text/css" />

  3. <![endif]-->

I have used Eric Meyers Reset CSS method to give uniform defaults to all elements and then used a font sizing method similar to the one used on Yahoo YUI. I am also going to use the :after method of clearing floats as documented on PIE as this allows floats to be cleared without structural mark-up and works nicely without too many side effects. All this will give a consistent base to work from and provides a good template for any page. Having this all set up to start with means that you can more or less get on with the job of converting the PSD without further ado.

You can copy the base files from here and get ready to roll.
base.htm
main.css
ie.css

Step 2

Assuming you have set up some reasonable defaults for text, link colors and font styles etc we can now get on with the job of construction. I have set the main font family to verdana in the body element because most of the page is in that font and that will save us from specifying it everywhere.

When I'm constructing a site for the first time I always work with the CSS in the head of the document (apart from the default sheets we already set up of course) because this makes it so much quicker to review and edit while working on the same page. Once the page is fully working and tested then the CSS can be added to the main external CSS file. It is also worth getting into the habit of checking your work at each stage in the browsers you want to support especially when you are learning. I more or less know what will or won't work but checking in 3 or 4 browsers at each stage makes sure that there are no discrepancies and things can be fixed easily at this stage rather than waiting until the whole thing is finished when indeed it may be impossible to fix.

You should also take these testing opportunities to quickly validate your HTML and CSS so that typos can be kept out of the code and ensure that the code you are using is legitimate.

I won't mention testing again (until the end) but you can assume that at each stage the above tests will take place.

From top to bottom

Working from the top down we will start with the body element itself and apply the gradient background as a repeating slice to the background of the body and repeat it along the x-axis. The background-color of the body will be set to the closing gradient color which happens in this case to be black. This will effect a seamless transition as the page goes from gradient to solid color.

The gradient is 800px high and therefore we have no choice but to slice the whole height of the gradient. Don't be tempted at this point to make the image 1px by 880px high because that means the browser will have to repeat that image 1024 times for a 1024px wide page and that takes a lot of effort on the browsers behalf. I would use at least a 5px wide slice or even 10px wide slice to save the browser working too hard and for the page to be drawn quickly. If the slice is 10px wide then the browser will only need to repeat the image 102.4 times rather that 1024 times which is a considerable difference.

There is always a trade-off between image file size and the time it takes to repeatedly draw it on the screen so don't be tempted to use 1px images everywhere or the page will slow to a crawl.

Slice the background of the PSD to create an image that is 5px x 880px and save it as bodybg.jpg.

This will give us the following CSS to add inside the head of our page (inside the appropriate style tags of course):

PLAIN TEXT

CSS:

  1. body{

  2. background:#000 url(images/bodybg.jpg) repeat-x 0 0;

  3. }

Now we move to the main content and need to create the page wrapper that holds all the content. Measure the page and then centre it. I have added a fix for ie5 already in the defaults that I set up earlier and have applied text-align:center to the body which will make ie5.x centre nested block elements such as our main wrapper #outer. We must however remember to set text-align back to left on #outer otherwise the text will be centred also.

Here is the resulting code from measuring the page and centering it using auto margins.

PLAIN TEXT

CSS:

  1. #outer{

  2. width:975px;

  3. margin:auto;/* center the page*/

  4. text-align:left;/* reset text back to left due to ie5.x fix */

  5. }

Header and Nav

The header is given a width to avoid "haslayout" issues in IE and ensure that we don't suffer from the myriad of associated bugs.

PLAIN TEXT

CSS:

  1. #header{

  2. width:975px;

  3. }

The navigation can be made horizontal by setting the list elements to generate "inline boxes" instead of "block boxes" and allow then to line up horizontally. Using lists for repeated navigation elements is now the accepted way of coding these elements and adds semantic structure to the page rather than a load of bare anchors that can cause accessibility problems with assisted technologies like screen readers. Adding padding to the ul allows the navigation to be spaced out correctly from the right edge and allow room for the overlapping graphic.

What font is is?

We run into out first problem in that the designer has to decided to use a non standard font for the navigation. Therefore you have to make choices (the first of many) on how to proceed.

If the design must have that exact font then there would be no alternative but to use images for the navigation as the font specified is unlikely to be present on 99.9% of systems. Using images for navigation can hurt your SEO (Search Engine Optimisation) prospects ins some cases so its worth avoiding doing this unless absolutely necessary. The main font used in the content of the page is Verdana so that would be the first font to try and see how close it looks. Unfortunately it didn't look too good but on testing further it seems that Arial is a close match especially when made italic and sized to match.

Here is a screenshot of the original navigation taken from the PSD compared to our layout in Firefox 2 using Arial.

Figure 1

Navigation comparison

The top line is the original and as far as I'm concerned that's pretty close. We can never match the anti aliasing and partial bolding that Photoshop offers anyway. If your client wants it exact then you will have to replace the text with images instead and use a suitable image replacement technique instead.

We can assume from the PSD that the word in green is the current page and can probably also assume that each word will rollover with the green color also so we will build that into the nav from the start. We simply apply a class of current to our list structure so that we can target that specific anchor and then also effect a change on hover for other elements. You may think that it would be better to add the class to the anchor instead but I find that putting the class on the list allows me to target the list element uniquely if needed and to also target the anchor uniquely therefore possibly saving using an extra class at a later date.

The full styles for the above are as follows.
CSS:

PLAIN TEXT

CSS:

  1. ul#nav{

  2. font-size:92%;

  3. padding:18px 115px 5px 0;

  4. text-align:right;

  5. }

  6. ul#nav li{

  7. display:inline;

  8. padding:0 13px 0 0;

  9. text-transform:uppercase;

  10. font-style: italic;

  11. font-weight:bold;

  12. font-family: Arial, Verdana, Helvetica, sans-serif;

  13. }

  14. ul#nav li a{

  15. color:#fff;

  16. }

  17. ul#nav li a:hover,

  18. ul#nav li.current a{color:#8bbd25}

HTML:

PLAIN TEXT

HTML:

  1. <ul id="nav">

  2. <li><a href="#">About Us</a></li>

  3. <li class="current"><a href="#">Gallery</a></li>

  4. <li><a href="#">Contact Us</a></li>

  5. <li><a href="#">Events</a></li>

  6. <li><a href="#">News</a></li>

  7. </ul>

Note that I have used text-transform:uppercase to make the navigation in uppercase rather than typing in uppercase. There are a number of reasons for this. First ITS RUDE TO SHOUT as we all know but more importantly the effect is really decoration and should be carried out via CSS and not the html and thirdly it makes the HTML look neater.

The navigation is more or less finished but we may need to tweak its positions later on so we will leave it as it is form now and come back later if we need to move it around.

That concludes part 1 of the Tutorial, Part 2 should be ready in a few days and will go more indepth into getting the page looking like the original PSD.

No comments: