What DPI do web images need to be? (spoiler alert: it doesn’t matter)


If you’ve ever had to communicate with someone about creating/resizing images for the web, I’ll bet you’ve heard a lot about “72 DPI”. As in, “images for the web should be 72 DPI while images for print should be at least 300 DPI”. You might even think it’s true.

Friends, I’m here to put the 72 DPI myth to rest.

If you’re sitting here thinking “WTF is DPI?” or “Is DPI the same as PPI?” or “Why, oh why, are there so many acronyms in the world?”, DPI stands for “dots per inch”, and PPI stands for “pixels per inch”. The term DPI is generally used for printed images since printed images are made up of tiny dots, while the term PPI is mostly used for screens, since screens contain pixels. They’re quite similar, and people often use them interchangeably, which is a little confusing, so don’t worry about it for now. Let’s think of them interchangeably for our purposes.

Now, let me show you three images from Placekitten, aka the best site ever. One is at 72 DPI, one is at 300 DPI, and one is at 1000 DPI:

72 DPI

72 DPI

300 DPI

300 DPI

1000 DPI

1000 DPI

Don’t believe me? Download them and open them in Photoshop. Take your time. I’ll be here!

Craziness! How could this be?

All you have to do is look back to what the acronym actually stands for: pixels/dots per inch. This refers to how many pixels/dots are squeezed into one inch of space on a printed page. Two images with the same pixel value (let’s say, 1000 pixels wide) will print at very different sizes depending on the set DPI. That image at 72 DPI will be 13.88 inches wide, while that same image at 300 DPI will be 3.33 inches wide. It’s just basic math. All DPI does is determine how many pixels your printer is going to cram into one inch of space on the page. That’s why a higher DPI image looks better than a lower DPI image – the more pixels you squeeze into a small area, the finer the detail in your printed image.

Remember the three images I showed you above with different DPI values that look exactly the same on the web? Here’s what they’d look like printed:

72 DPI

72 DPI

300 DPI

300 DPI

1000 DPI

1000 DPI

Ahhh, so image DPI does matter… but only if you’re printing it out.

So, how does this relate to the web, again?

Trick question – it doesn’t. Look back up again at the three original kitties – their size doesn’t change at all on your screen, because your screen understands one measurement: pixels. Pixels are all you ever need to think about. To determine how big an image should be on your website, you have to know what size in pixels it needs to fill. Your designer/developer should tell you something like “please make sure that images for this particular section of your website are X pixels wide.” The target size of your image is determined by the size of the container it needs to fill, and that measurement is different from website to website (or even in different parts of the same website), so the person who created your website (or your theme documentation, if you’re using a pre-made theme) will be able to tell you what size you should be aiming for. In pixels. Just pixels.

Hey, what about retina displays?

Glad you asked! Retina displays, also known as “high DPI” displays, are awesome in that they cram more pixels into their screens than standard displays. This means that each individual pixel is even smaller so you get a much sharper image than on a standard screen. So doesn’t image DPI matter now? Doesn’t it?

Nope. All you really need to know is that if you’re optimizing for a retina display that’s squishing double the number of pixels into the same area as a non-retina display would, you need to double the pixels in your image so it still appears crisp. So, a logo that’s 300px across normally should be saved at 600px. Then, when that image is presented at 300px as originally intended, it’ll look nice and crisp on retina screens since the image has double the number of pixels and so does the screen. The DPI/PPI setting in Photoshop is still irrelevant because you’re not printing it out.

If in doubt, remember that on the web, it’s all about the pixels. Unless you’re using a vector format like SVG, in which case, high five. You’re awesome.

Want more articles like this? Get ’em in your inbox!

Reflections on a year of pricing projects


Pricing your products or services can be pretty hard, right? I’m guessing that most self-employed people can relate to this, especially at the beginning of their careers. How much is too little? Too much? Do you charge an hourly rate? A fixed rate based on estimated time? A fixes rate based on value? Of course, as we all know deep down, there are no clear answers to these questions, and everyone does things a little bit differently anyway.

I’ve been running my business full time for almost a year now (!) so I’ve had a bit of time to try different things. After accumulating almost year of data on pricing my projects, I finally put it all together last week and analyzed it by taking each project and comparing how much time I estimated it would take, how long it actually took, how much I charged, and how much I really made per hour I worked on it.

What I found… was a little surprising.

First, a brief note on how I priced my projects this past year

About a year before I went full-time, I started to use fixed pricing based on time instead of billing by the hour, which is how I started off. That means that I would imagine how long the project would take, multiply it by an appropriate hourly rate, and that would be the price. If a project took less time than I’d anticipated, hurray! If it took more time, then oh well, my fault for estimating poorly.

This past year, I took a fairly similar approach, but with a couple of refinements. Instead of scoping each project from scratch, I created an internal price sheet to save myself some time when quoting similar projects, and I used a multiplier for complexity. When I got the sense that some projects would be more challenging than others (for whatever reason), I bumped up my quote, knowing that they were likely to take more of my time and energy. At this point I’m really interested in value based pricing, and am currently working on implementing that in my business.

And now, my main takeaways

Track your time like your life depends on it

When you’re charging fixed prices, tracking your time can feel like frivolous pain in the ass. But, if you don’t, you won’t have the proper data to refine your business practices, and every pricing change you make will be based on guesses. That’s no good! When I worked at Jet Cooper, I was sometimes a little lax about my time tracking, and I feel badly about it now that I understand how important it is. SORRY, GUYS!

I use a really simple app called TimeKeeper, which lets me tag every time entry both by project and by task type. It’s almost perfect for my purposes, aside from the fact that it doesn’t sync to Dropbox automatically. C’mon, TimeKeeper devs! Get on it! (Plz?)

Coding my own designs takes way less time than coding someone else’s

I take on two main types of projects: full websites (design and development) and development only. When I was putting my price list together, I came up with base prices for design and base prices for development, which seemed to make sense at the time. This means that I was scoping developing my own designs exactly the same way I scoped developing other people’s designs.


After “crunching the numbers”, as they say, I found out that sites I designed and developed sometimes earned up to three times more per hour worked than developing sites by other designers. That, friends, was pretty shocking, though when I think about it, it really shouldn’t have been. I didn’t take the additional complexity of working with another person into consideration, and I didn’t think about the fact that I would never design something that I knew was impossible (or just irritating) to code, so I would never be putting myself in a difficult development situation. If that wasn’t enlightening enough, I then found out that…

The least fun projects were generally the most lucrative

Wait, what?!

This really surprised me when I saw this pattern, but then I thought about it for 5 seconds and realized that it actually makes a bunch of sense. I think we all have a tendency to overestimate the time and difficulty of something we’re not as enthusiastic about, and underestimate the things that sound like fun. Though this is a totally natural thing to do, it essentially means that we’re rewarding ourselves for taking on projects that we’re not too fond of. That’s a little backwards, isn’t it? Oops!

In conclusion…

When you’re running your own business, every day is an opportunity to learn something! Also… track your damn time.

Developer Tip Tuesday: Always develop locally (part 2)

Part 2: Software!

At last! The very long-awaited (oops) sequel to my previous post about why it’s so important to develop websites locally. In my first post I gave you the theory, and in this one I’ll give you some more practical information.

This post is going to focus on developing WordPress sites, because if you’re developing something more complicated than that, you probably already know enough about local development, do everything via command line, and don’t really need me! ;D

Running the local server

As you’ve probably already figured out, WordPress is written in PHP, which is a server-side language. This means that the website has to communicate with a server in order to display the pages, unlike a static HTML website. WordPress, like most content management systems, separates the site’s structure (which is PHP-based) from its content (which is stored in a MySQL database). The server is what brings the two together, and this is why you need a server with PHP and MySQL to run WordPress.

I personally run my local servers by using a program called MAMP. The WordPress Codex (aka your new best friend) has a good article about how to set up WordPress with MAMP. If you’re not using a Mac, you can use XAMPP for Windows, which works similarly. If the Codex is a little too dry and/or confusing, there’s a great screencast over at CSS Tricks on this very topic! Essentially, MAMP (or XAMPP or one of the other alternatives) sets up Apache, MySQL and PHP on your computer, which lets you run a local server that you can access, but that isn’t online for everyone else to see.

One drawback of the free version MAMP is that you can only have one local server running at once, and its address is always localhost:8888, which can be fairly limiting, especially if you’ve taken on multiple projects at once (story of my life). If you’re going to be developing locally a lot, I’d recommend shelling out for MAMP Pro, which lets you run an unlimited number of local servers and name them whatever you want. I use MAMP Pro, and all of my local sites are named [sitename].dev. These local URLs are really easy to remember, and way sexier than localhost:8888… am I right?

Edit! Thanks to @Wordius on Twitter for reminding me that even in regular (free) MAMP, you can have an unlimited number of sites — they’ll all just reside at http://localhost:8888/[insertsitenamehere]. I prefer having separate local domains for each installation for a variety of reasons, but it’s not entirely necessary, especially if you’re just starting out.

This is my MAMP screen, and to the left are the zillions of local installations I have set up right now (including a local version of my own website, where I test all of my changes first before they go live). And no, don't worry, I'm not working on them all at once!

This is my MAMP screen, and to the left are the zillions of local installations I have set up right now (including a local version of my own website, where I test all of my changes first before they go live). And no, I’m not working on them all at once! I might be crazy, but not thaaaat crazy.

I’ve recently heard of another (free) program called AMPPS that provides similar functionality to MAMP. I haven’t tried it myself, but it may be worth looking into. If you’ve used it, let me know what you think!

Developing the actual site

As I mentioned in my previous post, one of the biggest advantages of coding locally is being able to use a nice text editor with syntax highlighting to do your work (as opposed to the horrors of the WordPress built-in editor), which lets you easily undo any catastrophic changes that you may or may not make. The best part about developing locally is that you’re never breaking anything that anyone else will see. It’s pretty nice when you take that pressure off yourself!

My current editor of choice is Sublime Text, which I’ve been using for about a year now, and it’s a real pleasure now that I’m used to it. I appreciate that it gets out of the way and lets me code in peace, but also has a ton of useful functionality under the hood. Before using Sublime Text I was a huge fan of Espresso, which has a really beautiful, friendly interface and some nice extra CSS features, like a built-in gradient generator. I only switched away from Espresso because I was doing a bunch of work with Sass and Haml, which Espresso didn’t support very well. You snooze, you lose, Espresso!

Leveling up your dev environment

One of the other joys of local development is being able to live reload your changes without having to manually refresh the page in the browser. Right now I’m using CodeKit for this purpose (as well as for using Sass, which is so awesome and useful and time-saving that it deserves its own post). Once you get used to seeing your changes happen in the browser without having to refresh, you can never really go back. I have a nice, big display, so I often have my code editor open on one side of my screen and the browser on the other, like so:

This resized image doesn't convey the majestic nature of having a 27" display. What is this, a display for ants? It needs to be at least three times this size!

This scaled-down image doesn’t convey the majestic nature of having a 27″ display. What is this, a display for ants?

Adding your WordPress project to CodeKit is super easy. With your CodeKit window open, click on the plus sign in the bottom left hand corner, and click “Add Project…” and find your WordPress theme directory (the one inside /wp-content/themes/). Open the directory, and now CodeKit is monitoring your work and will live-reload all of your changes (as well as run CSS pre-processors if you choose, minify your JavaScript, optimize your images, and all sorts of other stuff). Easy!

Like so!

Like so!

Okay, that’s cool, but now how do I get my local site on a real server?

Glad you asked! Since this post is nearly 1000 words at this point (!), it’s probably best to save that for another time instead of putting you to sleep by continuing this epic saga. In the meantime, I’ll refer you to another very helpful screencast at CSS Tricks that will walk you through this process. What this video shows is basically what I do (though I think I do a couple of things more efficiently) so definitely take a look and see if that helps you.

Till next time!

Want more articles like this? Get ’em in your inbox!

Developer Tip Tuesday: Always develop locally

This is a series of posts wherein I share the dev mistakes that I used to make, and hopefully help others in doing so! Also, I reserve the right to publish these either on Tuesdays or Thursdays. As long as the title is cheesy and alliterative, I’m happy.

Back when I was a young developer just learning the ropes, I did some silly things. One of them, as you can probably guess, was developing live (making changes on a live server) instead of locally (on my computer). I was full of excuses:

“But this site barely gets any traffic! If I make a few changes live, who will notice?”

“If I code this site right on a staging server, I don’t have to migrate the site from my computer to the server because it’s already there!”

“Setting up a local server sounds hard and I’m lazy!”

I’ve heard it all, because at some point I’ve said it all. First, let me walk you through the three main ways one can code a site:

Worst: Developing on a live/production site

In my defence, even back in the old days, I didn’t do this too often. After all, it would be ridiculous to develop a full new site from scratch in a public location where everyone could see it. But, not gonna lie, sometimes when I was asked to add new features to an existing site, I found myself being both lazy and overly optimistic and just quickly doing it live on the server.

Overly optimistic? Yep! I was assuming that I wouldn’t make a mistake that would mess up the live site and even potentially ruin my reputation as a developer. And when it’s easy to take out a whole site with a single missing semicolon, this was actually a pretty real risk.

Sub-Worst: Making changes to a WordPress theme using the built-in editor



If you are going to go ahead and make changes to a production WordPress site right on the live server, please never do it in the built-in editor. While HTML and CSS are pretty forgiving, one can royally screw up stuff in PHP (see above about missing semicolons taking out whole sites), and if you make a mistake in the online editor, you risk taking out your entire site with a White Screen Of Death™ and not even knowing why. Usually you’ll only take out the front end of your site, but in some cases, you can even lock yourself out of the admin pages. Know what’s super fun? Trying to restore your website when you can’t even access your website. Don’t do it, kids!

Don't let this happen to you!

Don’t let this happen to you!

Better: Developing on a staging site

So, you’ve decided instead that you’re going to develop your site on a staging server or a test site that only you and the client have access to. That’s obviously way better than making changes on a production server, because at least it’s private and if you mess something up, the public doesn’t have to know! Yay!

That being said, here’s what I don’t like about this method:

  1. Working off the server means that you’re at your server’s (and your Internet connection’s) mercy. All servers have outages at some point, and because the universe totally hates you, it’ll obviously happen when you need it the most.
  2. FTP is slow, dudes. There’s a lot of waiting and reloading with this method, and I’m impatient.
  3. Your super secret site might not be so super secret. I’ve found other developers’ “secret” “staging” sites in Google before when I wasn’t even looking for them. Oh noes!
  4. Once you’ve given out the secret address for your client to see, they can/will see all the further changes you make, and might see some mistakes that you make (or wonder what happened to the site when it’s taken out by the missing semicolon of doom). When I’m troubleshooting code or trying new features, I’ll often do strange things like outline elements in weird colours, use cats and Samuel L Ipsum as placeholders, and will occasionally console.log(‘some very profane things’). I don’t necessarily need my clients seeing all of that (though, to be honest, I’m pretty shameless about the cats).

Best: Developing locally alongside a staging site

Naturally, my favourite solution is to always develop sites locally (on my computer) so that the only people who can see the site in its incomplete state are me, myself, and I. Then, when I’ve finished, I upload the site to a super secret staging server (which I’ve made sure is hidden from search engines) for the client to see. Any time I have changes to make or bugs to fix, I go back to my local server to make the changes, and then push the changes to the staging site when I’m good and ready. This might sound tedious, but trust me, it’s saved me a lot of grief.

This method is awesome because:

  1. Developing locally is crazy fast! No need to wait for changes to upload or for pages to reload. There are various apps that’ll refresh your browser automatically every time you save a file, and let me assure you, this is a magical experience from which there is no turning back.
  2. I can screw up as much as I want in the comfort of my very own computer. Clients and the public only ever see the site when it’s in good shape. Life is much less embarrassing this way.
  3. Client-facing sites will never succumb to the White Screen of Death™ due to a missing semicolon.
  4. During development, I always have an up-to-date version of the website on my computer in case anything happens to the server.

Coming up next: How I develop locally!

Are you intrigued about the idea of developing locally? If so, stay tuned! My next post in this series will go into detail about how I develop locally, which programs I use, and other fun tips and tricks. And if you disagree with any of this, that’s cool too! Feel free to share your perspective in the comments below or reach out on Twitter.

Want more articles like this? Get ’em in your inbox!

Inspiration can be dangerous

I have a confession to make: I’m a complete information junkie. I love reading books and blogs, taking courses, listening to talks, and otherwise acquiring as much information as I can on just about every topic of interest.

This is my bedside table. I am actually in the middle of reading every one of these books, I shit you not.

Inspiration is a big buzzword these days, and for good reason. It’s important to be creatively energized and it’s really great to be able to see beauty and promise in the world around us. There are countless websites and books that are what I like to think of as aspiration porn. They make us want better, more interesting, more beautiful lives.

Inspiration is great, but it can also be dangerous. Why? Because it’s way easier to be inspired and to absorb information than it is to actually do something. It’s easier to think, to read, to plan, and to overanalyze than it is to actually take action and make changes in our lives. This applies to the little things like making that DIY craft project you keep saying you want to try and remembering to floss every day, all the way up to the big things like making major relationship and career changes.

I’m a total information junkie and always will be, but I have to constantly remind myself that although knowledge is power, going one step further and actually taking action is way more important.

Don’t live your life just inside your head. Don’t settle for merely being inspired. Go ahead and take a baby step (or, a big leap, if you prefer) toward building the life you really want to be living.