<?xml version="1.0" encoding="UTF-8" ?>

<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
			<title>Tagged with "webdesign"</title>
			<link>http://www.addedbytes.com/feeds/tag-feed/</link>
			<description></description>
			<language>en</language>
			<copyright>Web Development in Brighton - Added Bytes 2006</copyright>
			<ttl>120</ttl>
			<item>
				<title>Text Readability Scores</title>
				<link>http://www.addedbytes.com/blog/code/readability-score/</link>
				<description><![CDATA[ A tool to give an indication of how easy text is to read, using the Flesch-Kincaid, Gunning-Fog, Coleman-Liau, SMOG and Automated Readability scoring systems. <p><strong>This tool has moved!</strong> It's now on its own domain, at <a href="http://www.readability-score.com/">Readability-Score.com</a>. (It's also had a small makeover and is now full of speedy AJAXy goodness.)</p>

<p>The code that powers the tool is still available on <a href="https://github.com/DaveChild/Text-Statistics">GitHub</a>.</p>

<!--<p>There are a few bugs in the system, so I've left the old tool up for now until everything is running smoothly.</p>

[ -- !ReadabilityScore! -- ]

<form method="post" action="blog/code/readability-score/"><fieldset style="border: 0; width: 90%;"><textarea name="text" rows="20" cols="20" style="border: 1px solid #000; width: 100%; margin-bottom: 20px;">[!Repopulate? &field=`text` !]</textarea>
<p style="text-align: center; padding: 20px 0 0 0;"><input type="submit" value="Check Text Readability" /></p></fieldset></form>--> <br><br>]]></description>
				<pubDate>Wed, 07 Jul 2004 15:14:59 +0100</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/blog/code/readability-score/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=design&amp;start=0" class="ditto_tag" rel="tag">design</a>,<a href="/feeds/tag-feed/?tags=language&amp;start=0" class="ditto_tag" rel="tag">language</a>,<a href="/feeds/tag-feed/?tags=literature&amp;start=0" class="ditto_tag" rel="tag">literature</a>,<a href="/feeds/tag-feed/?tags=readability&amp;start=0" class="ditto_tag" rel="tag">readability</a>,<a href="/feeds/tag-feed/?tags=reference&amp;start=0" class="ditto_tag" rel="tag">reference</a>,<a href="/feeds/tag-feed/?tags=resources&amp;start=0" class="ditto_tag" rel="tag">resources</a>,<a href="/feeds/tag-feed/?tags=tool&amp;start=0" class="ditto_tag" rel="tag">tool</a>,<a href="/feeds/tag-feed/?tags=tools&amp;start=0" class="ditto_tag" rel="tag">tools</a>,<a href="/feeds/tag-feed/?tags=usability&amp;start=0" class="ditto_tag" rel="tag">usability</a>,<a href="/feeds/tag-feed/?tags=webdesign&amp;start=0" class="ditto_tag" rel="tag">webdesign</a>,<a href="/feeds/tag-feed/?tags=writing&amp;start=0" class="ditto_tag" rel="tag">writing</a>
			</item>

			<item>
				<title>Writing Secure PHP, Part 4</title>
				<link>http://www.addedbytes.com/articles/writing-secure-php/writing-secure-php-4/</link>
				<description><![CDATA[ The fourth part of the <a href="http://www.addedbytes.com/articles/writing-secure-php/">Writing Secure PHP</a> series, covering cross-site scripting, cross-site request forgery and character encoding security issues. <p>In <a href="http://www.addedbytes.com/php/writing-secure-php/">Writing Secure PHP</a>, <a href="http://www.addedbytes.com/security/writing-secure-php-2/">Writing Secure PHP, Part 2</a> and <a href="http://www.addedbytes.com/security/writing-secure-php-3/">Writing Secure PHP, Part 3</a> I covered many of the common mistakes PHP developers make, and how to avoid some potential security problems. This article covers some of the more advanced security problems common to PHP on the web.</p>

<h3>Cross-Site Scripting (XSS)</h3>

<p>Cross-site scripting (often abbreviated to XSS) is a form of injection, where an attacker finds a way to have the target site display code they control. In its most basic form, this can be as simple as a site that allows HTML characters in usernames, where someone can specify a username like:</p>

<pre class="php">DaveChild&lt;script type="text/javascript" src="http://www.example.com/my_script.js"&gt;&lt;/script&gt;</pre>

<p>Now, whenever someone sees my username on the target site, the script I've added to my username will run. I could potentially use this to grab the person's login information, log their keystrokes - any number of nefarious activities.</p>

<p>As a developer, you can combat this type of attack by encoding or removing HTML characters (watch out for character encoding issues, as outlined next). Even better than stripping out unwanted characters is to allow a whitelist of safe characters in usernames and other fields. Be especially careful with e-commerce sites where you are listing orders in a CMS - an XSS vulnerability may allow an attacker to gain administrative access to your CMS. It is also important to turn off TRACE and TRACK support on the server, as if there is a vulnerability (and always assume that despite your best efforts there will be) these potentially allow an attacker to steal a user's cookie.</p>

<p>As a user you are also vulnerable to this sort of attack, and it is very difficult, at the moment, to make yourself safe against it. Vigilance is key, and to that end I have released a <a href="http://www.addedbytes.com/tools/xss-alarm-userscript/">userscript that warns you about third party scripts</a> (for users of GreaseMonkey, Opera or Chrome).</p>

<h3>Cross-Site Request Forgery (CSRF)</h3>

<p>Despite the similar name, CSRF is unconnected to XSS. CSRF is a form of attack where an authenticated user performs an action on a site without knowing it.</p>

<p>Let's assume that Jack is logged in to his bank, and has a cookie stored on his computer. Each time he sends an HTTP request to the bank (i.e., views a page or an image on a page) his browser sends the cookie along with the request so that the bank knows that it's him making the request.</p>

<p>Jill, meanwhile, runs a different website and has managed to get Jack to visit it. One of the items on the page is in fact loaded from the bank, for example in an iframe. The URL of the iframe or request contains instructions to the bank to transfer money from Jack's account to Jill's. Because the request is coming from Jack's computer, and includes his cookie, the bank assumes it is a legitimate request and the money is transferred.</p>

<p>This type of attack is extremely dangerous and virtually untracable. As a developer, your job is to protect against it, and the best way to do that is to remember <a href="http://www.addedbytes.com/php/writing-secure-php/">Rule Number One: Never, Ever Trust Your Users</a>. No matter how authenticated they are, do not assume every request was intended.</p>

<p>In practical PHP terms, you can combat CSRF with several relatively simple coding habits. Never let the user do anything with a GET request - always use POST. Confirm actions before performing them with a confirmation dialog on a separate page - and make sure <em>both</em> the original action button or link <em>and</em> the confirmation were clicked. Even better, have the user enter information like letters from their password on the confirmation page.</p>

<p>Add a randomly generated token to forms and verify its presence when a request is made. Use <a href="http://javascript.internet.com/page-details/break-frames.html">frame-breaking JavaScript</a>. Time-out sessions with a short timespan (think minutes, not hours). Encourage the user to log out when they've finished. Check the HTTP_REFERER header (it can be hidden, but is still worth checking as if it is a different domain to that expected it is definitely a CSRF request).</p>

<h3>Character Encoding</h3>

<p>Character encoding in PHP and associated database systems is worthy of its own series. In any one request, there may be more different character encodings in use than you might think.</p>

<p>For example, a single request and response (uploading a file to a server and writing information to a database) may involve all of the following differently items with different character encodings: the HTTP request headers, post data, PHP's default encoding, the PHP MySQL module, MySQL's default set, the set of each table being used, a file being opened and read, a new file being created and written, the response headers and the response body.</p>

<p>English-speaking developers generally don't have much cause to get embroiled in character encoding issues, and that results in a lot of developers with a serious lack of understanding of how character encodings work and fit together. For those that do have a reason to look at character encodings, usually that interest ends with the setting of the response's character set.</p>

<p>However, character sets are a fundamental part of all web development. English alone can exist in any one of a wide variety of sets, and developers are usually familiar with the most common two: ISO-8859-1 and UTF-8. Fewer are familiar with UCS-2, UTF-16 or windows-1252. Still fewer are familiar with commonly used alternative language sets (e.g, GB2312 for Chinese).</p>

<p>Which, in a very roundabout way, brings me on to the security pitfalls of character encodings. Where data is processed by PHP using one character set, but a database server uses a different character set, a character (or series of characters) deemed safe by PHP may in fact allow SQL injection against the database.</p>

<p>PHP security expert Chris Shiflett <a href="http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string">has written about this issue</a> and included an example of how it can be exploited to allow SQL injection even where input is sanitized using addslashes().</p>

<p>The solution is to always <em>always</em> use mysql_real_escape_string() rather than addslashes() (or use prepared statements / stored procedures), and to explicitly state character sets at all stages of interaction. Ideally, use the same character set throughout your system (UTF-8 is recommended) and where PHP allows you to specify a character encoding for a function (e.g., htmlspecialchars() or htmlentities()), make use of it.</p>

<p>It's not just SQL that's vulnerable as a result of character encoding bugs. Cross-site scripting is possible even where HTML characters are escaped if character sets are not handled properly. Fortunately, once again that is simple to avoid by properly setting character encodings at all stages of the process and specifying character encoding for functions where possible.</p> <br><br>]]></description>
				<pubDate>Thu, 11 Sep 2008 13:11:14 +0100</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/articles/writing-secure-php/writing-secure-php-4/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=code&amp;start=0" class="ditto_tag" rel="tag">code</a>,<a href="/feeds/tag-feed/?tags=coding&amp;start=0" class="ditto_tag" rel="tag">coding</a>,<a href="/feeds/tag-feed/?tags=development&amp;start=0" class="ditto_tag" rel="tag">development</a>,<a href="/feeds/tag-feed/?tags=mysql&amp;start=0" class="ditto_tag" rel="tag">mysql</a>,<a href="/feeds/tag-feed/?tags=php&amp;start=0" class="ditto_tag" rel="tag">php</a>,<a href="/feeds/tag-feed/?tags=programming&amp;start=0" class="ditto_tag" rel="tag">programming</a>,<a href="/feeds/tag-feed/?tags=security&amp;start=0" class="ditto_tag" rel="tag">security</a>,<a href="/feeds/tag-feed/?tags=tips&amp;start=0" class="ditto_tag" rel="tag">tips</a>,<a href="/feeds/tag-feed/?tags=tutorial&amp;start=0" class="ditto_tag" rel="tag">tutorial</a>,<a href="/feeds/tag-feed/?tags=web&amp;start=0" class="ditto_tag" rel="tag">web</a>,<a href="/feeds/tag-feed/?tags=webdesign&amp;start=0" class="ditto_tag" rel="tag">webdesign</a>,<a href="/feeds/tag-feed/?tags=webdev&amp;start=0" class="ditto_tag" rel="tag">webdev</a>
			</item>

			<item>
				<title>Ten Ways To Improve Your Website Conversion Rate</title>
				<link>http://www.addedbytes.com/articles/online-marketing/ten-ways-to-improve-your-website-conversion-rate/</link>
				<description><![CDATA[ Why worry about getting twice as many people to visit your site, when it can be far easier to double the number of sales from the people already visiting? Here are 10 ways to improve your website conversion rate. <h3>What is a Conversion Rate?</h3>

<p>Your conversion rate is a measure of the number of potential customers that go on to buy. In the context of a website, it is usually the percentage of visitors that make a purchase. Many websites concentrate solely on increasing the number of visitors they have, when often they have fairly simple problems with their site that, if solved, would have a huge effect on their conversion rate and improve their site's bottom line at minimal expense.</p>

<p>Improving a website conversion rate can be relatively simple. Here are 10 techniques for doing just that:</p>

<h3>10. Make The User's Life Easy</h3>

<p>Let's start with something that sounds simple, but apparently is too complex for many companies to get right. The more difficult you make your web site to use, the less people will buy from you.</p>

<p>A well designed website should aim to <em>prevent nobody from buying</em> - to allow 100% of the people who want to buy to do so. So where do they go wrong?</p>

<ul><li><strong>Accessibility</strong><br />Making a site accessible is a legal obligation in many countries. Despite that, inaccessible websites are still being created. That can affect your sales, depending on how inaccessible you are, as visitors find the site impossible to use and go elsewhere (and end up recommending one of your competitors to their friends as well). A fairly typical inaccessible site could be losing 5% of potential sales because of this. (A <em>really</em> inaccessible website could even prevent search engines indexing it, giving a far higher amount of potential lost sales.)
&nbsp;</li><li><strong>Browsers</strong><br />Many designers only pay attention to Internet Explorer. The justification for this is usually that 99% of the site's users use IE. It never seems to occur to the designers that perhaps the reason they have so few visitors with other browsers is that their site is fundamentally broken - it doesn't work in anything else. Percentages of people not using IE varies from site to site - over 60% of visitors to this site use an alternative browser, for example. The number most often quoted though, is that 80-85% of web users are using IE on Windows, which means that an average site that doesn't work in anything else could easily be losing 15-20% of sales.
&nbsp;</li><li><strong>Be Bold!</strong><br />What happens when a user decides to buy a product? They add it to a shopping basket. How do they add it? They click a button or link (usually a button). What happens when they can't see the button? They go elsewhere. There are some users who are <em>still</em> uncomfortable scrolling. Having things above the fold is still important. And yet there are still plenty of sites out there with buttons that are too subtle, or don't say the right thing, or are hidden away at the bottom of the page. "Add" is rubbish button text. "Buy" is ok. "Add xxx To Your Basket" is great. "Add xxx to Your Basket" in big letters on a big, bright button, near the top of the page, is even better. Calls to action, like this, don't have to be gaudy or tasteless, but they do have to be obvious and clear. Sites I have worked on where just the call to action was changed have reported anything from a 1% to 30% increase in sales as a result.
&nbsp;</li><li><strong>Usability</strong><br />If your potential customers want to find out more before they buy, can they? Is it obvious to the user where to go to find the technical specs on your products? Are they online at all? Are they in PDF format? Can users even find your products in the first place? This is probably the most common mistake I see on any website - a complete failure to think of what the user wants and needs, and how they might use a site. Plenty of sites have product pages with a photo and some sales patter - and nothing else. Anything from 1% to 99% of potential sales can be lost through poor usability.</li></ul>

<p>When you combine all of the problems above, it becomes fairly clear how easy it is to have a site perform poorly. Make your site accessible, make sure it is usable, make sure it works in common browsers, and make your calls to action clear and unambiguous, and you should be in a position to start converting the people who want to buy.</p>

<h3>9. Be Clear, Open and Honest</h3>

<p>If you have a product out of stock, say so. Few things annoy users as much as reading all about a product they are after, adding it to a cart, and starting the checkout process - only to find out the product isn't actually available.</p>

<p>The same applies to pricing - a user might spend $100 on a product, but when they find out the shipping is $100 on top of that, they are unlikely to continue the sale. Showing delivery pricing is tricky business, but not impossible. An <a href="http://ip-to-country.webhosting.info/node/view/6">Ip to Country</a> database will allow you to work out where a user is from and show them a likely delivery cost, for example. If you can't do that, show delivery prices for the countries most appropriate to you - where your products are most often delivered, or for major world regions.</p>

<h3>8. Don't Waste Time</h3>

<p>One of the biggest mistakes sites make is asking for too much information. Your conversion process may be sale, or it may be a request for information. Either way, don't waste the user's time asking for things you don't need to know. This is, of course, doubly important when it comes to asking for information the user deems private, and that they don't want to give out without good reason.</p>

<p>You don't need to demand the user's email address before letting them download a PDF. You don't need their phone number when they fill out an email enquiry form. A user may not want to buy from you twice - so why make them create an account so they can buy again later before processing their first order? You can give the user the option to do all of these things by all means, but make sure it's not compulsory.</p>

<h3>7. Help The User Trust You</h3>

<p>Most people are still cautious when buying online, and rightly so. There are plenty of people you really shouldn't give your credit card information to! It's important to give the potential customer every reason to trust you.</p>

<p>An address - bricks and mortar, not a P.O. Box - is a good start. A phone number, with people answering the phone, also helps. Showing a privacy policy and explaining shipping procedures clearly can also help the user to trust you. If you have a SSL certificate, show the "VeriSign Secured" logo to the user.</p>

<p>Design and content also play a part in trust. A poor design gives off an unprofessional feeling. If a company can't afford a decent website, or won't spend the money on it, how can a user be sure their order will be treated with the importance it deserves? If content is inaccurate or badly written, the same applies - show that you take pride in what you do.</p>

<h3>6. Have a Clear Returns Policy</h3>

<p>Returns on the web are, and are likely to remain, a major issue for consumers. With a bricks and mortar shop, the customer knows where the shop is and that to return the product they simply have to go back there and explain the problem. With the web, this is more of an issue. This is especially true for clothing (where people cannot try things on before buying).</p>

<p>Users are impressed with sites with a good returns policy and are more likely to buy from them. Have people phone for returns - they can then explain the problem to a real person, which is always a good first step. Free return shipping is usually a good option, if commercially viable. People don't like to pay to return things, especially if it is a mistake by the retailer. Finally, give the user plenty of time to return things. 28 days is fairly common, but if it takes you that long to deliver a product, what use is the return policy? 28 days from the date of delivery is better.</p>

<h3>5. Keep the User Informed</h3>

<p>When somebody buys something online, they want to know when it's going to arrive at their door. People are impatient, after all. Giving them an estimated delivery date during the checkout process is a good start. Emailing them when their product is dispatched is great. Giving them a tracking number if using a delivery service that supports online tracking is even better. Keep the user informed at every step of the process, before and after sale, about as much as you can.</p>

<p>How will this improve your conversion rate? Leaving the customer happy once they have made a sale means they are more likely to speak favourably about you later. They may even recommend you to their friends and within online communities. They are also far more likely to buy from you again.</p>

<p>Think about it like this - if a salesman is doing their absolute best to help you, and to make your life easy, and answering your questions, you might buy what they were selling. If they completely ignored you after you'd bought from them, how would you feel about them? They might well have undone all the good work they put in, because once you'd completed your purchase they see no immediate value in you. A company that shows it cares about their customers, even after they've finished shopping, will make a user far happier and far more likely to return.</p>

<h3>4. Offer Different Payment Options</h3>

<p>It might sound obvious, but you should offer the user a reasonable selection of methods of payment. Not everybody has a credit card, and those that do don't always want to use them. You don't have to accept cheques, but when deciding on payment methods, consider alternatives to the usual methods. Make the user's life easy and give them what they want.</p>

<h3>3. Improve the Value of Visitors</h3>

<p>People that buy from you are doing so because they like what it is they see. If a user adds a product to a basket, show them other things they might like as well. If they are viewing a product, the same applies - show them similar items. While they might not buy the product they first saw, other similar ones may not have issues that put them off the first. Upselling and cross-selling are tried and tested sales techniques, and there is no reason not to use them on the web.</p>

<h3>2. Be Memorable</h3>

<p>A good site will include information. A poor one is just an online catalogue. Information (articles, advice, reviews and so on) all help the user early in their buying process. Users start with research online, just as they do offline. If you can make contact with the user at that stage of their process, and give a favourable impression, there is a good chance that they will come back and buy from you when they finally decide to make a purchase.</p>

<p>Being memorable, and making sure you stick in the user's mind, is dependant on a lot of factors. You must have a USP (see the next point), and branding is important (no good if your visitors remember why you are great but don't remember your name), as well as the quality of your site and information.</p>

<h3>1. Know Your USP</h3>

<p>Finally, the most important point of all - your Unique Selling Point (USP). Your USP is what sets you apart from your competition. If a visitor goes to several sites looking for a product, why would they decide to buy from you instead of somewhere else?</p>

<p>Many companies do not know their USP. Almost all companies have one, but not all of them are aware of it. If you are a family run business, that's a potential USP. Great customer service, low prices, products that can't be bought elsewhere, free delivery, great support - all of these are USPs. Tell your users what yours is. Shout it from the proverbial rooftops.</p>

<h3>Part 2</h3>

<p>In March 2009, part 2 of this series was added: <a href="http://www.addedbytes.com/online-marketing/nine-more-ways-to-improve-your-website-conversion-rate/">Nine More Tips for Improving Your Website Conversion Rate</a>.</p>

<h3>Bonus!</h3>

<p>One excellent (and practical) way to increase your website conversion rate is to add consumer reviews to your store. They are a proven way to increase sales, and they have an excellent positive effect on your search engine optimisation work. A service like <a href="http://www.feedbackfair.com">FeedbackFair</a> will give your reviews extra credibility.</p> <br><br>]]></description>
				<pubDate>Mon, 12 Jun 2006 13:00:04 +0100</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/articles/online-marketing/ten-ways-to-improve-your-website-conversion-rate/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=business&amp;start=0" class="ditto_tag" rel="tag">business</a>,<a href="/feeds/tag-feed/?tags=conversion&amp;start=0" class="ditto_tag" rel="tag">conversion</a>,<a href="/feeds/tag-feed/?tags=design&amp;start=0" class="ditto_tag" rel="tag">design</a>,<a href="/feeds/tag-feed/?tags=ecommerce&amp;start=0" class="ditto_tag" rel="tag">ecommerce</a>,<a href="/feeds/tag-feed/?tags=howto&amp;start=0" class="ditto_tag" rel="tag">howto</a>,<a href="/feeds/tag-feed/?tags=marketing&amp;start=0" class="ditto_tag" rel="tag">marketing</a>,<a href="/feeds/tag-feed/?tags=seo&amp;start=0" class="ditto_tag" rel="tag">seo</a>,<a href="/feeds/tag-feed/?tags=tips&amp;start=0" class="ditto_tag" rel="tag">tips</a>,<a href="/feeds/tag-feed/?tags=tutorials&amp;start=0" class="ditto_tag" rel="tag">tutorials</a>,<a href="/feeds/tag-feed/?tags=usability&amp;start=0" class="ditto_tag" rel="tag">usability</a>,<a href="/feeds/tag-feed/?tags=web&amp;start=0" class="ditto_tag" rel="tag">web</a>,<a href="/feeds/tag-feed/?tags=webdesign&amp;start=0" class="ditto_tag" rel="tag">webdesign</a>
			</item>

			<item>
				<title>Online Marketing for Beginners</title>
				<link>http://www.addedbytes.com/articles/for-beginners/online-marketing-for-beginners/</link>
				<description><![CDATA[ Wondering why you should hire someone to market your website and how they should go about doing it? Hopefully this article can help. <ul class="conversation"><li class="altrow"><span>Client:</span><div>'I want to be number 1 in Google.'</div></li><li><span>Me:</span><div>Sigh. 'Everyone does. Did you have any keywords in mind?'</div></li><li class="altrow"><span>Client:</span><div>'I was thinking of all these words.' (Client hands me a list of words including "sex", "poker", "loans" and so on.)</div></li><li><span>Me:</span><div>'Those have nothing to do with your business.'</div></li><li class="altrow"><span>Client:</span><div>'Yes, but lots of people search for them.'</div></li><li><span>Me (thinks):</span><div>'Did I travel back in time to 1996? Am I suddenly the Marty McFly of SEO? I wonder why DeLorean cars weren't more popular ...'</div></li><li class="altrow"><span>Client:</span><div>'Dave?'</div></li><li><span>Me:</span><div>'Sorry. Ok, we need to talk. Let me explain how search and online marketing actually work ...'</div></li></ul>

<p>It is amazing how many people hire online marketers without the faintest idea of what online marketers actually do. Search engine optimisation (SEO) is fairly simple - SEOs will try and improve your site's performance, usually by trying to leverage their knowledge of how search engines work and tricks they can use to make sites seem more relevant than they actually are to specific keywords.</p>

<p>Marketing online, though, need not have anything to do with search engines. Search engines are irrelevant - good positions and traffic are a by-product of effective online marketing.</p>

<p>Unfortunately, after educating a client on what online marketing is, they usually assume that if they pay you a few hundred pounds, you can make their site compete with the very best out there.</p>

<ul class="conversation"><li class="altrow"><span>Client:</span><div>'Ok, I see. Great positions aren't necessarily worth much unless there are customers searching for those keywords.'</div></li><li><span>Me:</span><div>'Right. We want high traffic, but not if it's not going to be bad for your bottom line. Traffic that doesn't convert to sales just costs you money. Same applies for phrases people never search for. No point being number one for the phrase "fish banana druid" - it's likely to get you as many customers as peeing on people that walk past your shop will.'</div></li><li class="altrow"><span>Client:</span><div>'Ok, so if I pay you, say, £300, how long before I'm at number one for this list of relevant phrases?'</div></li><li><span>Me:</span><div>'You wouldn't get in a boxing ring with Joe Calzhaghe after jogging a couple of miles and doing a few push-ups, would you?'</div></li><li class="altrow"><span>Client:</span><div>'Well, no.'</div></li><li><span>Me:</span><div>'Exactly. To compete with the big dogs, you need to think bigger. Your site is a 10 stone weakling at the moment, and the aim is to turn it into a champion. It needs to be Rocky Balboa. You won't get the top spots quickly - this takes time and hard work. And it's not cheap.'</div></li></ul>

<p>People are obsessed with money. Absolutely obsessed. Even more so in a company environment. The chances are the most of the time, the person you are talking to at a client (or potential client) company is not the top dog. They have to justify their decisions, and they certainly have to justify what they spend.</p>

<p>The problem is that the way most people look at SEO (and they are thinking SEO, not marketing - it's up to you to show them the difference) is that they're going to pay a certain amount of money for the top spots for certain keywords. You can guarantee they've been told another company will guarantee 10 number 1 positions for $50.</p>

<p>This is where ROI comes into play. ROI stands for "Return on Investment". Paying $50 for a $0 return is a bad idea - but people do it all the time, because it's cheap. Paying $5,000 for a $50,000 return is a great idea - but people gasp at the very idea they could spend that much in the beginning, despite the potential.</p>

<p>In order to measure a return, you need to use tracking. If you're focussed on natural search, measure natural search traffic. See how many people come to the site, and where from. See where they go in the site. See if they view products, add them to a basket, and complete sales. See if they view products then come back weeks later to buy them. Measure that over time and you can tell a client exactly what effect your marketing campaign is having - and you will be able to show them what they are getting for their money. Usually, telling a client you are going to do this will also put their mind at ease - much easier to spend money on someone when that person tells you how they're going to measure their success. Most companies involved in SEO and online marketing focus on positions, not results.</p>

<ul class="conversation"><li class="altrow"><span>Client:</span><div>'That's good to know. If I can see what's going on, I can give hard numbers to my boss. I'd rather tell him we have 10% more visitors and 20% more sales than tell him we're in top positions for our target phrases but traffic has gone down.'</div></li><li><span>Me:</span><div>'Woohoo! You've taken your first step into a larger world.'</div></li></ul>

<p>The other thing to bear in mind with money conversations is that most companies think of their site like a brochure. They think of it as a print-like cost, where they pay a fixed sum and that's it. They put the site up, leave it, and expect results. They should be thinking of a site like a salesman. A salesman that never sleeps, rarely gets ill, and can handle virtually unlimited enquiries. As such, they should be thinking of the money they spend more like a wage.</p>

<ul class="conversation"><li class="altrow"><span>Client:</span><div>'We're spending $200 a month on our site now for hosting. Are you saying we should be spending a lot more?'</div></li><li><span>Me:</span><div>'What would you pay a salesman with the figures your site has, ignoring PPC?'</div></li><li class="altrow"><span>Client:</span><div>'Probably $3000 a month.'</div></li><li><span>Me:</span><div>'Then that's what you should be spending on the site. As the figures get better, spend a little more. Remember that that needs to include redesigns, hosting and other costs.'</div></li></ul>

<p>(Note: PPC is something of a difficult subject to bring in to a monthly spend on a site. You should have a monthly spend on PPC, but it should be managed as a separate entity.)</p>

<p>The same traffic you are monitoring to see where site visitors are coming from and what they are doing when they reach the site can also give you some good places to start making changes. Break the traffic down by area, by language, by time of day (user time of day, not server time of day), and track who converts to a sale and who doesn't. Track people through the sales process, and watch which links they click to navigate and buy products.</p>

<p>This will tell you a huge amount about the current users of the site. It will show you quick wins, opportunities, and highlight problems. Forget search - if on your first day marketing a website you can spot that there is a problem with the site checkout process and get it fixed, you could double sales from existing users. That's a good start to any campaign.</p>

<p>Look at language and area closely as well. If a site is getting traffic from the US, but only sells to the UK, look at similar companies only serving the US and strike a deal with them. You direct US traffic to them, they direct UK traffic to you, and you both do slightly better.</p>

<p>Check browser usage stats, especially if the site is a tables-based dinosaur. The chances are that it is an inaccessible mess. Get it cleaned up! Semantic markup is key - it allows user agents (browsers, search engine spiders, screen readers) to attach specific meaning to different areas of a page. Unlike with tables, semantic markup allows you to differentiate between a header and normal content, or to identify an address. Accessible coding is likely to draw attention, and should help you retain a higher percentage of your visitors, and should help reduce the running costs of your website (lower bandwidth bills and quicker turnarounds on redesigns, for example, both save you money).</p>

<ul class="conversation"><li class="altrow"><span>Client:</span><div>'I don't care about different browsers though - they only make up 1% of my traffic. Everyone else uses Internet Explorer'</div></li><li><span>Me:</span><div>'Perhaps it is because your site doesn't work in other browsers that that number is so low. Even if you do have 99% of users on the same system, the other 1% is still important. Techies use different browsers and operating systems. Techies are also often the people who are asked by their families if they know a good site to buy something from. Many directory editors are in the same boat, and techies can create links to your site.'</div></li><li class="altrow"><span>Client:</span><div>'Ok, techies are important. But do I need to care about blind users and all that accessibility stuff?'</div></li><li><span>Me:</span><div>'Yes, of course. It's a legal obligation for one thing, but users with sight problems make up a far larger proportion of your audience than you might think. They have a voice too - and it's far harder to undo the damage some adverse publicity can do than it is to make a site work properly in the first place. Finally, search engine spiders are blind users with no JavaScript support.'</div></li></ul>

<p>Dynamic sites are slightly trickier to improve. Most of the time, they are restricted, with the original authors not allowing access to the website code. Even if access to the code is allowed, changes may be overwritten later or worse cause immediate problems on the site. That said, making a site easier to use is important, and often dynamic sites are not easy to use.</p>

<p>Look at the pages users visit in the site, and how they get there. Look at the products they buy and spot themes. Use that information to make the important sections and products easier to find and organise. For example, if listing products, don't make people click through 4 levels of navigation to find them - improve the product navigation. Once they get there, allow them to reorder the page according to what they consider important, be that name, price, manufacturer - whatever is possible.</p>

<p>Remember also that people like to tell other people about things they find. If a user likes something on your site, they may email the address of the page they are on to a friend. Most people use forms to set the ordering criteria of a page. That means that the user will be sending a friend a URL that will show that friend something different to what the user currently sees. Make life easy for your users - use URLs, not forms, wherever possible in a site.</p>

<ul class="conversation"><li class="altrow"><span>Client:</span><div>'I am curious about one thing. We're already really well ranked for the name of our main product, and lots of people search for it. The people that visit our site tend to buy the product. But I can't help feeling that there should be more people coming from the engines. Any ideas?'</div></li><li><span>Me:</span><div>'Yes. The <a href="http://inventory.overture.com/d/searchinventory/suggestion/">Overture Search Term Suggestion Tool</a>', capitalising my speech for no good reason, 'shows that millions of people search for that phrase. I can see you have a top spot. And your traffic is surprisingly low, but converting well.'</div></li><li class="altrow"><span>Client:</span><div>'So I'm not imagining it then - we have a problem?'</div></li><li><span>Me:</span><div>'Yes, we do. When a user looks at search results, they scan the first two or three words of each link. Your link says "Arthur Jackson Ltd. Sheds and other garden products." That comes from your page title.'</div></li><li class="altrow"><span>Client:</span><div>'And that's bad?'</div></li><li><span>Me:</span><div>'Most people will only glance at "Arthur Jackson Ltd". You need to show them, in the first two or three words of your page title, that you have what they are looking for. And you're not doing that. The user has no reason to click on your link ahead of all the others they see.'</div></li></ul>

<p>Titles are tricky. They're important to the user, they provide the text for bookmarks, they appear in search results, and search engines use them as part of ranking algorithms. You need for fit branding into a title, and describe a product, ideally also incorporating a call to action. Tricky stuff. But not impossible.</p>

<p>First, consider the brand. Most companies think their company name should be the first thing in a page title, even if the rest is unique for each page (as it should be). However, unless the company has a household brand name, the company name is irrelevant to the searcher. They're looking for a product (or the answer to a question), so show them you have it.</p>

<p>Next, remember that as titles are used as the text for bookmarks, links and appear in search engines, they should, when taken out of context, by themselves, leave no doubt what a page is about.</p>

<p>A good example of a title is:</p>

<ul class="conversation"><li class="altrow">"Norwegian Blue Parrot - Buy Norwegian Blue Parrots from Mr. Praline's Pet Shop".</li></ul>

<p>You've included the all-important product name twice in the title, along with a call to action, a hefty dose of branding, and not added irrelevant information. It's a title that tells the user straight away what the page is about. No messing around.</p>

<ul class="conversation"><li class="altrow"><span>Client:</span><div>'Ok, the titles need sorting, but what about the content of the site? I keep hearing that "Content is King".'</div></li><li><span>Me:</span><div>'Content is, ultimately, King. Sites with lots of great content will, over a decent time period, far outperform sites with no original content. But content doesn't just have to be on site ...'</div></li></ul>

<p>Product is important. The object you sell though is only half of the picture. A user will want support from you. They will want information. They may want news. All of this is part and parcel of the package a company offers. Your site needs good, visible support (including a phone number), as well as plenty of good, original information. Guides to products, online manuals, FAQs, advice - there are always areas, in any industry, where content can be added.</p>

<p>Content need not be solely posted on the website either. Big news should be released as a press release, and there are plenty of services that will distribute press releases for you. These will be reproduced all over the web, allowing more and more people to hear of the company. Most press release services will allow you to embed a link to a site in a press release, generating more direct traffic as well.</p>

<p>When writing content, or advising on the writing of content, remember that it is not about keywords. Sure, keywords are important, but there is more to it than simply stuffing as many keywords into text as possible. Content needs to answer questions - to provide information. It needs to give a user what they are looking for, and they need to feel that it has done that. Content that is written for SEO can read very badly with too many keywords in, and can mean that although more people see an article, most of them leave the site straight away to find a better one.</p>

<p>A good way to add content to a site is a blog, or a news section. Aside from adding plenty of information, this gives a great opportunity to connect with the user. Consumers are constantly being targeted, from every angle, by companies anxious to take their money. Sometimes they get trodden on. When adding content to your site, stay on the side of the average consumer. Recently, in the UK, the energy companies all raised their prices dramatically. Sites that allow users to compare fuel prices almost all missed a great opportunity to have themselves noticed - not one of them posted a decent news item denouncing the changes as unnecessary or over the top. They all simply commented on the change factually.</p>

<p>While on the one hand, some of these companies may be unable to comment in this fashion (and many companies have strict policies regarding neutrality and customer perception), at least one should have been able to stand out by taking a clear, customer-supporting position on the issue. That is the kind of thing that gets companies noticed and remembered, and spotting opportunities like that is key to a good marketing strategy.</p>

<p>Not all content need be inflammatory of course. It does need to be unique in some way, however. It can be controversial, but it could also be definitive - the ultimate and complete guide to a topic. Controversial content is interesting to the user, and definitive content is just plain useful - either makes for good content for any website.</p>

<p>Users go through different stages when buying products, and one of the early ones is a research stage. There is always a good chance that a user will come back to the same place that helped them or impressed them when they were doing research to buy what they were looking for. This is branding - associating specific ideas and feelings with your company. You want your users, when they revisit the web to make a purchase, to think of your company first.</p>

<p>Which brings us nicely to our last, and most important point. Why would a customer think of any company first, ahead of any other. Content will help, yes. A nice design might even make a difference. More than anything else, though, customers pay attention to the company that stands out from the crowd - the company that is <em>different</em>, that offers them something nobody else does. Often known as a Unique Selling Point, or USP, this is the thing that makes you memorable, or if ignored helps you blend into the crowd.</p>

<ul class="conversation"><li class="altrow"><span>Client:</span><div>'But we don't have a USP. How do we get one?'</div></li><li><span>Me:</span><div>'Well, hang on one minute. You say you don't have a USP, but is there nothing about your product that makes it better than the alternatives?'</div></li><li class="altrow"><span>Client:</span><div>'Well, we sell Norwegian Blue Parrots. They're all the same, really. Although a rather large proportion of our competitors appear to sell mostly dead ones.'</div></li><li><span>Me:</span><div>'There you go then. Your USP is that your product is, in fact, not dead.'</div></li><li class="altrow"><span>Client:</span><div>'By that reasoning, a USP could be almost anything, when put in the right light. And when did we turn into a Monty Python sketch?'</div></li><li><span>Me:</span><div>'Be quiet about the Monty Python thing. Yes, though, a USP can be virtually anything. It can be quicker delivery than competitors, better products, better customer service, a freephone enquiries number, or simply the people that run the business. Almost every business has a USP - although most of them don't know what it is.'</div></li></ul>

<p>Many businesses don't know their own USP. They can't tell you, when you ask, what makes them different. Many of them will just say "because we're better than the others", but can't explain why. Usually, however, a quick chat will reveal what makes them stand out. Whatever the USP is, it needs to be clear and obvious on the website. The customer can't miss it, because if they don't know what makes one business different from another, they're not going to remember it.</p>

<ul class="conversation"><li class="altrow"><span>Client:</span><div>'What about search? You've not told me how to get my site to the top of the search engines!'</div></li><li><span>Me:</span><div>'Let's review, shall we. You've changed your site substantially, so that it meets current standards and you can sell to more of your users. You're showing your clients why you are better than your competition. You've started releasing press releases, and adding content to your site. You're championing the cause of the common man, increasing link numbers and getting people talking about your business. And you know how your users find your site, and what they do when they get there.'</div></li><li class="altrow"><span>Client:</span><div>'And?'</div></li><li><span>Me:</span><div>'You're positioning yourself as a great resource for your market. Your search engine rankings will come as a direct result of everything else you are doing. You're going to perform well in search, as a direct result of good marketing.'</div></li><li class="altrow"><span>Client:</span><div>'I'll get my chequebook.' (Hah. As if.)</div></li></ul> <br><br>]]></description>
				<pubDate>Fri, 19 May 2006 08:34:00 +0100</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/articles/for-beginners/online-marketing-for-beginners/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=article&amp;start=0" class="ditto_tag" rel="tag">article</a>,<a href="/feeds/tag-feed/?tags=blog&amp;start=0" class="ditto_tag" rel="tag">blog</a>,<a href="/feeds/tag-feed/?tags=business&amp;start=0" class="ditto_tag" rel="tag">business</a>,<a href="/feeds/tag-feed/?tags=guide&amp;start=0" class="ditto_tag" rel="tag">guide</a>,<a href="/feeds/tag-feed/?tags=howto&amp;start=0" class="ditto_tag" rel="tag">howto</a>,<a href="/feeds/tag-feed/?tags=marketing&amp;start=0" class="ditto_tag" rel="tag">marketing</a>,<a href="/feeds/tag-feed/?tags=optimization&amp;start=0" class="ditto_tag" rel="tag">optimization</a>,<a href="/feeds/tag-feed/?tags=search&amp;start=0" class="ditto_tag" rel="tag">search</a>,<a href="/feeds/tag-feed/?tags=seo&amp;start=0" class="ditto_tag" rel="tag">seo</a>,<a href="/feeds/tag-feed/?tags=toread&amp;start=0" class="ditto_tag" rel="tag">toread</a>,<a href="/feeds/tag-feed/?tags=tutorials&amp;start=0" class="ditto_tag" rel="tag">tutorials</a>,<a href="/feeds/tag-feed/?tags=web&amp;start=0" class="ditto_tag" rel="tag">web</a>,<a href="/feeds/tag-feed/?tags=webdesign&amp;start=0" class="ditto_tag" rel="tag">webdesign</a>
			</item>

			<item>
				<title>Preload Images with CSS</title>
				<link>http://www.addedbytes.com/blog/code/preloading-images-with-css/</link>
				<description><![CDATA[ How to preload images using CSS and so avoid delays with rollover effects. <p>As support for CSS improves, pseudo-selectors like :hover, :active and :focus will become more widely used. Already :hover is in use on many sites to provide rollover states to buttons, as on this site (the menu bar). The other pseudo selectors will, in time, give far more opportunities for the use of rollover images.</p>

<p>One potential problem with image rollovers, though, is that in order for an image to be displayed, it must be downloaded. Consequently, for rollovers to work smoothly and quickly, all the necessary images must be already available on the user's PC. Otherwise, the rollovers will behave badly, like in this <a href="http://www.addedbytes.com/css_preload/">example using large images</a>.</p>

<p>Until recently, rollover effects were achieved through use of JavaScript, and as a result, a plethora of solutions to the preloading image problem in JavaScript are available. However, using JavaScript to preload images, though not a bad idea when using JavaScript to control rollovers, becomes less bright when it is CSS that's controlling them. A user could very easily (and this is becoming more common) have a CSS-capable browser without JavaScript support or with JavaScript turned off.</p>

<p>So there's a clear need for a way to use CSS to preload images or find another way to avoid the problem. Which gives us two relatively simple solutions to our problem.</p>

<p>The first solution is to create a single background image for your element that actually contains both the rollover and non-rollover images, and then position is using the background-position CSS property. Instead of changing the image when the mouse moves over the element, you can simply change the background-position to reveal the previously hidden rollover image. There's a more detailed <a href="http://wellstyled.com/css-nopreload-rollovers.html">explanation of this technique</a> over at WellStyled.com.</p>

<p>The other option available to you is to trick the browser into downloading the image before it is required for the rollover. This can be done by applying the image as a background to an element, and then hiding it using the background-position property. The image will then be downloaded but will not be displayed. Then, when the rollover is activated, it will operate smoothly and instantly.</p>

<p>First, you need to select an element that doesn't currently have a background image. If so select an element that does have a background image, you will either end up not preloading the image you are after, or you will prevent the element's normal background displaying. Neither is ideal.</p>

<p>Once you have picked an element to use for this purpose, you need to add the background image. The following CSS can be applied to the element and will place the background image outside the viewable area of the image:</p>

<code>background-image: url("rollover_image.png");
background-repeat: no-repeat;
background-position: -1000px -1000px;</code>

<p>Your rollover image will then be loaded when the page itself is initially loaded, along with the other images. When a rollover is then activated, the image will already be available to the browser and the effect will be instant.</p> <br><br>]]></description>
				<pubDate>Thu, 23 Dec 2004 10:13:43 +0000</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/blog/code/preloading-images-with-css/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=code&amp;start=0" class="ditto_tag" rel="tag">code</a>,<a href="/feeds/tag-feed/?tags=css&amp;start=0" class="ditto_tag" rel="tag">css</a>,<a href="/feeds/tag-feed/?tags=design&amp;start=0" class="ditto_tag" rel="tag">design</a>,<a href="/feeds/tag-feed/?tags=howto&amp;start=0" class="ditto_tag" rel="tag">howto</a>,<a href="/feeds/tag-feed/?tags=image&amp;start=0" class="ditto_tag" rel="tag">image</a>,<a href="/feeds/tag-feed/?tags=images&amp;start=0" class="ditto_tag" rel="tag">images</a>,<a href="/feeds/tag-feed/?tags=preload&amp;start=0" class="ditto_tag" rel="tag">preload</a>,<a href="/feeds/tag-feed/?tags=rollover&amp;start=0" class="ditto_tag" rel="tag">rollover</a>,<a href="/feeds/tag-feed/?tags=web&amp;start=0" class="ditto_tag" rel="tag">web</a>,<a href="/feeds/tag-feed/?tags=webdesign&amp;start=0" class="ditto_tag" rel="tag">webdesign</a>,<a href="/feeds/tag-feed/?tags=webdev&amp;start=0" class="ditto_tag" rel="tag">webdev</a>
			</item>

			<item>
				<title>View Page Structure</title>
				<link>http://www.addedbytes.com/blog/code/view-page-structure/</link>
				<description><![CDATA[ A tool that outputs the structure of a page. Makes working with CSS (especially resolving inheritance issues) much easier. <p>A couple of days ago, I was having a little CSS trouble. In the end, it turned out that I had set a property of an element "above" in the document tree, and the problematic element was inheriting that property.</p>

<p>It struck me that it would be easier to work through this kind of CSS problem with some kind of simple tool to show how a page was put together. If I could see all the tags on the page in a nested format, with parent and child relationships obvious, and without all the text getting in the way, my life would be easier.</p>

<p>So, I put together this tool. In simple terms, it will fetch a page from a web server and output the tags within the page in a nested list. The JavaScript side of it will also highlight children of an element when you hover over it.</p>

<p>Classes and ids attributes are highlighted, as are tag names. Class and ID names, though, must be enclosed in quotation marks to be highlighted. Text, closing tags and line breaks are not shown. Though I can understand some people may find it useful to see text, I found it made the tree too large to be usable.</p>

<p>I've used it a few times, and am quickly finding it saves quite a lot of time solving simple CSS problems or conflicts. Which is exactly what it was supposed to do. Enjoy!</p>

<h3>Highlighting Issues</h3>

<p>When writing the tool, I came across a fairly unusual problem. I wanted, when the mouse was over an element, to highlight its children. However, this cannot be done with CSS (at least, I couldn't think of a way to make it work).</p>

<p>The problem with the CSS was that whenever you hover over an element, you are also hovering over its parents. So they, and their children, are highlighted - meaning everything is highlighted. For this reason, the highlighting of elements uses JavaScript.</p>

<h3>How to Use</h3>

<p>The page structure tool is written to accept a URL either by GET or POST. You can therefore use it one of two ways.</p>

<p>First, you can use the tool by visiting the URL below, replacing "##url##" with the address of the page you want to view:</p>

<p>http://www.addedbytes.com/view_structure.php?url=##url##</p>

<p>Alternatively, you can use the following form to submit an address to the page:</p>

<form action="http://www.addedbytes.com/view_structure.php" method="post"><label for="viewstrucinput">Enter URL</label> <input id="viewstrucinput" name="url" type="text" /> <input type="submit" value="View" /></form>

<h3>Bookmarklet</h3>

<p>To make life a little easier, I've coded a quick JavaScript bookmarklet for you to use, that, when activated, will automatically submit the URL of the page you are viewing to the tool. Simply copy or drag the link below to your links bar, your favourites folder or anywhere else you wish:</p>

<ul><li><a href="javascript:void(location.href='http://www.addedbytes.com/view_structure.php?url='+location.href);">View Page Structure</a></li></ul>

<h3>Notes</h3>

<ul><li>This tool works best with valid code, especially XHTML.</li><li>A certain amount of basic code improvement is done before processing (for example all empty tags are automatically closed).</li><li>Sites with non-empty tags that aren't closed properly may not show up correctly.</li><li>Sites with large amounts of nested code should still show up, but it may be difficult to view the output.</li></ul>

<h3>Example</h3>

<p>If you want to see an example of the output of this tool, you can view the  <a href="http://www.addedbytes.com/view_structure.php?url=http://www.addedbytes.com">structure for AddedBytes.com</a>.</p> <br><br>]]></description>
				<pubDate>Tue, 12 Oct 2004 16:24:00 +0100</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/blog/code/view-page-structure/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=cheatsheet&amp;start=0" class="ditto_tag" rel="tag">cheatsheet</a>,<a href="/feeds/tag-feed/?tags=code&amp;start=0" class="ditto_tag" rel="tag">code</a>,<a href="/feeds/tag-feed/?tags=css&amp;start=0" class="ditto_tag" rel="tag">css</a>,<a href="/feeds/tag-feed/?tags=design&amp;start=0" class="ditto_tag" rel="tag">design</a>,<a href="/feeds/tag-feed/?tags=imported&amp;start=0" class="ditto_tag" rel="tag">imported</a>,<a href="/feeds/tag-feed/?tags=resources&amp;start=0" class="ditto_tag" rel="tag">resources</a>,<a href="/feeds/tag-feed/?tags=tool&amp;start=0" class="ditto_tag" rel="tag">tool</a>,<a href="/feeds/tag-feed/?tags=tools&amp;start=0" class="ditto_tag" rel="tag">tools</a>,<a href="/feeds/tag-feed/?tags=useful&amp;start=0" class="ditto_tag" rel="tag">useful</a>,<a href="/feeds/tag-feed/?tags=webdesign&amp;start=0" class="ditto_tag" rel="tag">webdesign</a>,<a href="/feeds/tag-feed/?tags=xhtml&amp;start=0" class="ditto_tag" rel="tag">xhtml</a>
			</item>

			<item>
				<title>Writing Secure PHP, Part 1</title>
				<link>http://www.addedbytes.com/articles/writing-secure-php/writing-secure-php-1/</link>
				<description><![CDATA[ Learn how to avoid some of the most common mistakes in PHP, and so make your sites more secure. <p><a href="http://www.php.net">PHP</a> is a very easy language to learn, and many people without any sort of background in programming learn it as a way to add interactivity to their web sites. Unfortunately, that often means PHP programmers, especially those newer to web development, are unaware of the potential security risks their web applications can contain. Here are a few of the more common security problems and how to avoid them.</p>

<p>[Writing Secure PHP is a series. <a href="http://www.addedbytes.com/php/writing-secure-php-2/">Part 2</a>, <a href="http://www.addedbytes.com/php/writing-secure-php-3/">Part 3</a> and <a href="http://www.addedbytes.com/php/writing-secure-php-4/">Part 4</a> are currently also available.]</p>

<h3>Rule Number One: Never, Ever, Trust Your Users</h3>

<p>It can never be said enough times, you should never, ever, ever trust your users to send you the data you expect. I have heard many people respond to that with something like "Oh, nobody malicious would be interested in my site". Leaving aside that that could not be more wrong, it is not always a malicious user who can exploit a security hole - problems can just as easily arise because of a user unintentionally doing something wrong.</p>

<p>So the cardinal rule of all web development, and I can't stress it enough, is: <strong>Never, Ever, Trust Your Users</strong>. Assume every single piece of data your site collects from a user contains malicious code. Always. That includes data you think you have checked with client-side validation, for example using JavaScript. If you can manage that, you'll be off to a good start. If PHP security is important to you, this single point is the most important to learn. Personally, I have a "PHP Security" sheet next to my desk with major points on, and this is in large bold text, right at the top.</p>

<h3>Global Variables</h3>

<p>In many languages you must explicitly create a variable in order to use it. In PHP, there is an option, "register_globals", that you can set in php.ini that allows you to use global variables, ones you do not need to explicitly create. </p>

<p>Consider the following code:</p>

<pre class="php">if ($password == "my_password") {
    $authorized = 1;
}

if ($authorized == 1) {
    echo "Lots of important stuff.";
}</pre>

<p>To many that may look fine, and in fact this exact type of code is in use all over the web. However, if a server has "register_globals" set to on, then simply adding "?authorized=1" to the URL will give anyone free access to exactly what you do not want everyone to see. This is one of the most common PHP security problems.</p>

<p>Fortunately, this has a couple of possible simple solutions. The first, and perhaps the best, is to set "register_globals" to off. The second is to ensure that you only use variables that you have explicitly set yourself. In the above example, that would mean adding "$authorized = 0;" at the beginning of the script:</p>

<pre class="php">$authorized = 0;
if ($password == "my_password") {
    $authorized = 1;
}

if ($authorized == 1) {
    echo "Lots of important stuff.";
}</pre>

<h3>Error Messages</h3>

<p>Errors are a very useful tool for both programmer and hacker. A developer needs them in order to fix bugs. A hacker can use them to find out all sorts of information about a site, from the directory structure of the server to database login information. If possible, it is best to turn off all error reporting in a live application. PHP can be told to do this through .htaccess or php.ini, by setting "error_reporting" to "0". If you have a development environment, you can set a different error reporting level for that.</p>

<h3>SQL Injection</h3>

<p>One of PHP's greatest strengths is the ease with which it can communicate with databases, most notably <a href="http://www.mysql.com">MySQL</a>. Many people make extensive use of this, and a great many sites, including this one, rely on databases to function.</p>

<p>However, as you would expect, with that much power there are potentially huge security problems you can face. Fortunately, there are plenty of solutions. The most common security hazard faced when interacting with a database is that of SQL Injection - when a user uses a security glitch to run SQL queries on your database.</p>

<p>Let's use a common example. Many login systems feature a line that looks a lot like this when checking the username and password entered into a form by a user against a database of valid username and password combinations, for example to control access to an administration area:</p>

<pre class="php">$check = mysql_query("SELECT Username, Password, UserLevel FROM Users WHERE Username = '".$_POST['username']."' and Password = '".$_POST['password']."'");</pre>

<p>Look familiar? It may well do. And on the face of it, the above does not look like it could do much damage. But let's say for a moment that I enter the following into the "username" input box in the form and submit it:</p>

<pre class="php">' OR 1=1 #</pre>

<p>The query that is going to be executed will now look like this:</p>

<pre class="sql">SELECT Username, Password FROM Users WHERE Username = '' OR 1=1 #' and Password = ''</pre>

<p>The hash symbol (#) tells MySQL that everything following it is a comment and to ignore it. So it will actually only execute the SQL up to that point. As 1 always equals 1, the SQL will return all of the usernames and passwords from the database. And as the first username and password combination in most user login databases is the admin user, the person who simply entered a few symbols in a username box is now logged in as your website administrator, with the same powers they would have if they actually knew the username and password.</p>

<p>With a little creativity, the above can be exploited further, allowing a user to create their own login account, read credit card numbers or even wipe a database clean.</p>

<p>Fortunately, this type of vulnerability is easy enough to work around. By checking for apostrophes in the items we enter into the database, and removing or neutralising them, we can prevent anyone from running their own SQL code on our database. The function below would do the trick:</p>

<pre class="php">function make_safe($variable) {
    $variable = mysql_real_escape_string(trim($variable));
    return $variable;
}</pre>

<p>Now, to modify our query. Instead of using _POST variables as in the query above, we now run all user data through the make_safe function, resulting in the following code:</p>

<pre class="php">$username = make_safe($_POST['username']);
$password = make_safe($_POST['password']);
$check = mysql_query("SELECT Username, Password, UserLevel FROM Users WHERE Username = '".$username."' and Password = '".$password."'");</pre>

<p>Now, if a user entered the malicious data above, the query will look like the following, which is perfectly harmless. The following query will select from a database where the username is equal to "\' OR 1=1 #".</p>

<pre class="sql">SELECT Username, Password, UserLevel FROM Users WHERE Username = '\' OR 1=1 #' and Password = ''</pre>

<p>Now, unless you happen to have a user with a very unusual username and a blank password, your malicious attacker will not be able to do any damage at all. It is important to check all data passed to your database like this, however secure you think it is. HTTP Headers sent from the user can be faked. Their referral address can be faked. Their browsers User Agent string can be faked. Do not trust a single piece of data sent by the user, though, and you will be fine.</p>

<h3>File Manipulation</h3>

<p>Some sites currently running on the web today have URLs that look like this:</p>

<pre class="php">index.php?page=contactus.html</pre>

<p>The "index.php" file then simply includes the "contactus.html" file, and the site appears to work. However, the user can very easily change the "contactus.html" bit to anything they like. For example, if you are using <a href="http://www.apache.org/">Apache</a>'s mod_auth to protect files and have saved your password in a file named ".htpasswd" (the conventional name), then if a user were to visit the following address, the script would output your username and password:</p>

<pre class="php">index.php?page=.htpasswd</pre>

<p>By changing the URL, on some systems, to reference a file on another server, they could even run PHP that they have written on your site. Scared? You should be. Fortunately, again, this is reasonably easy to protect against. First, make sure you have correctly set "open_basedir" in your php.ini file, and have set "allow_url_fopen" to "off". That will prevent most of these kinds of attacks by preventing the inclusion of remote files and system files. Next, if you can, check the file requested against a list of valid files. If you limit the files that can be accessed using this script, you will save yourself a lot of aggravation later.</p>

<h3>Using Defaults</h3>

<p>When MySQL is installed, it uses a default username of "root" and blank password. SQL Server uses "sa" as the default user with a blank password. If someone finds the address of your database server and wants to try to log in, these are the first combinations they will try. If you have not set a different password (and ideally username as well) than the default, then you may well wake up one morning to find your database has been wiped and all your customers' credit card numbers stolen. The same applies to all software you use - if software comes with default username or password, change them.</p>

<h3>Leaving Installation Files Online</h3>

<p>Many PHP programs come with installation files. Many of these are self-deleting once run, and many applications will refuse to run until you delete the installation files. Many however, will not pay the blindest bit of attention if the install files are still online. If they are still online, they may still be usable, and someone may be able to use them to overwrite your entire site.</p>

<h3>Predictability</h3>

<p>Let us imagine for a second that your site has attracted the attention of a Bad Person. This Bad Person wants to break in to your administration area, and change all of your product descriptions to "This Product Sucks". I would hazard a guess that their first step will be to go to http://www.yoursite.com/admin/ - just in case it exists. Placing your sensitive files and folders somewhere predictable like that makes life for potential hackers that little bit easier.</p>

<p>With this in mind, make sure you name your sensitive files and folders so that they are tough to guess. Placing your admin area at http://www.yoursite.com/jsfh8sfsifuhsi8392/ might make it harder to just type in quickly, but it adds an extra layer of security to your site. Pick something memorable by all means if you need an address you can remember quickly, but don't pick "admin" or "administration" (or your username or password). Pick something unusual.</p>

<p>The same applies to usernames and passwords. If you have an admin area, do not use "admin" as the username and "password" as the password. Pick something unusual, ideally with both letters and numbers (some hackers use something called a "dictionary attack", trying every word in a dictionary as a password until they find a word that works - adding a couple of digits to the end of a password renders this type of attack useless). It is also wise to change your password fairly regularly (every month or two).</p>

<p>Finally, make sure that your error messages give nothing away. If your admin area gives an error message saying "Unknown Username" when a bad username is entered and "Wrong Password" when the wrong password is entered, a malicious user will know when they've managed to guess a valid username. Using a generic "Login Error" error message for both of the above means that a malicious user will have no idea if it is the username or password he has entered that is wrong.</p>

<h3>Finally, Be Completely and Utterly Paranoid</h3>

<p>If you assume your site will never come under attack, or face any problems of any sort, then when something eventually does go wrong, you will be in massive amounts of trouble. If, on the other hand, you assume every single visitor to your site is out to get you and you are permanently at war, you will help yourself to keep your site secure, and be prepared in case things should go wrong.</p>

<p><em>Ready for more? Try <a href="http://www.addedbytes.com/security/writing-secure-php-2/">Writing Secure PHP, Part 2</a>.</em></p> <br><br>]]></description>
				<pubDate>Fri, 16 Jul 2004 10:07:15 +0100</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/articles/writing-secure-php/writing-secure-php-1/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=code&amp;start=0" class="ditto_tag" rel="tag">code</a>,<a href="/feeds/tag-feed/?tags=coding&amp;start=0" class="ditto_tag" rel="tag">coding</a>,<a href="/feeds/tag-feed/?tags=development&amp;start=0" class="ditto_tag" rel="tag">development</a>,<a href="/feeds/tag-feed/?tags=mysql&amp;start=0" class="ditto_tag" rel="tag">mysql</a>,<a href="/feeds/tag-feed/?tags=php&amp;start=0" class="ditto_tag" rel="tag">php</a>,<a href="/feeds/tag-feed/?tags=programming&amp;start=0" class="ditto_tag" rel="tag">programming</a>,<a href="/feeds/tag-feed/?tags=security&amp;start=0" class="ditto_tag" rel="tag">security</a>,<a href="/feeds/tag-feed/?tags=tips&amp;start=0" class="ditto_tag" rel="tag">tips</a>,<a href="/feeds/tag-feed/?tags=tutorial&amp;start=0" class="ditto_tag" rel="tag">tutorial</a>,<a href="/feeds/tag-feed/?tags=web&amp;start=0" class="ditto_tag" rel="tag">web</a>,<a href="/feeds/tag-feed/?tags=webdesign&amp;start=0" class="ditto_tag" rel="tag">webdesign</a>,<a href="/feeds/tag-feed/?tags=webdev&amp;start=0" class="ditto_tag" rel="tag">webdev</a>
			</item>

			<item>
				<title>The Box Model For Beginners</title>
				<link>http://www.addedbytes.com/articles/for-beginners/the-box-model-for-beginners/</link>
				<description><![CDATA[ An explanation of what the box model is and how it is treated by different user agents. <p>The term "box model" is often used by people when talking about CSS-based layouts and design. Not everyone understands what is meant by this though, and not everyone understands why it is so important.</p>

<p>Any HTML element can be considered a box, and so the box model applies to all HTML (and XHTML) elements.</p>

<p>The box model is the specification that defines how a box and its attributes relate to each other. In its simplest form, the box model tells browsers that a box defined as having width 100 pixels and height 50 pixels should be drawn 100 pixels wide and 50 pixels tall.</p>

<p>There is more you can add to a box, though, like padding, margins, borders, etc. This image should help explain what I'm about to run through:</p>

<p style="text-align:center;"><img src="content/box-model/box.png" alt="Outline of box model" /></p>

<p>As you can see, a box is made up of four distinct parts. The outside one, the margin, is completely invisible. It has no background color, and will not obstruct elements behind it. The margin is outside the second part, which is the border. The border outlines the visible portion of the element. Inside the border is the third part of the box, the padding, and then inside that the content area of the box. The padding defines the space between the content area of the box and the border.</p>

<p>(Note that in the image above, the only border of the three drawn that would actually be visible is the solid line - the dashed lines are added to help demonstrate the box model).</p>

<p>When you define a width and a height for your box using CSS, you are defining not the entire area taken up by the content, padding, border and margin. You are actually just defining the content area itself - the bit right in the middle. The padding, border and margin must be added to that in order to calculate the total space occupied by the box. (From this point on, we will use width for demonstrations, but the same principles apply to both width and height).</p>

<code>box {
    width: 200px;
    border: 10px solid #99c;
    padding: 20px;
    margin: 20px;
}</code>

<p>The above CSS, applied to a box, would mean that that box occupied 300 pixels of space horizontally on the page. The content of the box would occupy 200 pixels of that (dashed line added to demonstrate the edge of the area occupied by the box):</p>

<p style="text-align:center;"><img src="content/box-model/box_demo.png" alt="Box model demonstration." /></p>

<p>In the above image, you can see that the pale blue area is 240 pixels wide (200 pixels of content plus 20 pixels padding either side). The border is 10 pixels wide either side, making the total width including the border 260 pixels. The margin is 20 pixels either side, making the total width of the box 300 pixels.</p>

<p>In practice, this can cause some confusion. For example, if I have a 100 pixel wide space available, and want to fill it with a pale red box with a dark red border and a small amount of padding, it would be very easy to write the CSS like so:</p>

<code>box {
    width: 100px;
    border: 1px solid #900;
    padding: 10px;
    margin: 0;
    background: #fee;
}</code>

<p>(A declaration of 0, as used for the margin above, does not require a unit to be added. Any value other than 0 does require a unit, e.g. px for pixels. Also, although "background" is defined as a shorthand property, it is more widely supported than the more correct "background-color".)</p>

<p>However, that will not give us a 100 pixel wide box, as the width declaration defines the content area of the box. The content area of the box will be 100 pixels - the total width of the box as defined above will be 122 pixels:</p>

<p style="text-align:center;"><img src="content/box-model/box_demo2.png" alt="Box model demonstration." /></p>

<p>In order to set the above box to only occupy 100 pixels horizontally, you would need to set the width of the content area to be 100 pixels minus the padding and minus the border, in this case 78 pixels, like so:</p>

<code>box {
    width: <strong>78px</strong>;
    border: 1px solid #900;
    padding: 10px;
    margin: 0;
    background: #fee;
}</code>

<p>To calculate the overall width of a box, including all padding, borders and margins, you would use the following formula:</p>

<code>total box width = content area width + left padding + right padding + left border + right border + left margin + right margin</code>

<h3>Compatibility</h3>

<p>At this point, you should now have a good understanding of what the box model is, and how boxes <em>should</em> be treated by different browsers. However, as you will soon learn (if you did not know already), not every browser does as it is supposed to. In order to use boxes, and by extension make the most of CSS in your website, you will need to be aware of how the different browsers treat boxes in practice and how to overcome and work around the problems presented by these idiosyncrasies.</p>

<h3>Top Notch</h3>

<p><img src="images/browser_logos/opera6.gif" alt="Opera 6" /> <img src="images/browser_logos/opera7.gif" alt="Opera 7" /> <img src="images/browser_logos/mozilla.gif" alt="Mozilla" /> <img src="images/browser_logos/firefox.gif" alt="Firefox" /> <img src="images/browser_logos/camino.gif" alt="Camino" /> <img src="images/browser_logos/safari.gif" alt="Safari" /> <img src="images/browser_logos/konqueror.gif" alt="Konqueror" /> <img src="images/browser_logos/netscape6.gif" alt="Netscape 6" /> <img src="images/browser_logos/netscape7.gif" alt="Netscape 7" /> <img src="images/browser_logos/ie6.gif" alt="Internet Explorer 6" /></p>

<p>Most browsers released in the last few years have no problem with boxes and render boxes correctly. Opera 6 and 7, Mozilla 1 (and by extension other browsers based on the Gecko engine like Netscape 7, Camino and Firefox and other derivatives), Safari, Konquerer (and derivatives) and Internet Explorer 5 for the Mac are all shining examples of how a web browser <em>should</em> behave, all rendering boxes flawlessly. IE 6 for Windows also will render a box correctly, as long as the [url=http://www.addedbytes.com/design/dtds-explained]Document Type Definition[/url] for the page is correct.</p>

<h3>Whoops, Mrs Miggins, You're Sitting On My Artichokes</h3>

<p><img src="images/browser_logos/ie5.gif" alt="Internet Explorer 5" /> <img src="images/browser_logos/ie6.gif" alt="Internet Explorer 6" /></p>

<p>Some browsers don't display a box correctly. Unlike those below here, these browsers are widely enough used on the web that it is usually worth the effort to work through the problem. There are various methods for doing this, some better than others, that follow on. Most notable among the browsers with problems are Internet Explorers 4 and 5 and Internet Explorer 6. IE 6 is easy to work around, by adding a correct DTD (which you should be doing anyway).</p>

<p>Internet Explorer 5 is the main reason there is a box model problem at all. It, unfortunately, does not follow the simple definition for box layout as defined by the W3c. When you define a width for a box and it is rendered in IE5, instead of that width defining the content area of the box, it <em>includes the borders and padding</em>. Margins are added on to the content width correctly, but padding and borders are not. Unfortunately, this leaves us with some unpleasant choices:</p>

<ol><li><strong>Use a box model hack</strong><br />
Hack's like [url=http://www.tantek.com/CSS/Examples/boxmodelhack.html]Tantek's box model hack[/url] are unfortunately something of a necessity. While some might argue that using hacks like this is completely missing the point of using CSS for web design, commercial necessity and the prevalence of IE5 leave us with little in the way of choice. The IE5 box model hack is in use all over the web and has spawned plenty of variants.</li><li><strong>Add in extra code</strong><br />
Some might consider this a slightly "better" way of working around this problem. Rather than adding a style sheet hack, you can nest elements within each other. Adding a div within another div means that rather than using padding, you can use just margins, which are handled correctly by IE5. As with the box model hack, it is far from a perfect solution, but there are few other options if you want a site to look the same in IE5 as other more capable browsers.</li></ol>

<h3>Hall of Shame</h3>

<p><img src="images/browser_logos/ie4.gif" alt="Internet Explorer 4" /> <img src="images/browser_logos/netscape4.gif" alt="Netscape 4" /></p>

<p>On the one hand, the browsers that I am about to mention are appalling, all failing dismally to render a simple box correctly for one reason or another. On a more positive note, users of these browsers, mostly old versions of current browsers, make up an extremely small, and continually shrinking, portion of web users. While you could probably find a workaround for the bugs in the display of boxes in these browsers, it is almost certainly not worth the effort - you are likely to cause yourself more harm than good with workarounds for these!</p>

<p>Netscape 4's box model is awful, but even worse, the simple box model hacks to fix the problem for IE5 and IE6 will crash Netscape 4. Netscape 4's style sheet support is abysmal overall, and it is being supported less and less. Though it is strictly a personal choice, I don't think it is worth the time and effort to support Netscape 4 any more - it's just not used enough, and the number of users is only ever going to shrink.</p>

<p>Internet Explorer 4 suffers, basically, the same problem as IE5. It treats boxes in a very similar way. However, it falls over in far more ways, and many of the available hacks will crash IE4. As it is also used by few people, and that number is dropping, many designers ignore it.</p>

<h3>What does the future hold?</h3>

<p>CSS3 promises us the option to determine how we want the user agent to treat boxes, and specify which box model we want to use. Support for CSS3 at a level that will be possible is many many years away yet. Until then, we are stuck with the CSS2 box model, and while IE5 is still used by a significant percentage of the web's population, we are going to have problems with boxes.</p> <br><br>]]></description>
				<pubDate>Fri, 09 Jul 2004 11:48:54 +0100</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/articles/for-beginners/the-box-model-for-beginners/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=box&amp;start=0" class="ditto_tag" rel="tag">box</a>,<a href="/feeds/tag-feed/?tags=boxmodel&amp;start=0" class="ditto_tag" rel="tag">boxmodel</a>,<a href="/feeds/tag-feed/?tags=css&amp;start=0" class="ditto_tag" rel="tag">css</a>,<a href="/feeds/tag-feed/?tags=design&amp;start=0" class="ditto_tag" rel="tag">design</a>,<a href="/feeds/tag-feed/?tags=html&amp;start=0" class="ditto_tag" rel="tag">html</a>,<a href="/feeds/tag-feed/?tags=model&amp;start=0" class="ditto_tag" rel="tag">model</a>,<a href="/feeds/tag-feed/?tags=reference&amp;start=0" class="ditto_tag" rel="tag">reference</a>,<a href="/feeds/tag-feed/?tags=tips&amp;start=0" class="ditto_tag" rel="tag">tips</a>,<a href="/feeds/tag-feed/?tags=tutorial&amp;start=0" class="ditto_tag" rel="tag">tutorial</a>,<a href="/feeds/tag-feed/?tags=webdesign&amp;start=0" class="ditto_tag" rel="tag">webdesign</a>,<a href="/feeds/tag-feed/?tags=webdev&amp;start=0" class="ditto_tag" rel="tag">webdev</a>
			</item>

			<item>
				<title>28k and 56k Modem Emulator</title>
				<link>http://www.addedbytes.com/blog/code/modem-emulator/</link>
				<description><![CDATA[ Regardless of your connection speed, this will show you how your site loads on PCs with older connections. <p><strong><span style="color: #f00;">PLEASE NOTE:</span> This tool has been taken offline and the code has been released as an open source project: <a href="http://code.google.com/p/modem-emulator/">modem-emulator</a>. There's some <a href="http://www.addedbytes.com/blog/modem-emulator-open-sourced/">background on the change here</a>.</strong></p>

<p>Some designers have taken the rise of broadband to mean that graphic intensive pages are now acceptable, that 600k Flash intros are suddenly desirable, and that otherwise bombarding the user with bandwidth-hungry sites is commendable. Sadly, plenty of users are still on dial-up, using 28k, 33.6k or 56k modems, and it's all too easy to forget that when you're surfing on a high speed office connection or even your home broadband.</p>

<p>With that in mind, I've put together a <del>modem emulator (or is it a modem simulator?)</del> <ins>throughput throttling proxy (<a href="http://www.addedbytes.com/resources/modem-emulator/comments/#comment18">apparently</a>)</ins>. In theory it should allow you to view your site through the eyes of a user with a slower connection. In practice, it isn't perfect, but might give you an idea of how some of your users actually experience your site.</p>

<p>A word of warning as well - the tool is tested (though not extensively) with sites that I use or have built. There will be unusual sites that don't work with this tool (flash is so far untested for example). Please <a href="mailto:dave@addedbytes.com">email me</a> if you have any problems.</p>

<p>The emulator suffered a great deal of abuse in the past, mainly by people wanting to bypass work internet filters. Unfortunately, that has meant that I have had to add a few features to the tool. The primary change, for my own sanity, is a blacklist of URLs. I hope to not have to change this to a whitelist, but that option is available should the need arise.</p>

<p>To use it, simply enter your URL and the speed you'd like to see the site go, and the script will show you the page desired loading as it would on a slower connection.</p>

<p><em>The tool has been taken offline, and the code has been released under an open source license. There's some <a href="http://www.addedbytes.com/blog/modem-emulator-open-sourced/">background on the change here</a>.</em></p>

<p>Finally, someone is bound to ask, so to save myself the time answering later - no, this cannot show you how your site will load on a faster connection than you have yourself :).</p>

<h3>Update 29 December 2006</h3>

<p>The emulator has been tentatively reinstated with some features to enable me to manage it.</p> <br><br>]]></description>
				<pubDate>Tue, 29 Jun 2004 01:12:00 +0100</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/blog/code/modem-emulator/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=accessibility&amp;start=0" class="ditto_tag" rel="tag">accessibility</a>,<a href="/feeds/tag-feed/?tags=design&amp;start=0" class="ditto_tag" rel="tag">design</a>,<a href="/feeds/tag-feed/?tags=development&amp;start=0" class="ditto_tag" rel="tag">development</a>,<a href="/feeds/tag-feed/?tags=modem&amp;start=0" class="ditto_tag" rel="tag">modem</a>,<a href="/feeds/tag-feed/?tags=optimization&amp;start=0" class="ditto_tag" rel="tag">optimization</a>,<a href="/feeds/tag-feed/?tags=testing&amp;start=0" class="ditto_tag" rel="tag">testing</a>,<a href="/feeds/tag-feed/?tags=tools&amp;start=0" class="ditto_tag" rel="tag">tools</a>,<a href="/feeds/tag-feed/?tags=usability&amp;start=0" class="ditto_tag" rel="tag">usability</a>,<a href="/feeds/tag-feed/?tags=web&amp;start=0" class="ditto_tag" rel="tag">web</a>,<a href="/feeds/tag-feed/?tags=webdesign&amp;start=0" class="ditto_tag" rel="tag">webdesign</a>,<a href="/feeds/tag-feed/?tags=webdev&amp;start=0" class="ditto_tag" rel="tag">webdev</a>
			</item>

			<item>
				<title>Faux Columns for Liquid Layouts</title>
				<link>http://www.addedbytes.com/blog/code/faux-columns-for-liquid-layouts/</link>
				<description><![CDATA[ Using CSS for layouts can be a problem when using backgrounds for two columns that are not of equal length. This article expands on the solution to this problem from AListApart. <p>In January of 2004, <a href="http://simplebits.com/">Dan Cederholm</a> (author of <a href="http://www.amazon.co.uk/exec/obidos/ASIN/1590593812/tooyoo-21">Web Standards Solutions</a>) posted an article on <a href="http://www.alistapart.com">AListApart</a> entitled "<a href="http://www.alistapart.com/articles/fauxcolumns/">Faux Columns</a>". In it, he explained how designers can overcome a common problem in CSS-based designs.</p>

<p>The problem is one that usually rears its ugly head with two and three column designs (though for now, we'll just worry about two columns). If your two columns each have a different background color, how do you make the colours extend to the bottom of the page using css? Equal height columns are difficult to achieve using height and overflow properties. Each column will be of a different height, and you do not always know which is the taller of the two. It is all too easy to end up with a site where one column just doesn't extend all the way to the bottom of the page, where it should end.</p>

<p>CSS does actually include a rather nifty little tool that can be used to work around this problem, the "min-height" declaration, that allows you to specify a minimum height for an element - which you can use to ensure that one specific column is always larger than the other, allowing you to avoid this problem. Unfortunately (and perhaps unsurprisingly) Internet Explorer does not support this declaration, so in practice it isn't a useful solution to the problem.</p>

<p>Dan, in his article (which if you haven't read yet, I suggest you do before continuing), outlines a solution he uses on his own site. This solution involves tiling a background on the page, to give the appearance that there are distinct columns that extend the full length of the page. It's a simple but clever solution, and can be seen in use on a great many sites on the web.</p>

<p>During the recent redesign of this site, though, I came across a small problem. Though Dan's solution is perfect for fixed-width layouts, it just wouldn't work with a percentage-based, liquid layout. The problem was simple - a graphic cannot alter itself based upon the user's screen. If you come up with a background image like the below, and tile it on a page, the left hand column will need to be 200 pixels wide. If your column is 20% of the page, though, that could make it anything from 20 to 2000 pixels - and as a result your columns will rarely look as you intended. This makes equal height columns in liquid layouts a tricky proposal.</p>

<p>However, Dan's solution can be used to apply a background to a page when the layout is liquid, using background positioning.</p>

<p>Background positioning can allow us to give our background the appearance of being liquid. When you positioning a background using pixels, you position the top left corner of the image. When you position a background using percentages or keywords, you don't. Instead, you position a <em>point within the image itself</em>. For example, let's say we have a page and a simple background image. We use the following to set and position the background:</p>

<code>body {
    background-image: url("image.gif");
    background-repeat: no-repeat;
    background-position: 25% 10%;
}</code>

<p>The above will set "image.gif" as the background of the page. It will position the background 25% of the way across the page from the left, and 10% of the way down the page from the top. However, it is not the left hand corner that will appear at that point. It is the point 25% from the left hand side of the background image and 10% from the top that will appear at that point, like so:</p>

<p style="text-align: center;"><img src="content/faux-columns-for-liquid-layouts/faux-example.gif" alt="Example of background positioning based upon percentages" /></p>

<p>We can use this to apply a background to a page that will give the illusion of a pair of columns, even though the columns are not of a fixed width. Let's say we have two columns (for now), of 25% and 75% width. We can create a simple image, 1 pixel tall by 2000 pixels wide (why so wide will become apparent shortly - but don't be afraid to go even larger if you wish - 4000 pixels wouldn't necessarily be a bad thing). We want the left column to be a nice shade of orange, and the right a nice shade of grey, with a black line to divide them. So the image needs to have a black line 25% of the way along, with everything to the left orange and everything to the right grey, like so (scaled for visibility):</p>

<p style="text-align: center;"><img src="content/faux-columns-for-liquid-layouts/faux-example2.gif" alt="Example of background image" /></p>

<p>Now, we position the background using the following CSS:</p>

<code>body {
    background-image: url("background.gif");
    background-repeat: repeat-y;
    background-position: 25% 0;
}</code>

<p>Now, if you were to draw a line down the page, 25% of the way across from the left hand side, then 25% of our background image would be to the left of that line and 75% to the right. If we use the 2000 pixel wide background mentioned earlier, and position it as above, we'll have an orange background for 25% of the page, a black line, then grey will fill the remaining 75% of the page. You can <a href="http://www.addedbytes.com/content/faux-columns-for-liquid-layouts/faux1.html">see an example of that here</a>. If you resize your browser window, while viewing the example, you will see the columns expand and contract to maintain the same proportions of the columns. With a little imagination, and the use of partly transparent background images, you can create image borders between elements using the same technique.</p>

<p>A little markup and a little more CSS, and we can turn the above into a respectable liquid page, with columns that expand and contract with the users' windows, and always extend just as far as they are needed. A <a href="http://www.addedbytes.com/content/faux-columns-for-liquid-layouts/faux2.html">more complete example is here</a>, and this technique is also in use at this very site [please note that this technique is in use in versions 3, 4 and 5 of this site, accessible through the footer], allowing the flexible navigation and content columns to always appear equal in length, despite the fact they almost never are.</p> <br><br>]]></description>
				<pubDate>Tue, 22 Jun 2004 17:31:13 +0100</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/blog/code/faux-columns-for-liquid-layouts/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=css&amp;start=0" class="ditto_tag" rel="tag">css</a>,<a href="/feeds/tag-feed/?tags=design&amp;start=0" class="ditto_tag" rel="tag">design</a>,<a href="/feeds/tag-feed/?tags=faux&amp;start=0" class="ditto_tag" rel="tag">faux</a>,<a href="/feeds/tag-feed/?tags=fluid&amp;start=0" class="ditto_tag" rel="tag">fluid</a>,<a href="/feeds/tag-feed/?tags=hacks&amp;start=0" class="ditto_tag" rel="tag">hacks</a>,<a href="/feeds/tag-feed/?tags=html&amp;start=0" class="ditto_tag" rel="tag">html</a>,<a href="/feeds/tag-feed/?tags=layout&amp;start=0" class="ditto_tag" rel="tag">layout</a>,<a href="/feeds/tag-feed/?tags=liquid&amp;start=0" class="ditto_tag" rel="tag">liquid</a>,<a href="/feeds/tag-feed/?tags=reference&amp;start=0" class="ditto_tag" rel="tag">reference</a>,<a href="/feeds/tag-feed/?tags=tutorial&amp;start=0" class="ditto_tag" rel="tag">tutorial</a>,<a href="/feeds/tag-feed/?tags=web&amp;start=0" class="ditto_tag" rel="tag">web</a>,<a href="/feeds/tag-feed/?tags=webdesign&amp;start=0" class="ditto_tag" rel="tag">webdesign</a>
			</item>
	</channel>
</rss>