Loading Web Fonts Without Performance Penalty From Lighthouse

One thing that will most certainly lose you performance points in Google Lighthouse Performance Audit is loading web fonts. More specifically, loading web fonts in a way that render-blocks.

If you simply drop @font-face into your CSS or load <link rel="stylesheet" ... /> tags into your <head/>, Google Lighthouse will hate you. Even if you are loading a Google Font.

Don’t despair! It’s very easy to avoid this penalty.

Step 1: Skip the <link/>

To avoid render-blocking, don’t just add the default <link .../> or @import { ... } code that Google Fonts gives you to your site. Google Fonts gives you a link to a stylesheet which loads the fonts. We want to skip this interim step and load the content of that stylesheet directly.

So for example if I want to load the font Raleway, Google gives me:

<link href="https://fonts.googleapis.com/css?family=Raleway" rel="stylesheet">

So I load the URL https://fonts.googleapis.com/css?family=Raleway in my browser and get its contents.

The CSS file contains all of the @font-face { ... } rules for loading my font. I’m going to copy them into my site’s CSS.

Step 2: Setup Font Swapping

Now that we’re loading the fonts directly via @font-face { ... } rules in our own CSS file, we need to instruct the browser to how to handle the font before it is fully-loaded. We use the font-display CSS rule for that.

Setting font-display: swap; tells the browser to use the closest matching font in the font stack, and then swap in the web font after it loads. Setting font-display: optional; tells the browser to use the closest matching font in the font stack that is currently available, or is available within 100ms of page load. In other words, the web font will not be swapped-in if it is not almost immediately available.

What’s the downside? The font-display property doesn’t have great cross-browser support,and the default behavior varies from browser to browser. On most browsers the default behavior will be FOUT: a flash of unstyled text,while the browser displays the closest matching font, and then loads the web font when it becomes available. This experience can be a little jarring.

If you use font-display: swap; and your user’s browser supports it, your users will experience FOUT before the font loads for the first time. After the font is loaded and cached, it will be used immediately.

If you use font-display: optional; users whose browser supports the property will not notice FOUT, but they may experience a page rendered in the closest matching font in the stack when the web font is not immediately available. On subsequent loads (when the web font is cached), pages will render immediately using the web font.

Small Rental Agencies: Don’t Bother with a Zillow Feed

This is a follow-up to a previous article we wrote about integrating with Zillows Listing Feeds.

While the technical specifics of integrating with Zillow remain true, recent experience has led to the conclusion that small agencies cannot trust Zillow Listing Feeds to work for them, and we cannot make the recommendation to use them.

Zillow Feeds Explained

Zillow is a popular real estate and rental aggregation service. At the time of writing, Zillow, HotPads, and Trulia are all the same company using more or less the same database. Getting listed in one usually means you’re listed in all three.

There are numerous methods that agencies and agents can publish their listings to Zillow. A popular method is by building a Zillow Listing Feed. The basic premise of building a feed is that you can take the data you’re managing elsewhere and publish it in Zillow’s XML format, which they will read and update daily. Agencies and agents love feeds because they already have to enter the same data into their websites and/or MLS. Building a feed means they can publish to Zillow without doubling their workload: they no longer have to enter their listings a second time into Zillow Rental Manager.

Our History with Zillow

In my previous position at another agency, I built my first Zillow Listing Feed for a local real estate agency. It was not without it’s issues: we learned some hard lessons about how Zillow compiles data from multiple sources and decides which is the “source of truth” for your listings, but overall it was a massive success. When I started Reich Web Consulting, I made it a goal of mine to leverage this new skill set to build affordable solutions for other real estate agencies and agents.

I built a WordPress plug-in for property management that tracks all 200+ data points available in the Zillow Listing Feed specification. This solution was massively successful to the three small local rental agencies that currently use it. I was hoping this would be something that got big. That would make a difference in the rental agency community.

Client Number 5

In late 2018, the co-owners of one of the agencies using this solution decided to part ways. One kept the old site and feed. The other started a new business with a new website, and a new feed. The new business has about 100 properties, with anywhere from 2-8% of them vacant at a given time. We submitted our feed to Zillow in late December.

Where Things Went Wrong

Our history with Zillow informs us that getting listed takes time, so when they weren’t showing up by mid-January I didn’t get too worked up. I contacted feeds@zillow.com, the support address referenced in the Zillow Listing Feed specification document. No one responded. Another month later I tried again, with no response.

By March my customer was getting quite frustrated, so I started getting desperate.

I tried calling. There is no published phone number for Zillow feed support. So I dug up and called their customer service number. There is no option for feed support. There is no option for support without an account. Fortunately Client #5 has a Rental Manager account, which they provided. But when I called back I discovered that you can’t get through the call system without a paid account.

So I started emailing anyone at Zillow I could find, including the direct email address of several Zillow support staff that had helped me in the past. I considered naming names and email addresses, but even as worked-up as I am, I don’t want to dox anyone. No one responded back.

By this time it is early April. The feed is still not being pulled by Zillow. I decided to attempt a Hail Mary and resubmit the feed and while doing so, I notice two things. First, I notice the following language:

If you have more than 200 listings, you can send us listings data through our free automated feed program.

Zillow Listing Feed Program

At this point I am pretty certain I know what the problem is, though previous clients have had small feeds and got into the program. I also see another email address: listingsupport@zillow.com and I decide to make one last attempt to get help.

Zillow’s Unsupportive Feed Support

I sent an email to listingsupport@zillow.com simply asking if the mailbox is active, and two days later I get a response back asking how they can help. I tell them my situation in detail. Here is the response I receive back:

Thank you for clarifying about your issue. I looked it appears that you are only sending to us 4 listings, which at this point we recommend you just use Zillow Rental Manager to create your listings.

Phong, Zillow Listing Support

Before the split, the larger company had well over 200 listings which met their requirement. The new company has around 100, and is fortunate enough to only have a few vacancies. I think this might help make our case, so I reply back:

Hi Phong,

The client has significant more units (over 100), but only 4 are currently vacant. It would be very cumbersome to manage all of those manually through the rental manager. Should I be sending the rest of the properties in the feed with a different status?

Brian Reich, CEO, Reich Web Consulting

He responds back:

On average, how many properties are vacant?

Phong, Zillow Listing Support

Cool, now we’re getting somewhere! I contact the client, get that information, and respond back. I decided to appeal to their humanity by being honest about the situation, why the businesses split, leaving two smaller feeds under their 200 listing recommendation. The email below has been redacted to protect the identity of our client.

They typically have 8-10 available at any given time.

Phong here is some additional background.  This client, Rental Agency B, was previously part of a family business called ”
Rental Agency A” for which I built a feed years ago which Zillow is already successfully processing. With the exception of that site having a brief downtime issue about a year or so back I believe it’s been pretty reliable and low-maintenance for both of us.  The owner of that business was diagnosed with a terminal neurological disease, and as a result his wife and children (all co-owners) decided it was best to separate their interests into separate legal entities.

Rental Agency B is the children’s new business.  All of the properties that are in this feed were previously in the feed of Rental Agency A and had to be legally removed from that site/feed when the business was legally split up. I know it’s not Zillow’s responsibility to care about any of this, but my point was that all of the listings that are in the Rental Agency B’s Feed were rental properties that were already accepted and listed under the other business’ feed just a few months ago. If not for their dad being diagnosed with Alzheimer’s and the business structure being forced to change, they’d still be there and we would not be having this conversation. And if not for a lawyer forcing me to split the sites up, I’d put them right back in the feed you are already parsing.  Does that make sense?  I tell you all this to try and make the case that, even though this is a new business, the feed data actually has history with Zillow and is entirely trustworthy; if it were still combined with their family business we’d be at that higher feed size and there would be no issue to discuss.

They have tremendous success with the Rental Agency A feed and really depended on the leads they got from Zillow/Trulia/Hotpads to fill vacancies quickly. I’m really hoping your side can understand all of this and, if necessary, make an exception and parse this feed.

Thanks for your time and understanding.

Brian Reich, CEO, Reich Web Consulting

A day later, I receive a final reply:

Hey Brain,
Thank you for that update. Though I really appreciate the interest and the efforts made, I took a look at the Rental Agency A feed and from the looks of it when I looked from beginning of this year, it hovered from 0 listings to 2 listings and nothing more than that.
The reason why we have the Zillow Rental Manager product built is for reasons like those where it isn’t necessary to use your bandwidth and just to manage 2 listings when you can easily just use Zillow Rental Manager and do that.

Phone, Zillow Listing Support

At this point I’m resigned to accept that this conversation is going nowhere, but I’m frustrated. I’ve built several successful feeds that were accepted in spite of their size being below 200. I’ve submitted feeds in the past and did not see the language about 200 listings in the past (though it is entirely possible that I just missed it).

What I’m most frustrated about is the fact that Zillow doesn’t seem to understand or care, about the impact this has on smaller rental agencies. To quote Phong, it isn’t necessary to use your bandwidth and just to manage 2 listings when you can easily just use Zillow Rental Manager and do that.” He’s completely missing the point. Is Zillow Rental Manager easy to use? Sure. But not any easier than the solution my clients already have in place. Forcing them to use it forces them to double their efforts. And the claim that it’s just 2 listings is wrong. As I already told him they have over 100 and the vacancy status of those units change over time. Doubling the effort to manage a portfolio of that size is a considerable hardship. I sent a final reply more out of frustration than anything:

I’m done arguing my point. I’m clearly not going to get anywhere, but this is kind of ridiculous. My clients have a lot of properties, and they’re fortunate enough to keep them rented. I’m not sure why that’s counted against them. Rental Agency A‘s Zillow feed was critical for helping them keep their apartments rented, and constantly tell me that Zillow sends them the most qualified leads. As renters they love your front-end service. So based on that I built a system that allowed rental agencies to manage their properties in one place and feed them to their website, Zillow, and other aggregation services.  So to counter your point: unfortunately, no, they can’t “just as easily” use the Zillow Rental Manager.  It doesn’t get any easier than editing/updating your listings once, in one location. If they also have to manage all of their properties in the Rental Manager that essentially doubles their workload.

I build APIs as part of my job. If Zillow doesn’t want people integrating with their API, or has strict rules about who can access/use it, then they should be transparent about that. API’s are all about maintaining consistency over time.  How is it that this is the fourth feed I’ve built and sent to Zillow and I’m only now being told my clients are too small to participate?

Having built a pretty terrific WordPress plugin for property management that integrates with your API, I was hoping I’d be able to feed more information to Zillow in the future and make it easier for smaller rental companies to leverage Zillow without doubling their workload. Clearly making integration easy for renters isn’t actually what Zillow wants.  I’ll make sure that all of my rental and real estate clients are well aware of this in the future.

Brian Reich, CEO, Reich Web Consulting

The Takeaway

What advice can I offer rental agencies and agents?

Zillow only wants feeds with 200 or more listings, and that statement is a rule, not a request. As of the time I write this (4/25/2019), if you’re an agent with only a handful of vacant units at a given time or your portfolio is below this threshold, don’t waste your time building a feed to Zillow, Trulia, or HotPads. Accept that you need to either manually manage your listings via the Zillow Rental Manger or participate in a larger service is already integrated into Zillow, such as an MLS.

What advice can I offer to Zillow?

With great API comes great responsibility. When you create an API or similar service such as feed aggregation and make it public, you accept a certain amount of responsibility for making sure the experience stays consistent and does not break integrations. At some point Zillow instituted this 200 listing minimum. At some other point, they decided to actually enforce it. The language on their website is way too soft and calls a feed “the best solution” for agents with 200 or more listings. It does not say it’s a hard requirement to participate. It should.

Second: if Zillow wants to limit participation in the Zillow Listing Feed service, then don’t make it public. This entire fiasco could have been avoided if Zillow simply but feed submission behind a form that rejected us because the feeds didn’t meet their requirements.

Third: update your documentation. The Zillow Listing feed docs list a support email address that worked in the past but seems to be dead. This led to me beating my head against a brick wall and disappointing my client for months until I accidentally stumbled across a different email address.

Finally: take communication with developers participating in this program seriously. We can work together and help each other, if you’re willing to listen. Out of desperation I tried contacting several individuals at Zillow that have assisted me in the past. According to the LinkedIn profiles of those individuals, they are still at Zillow. But they did not respond to my requests, even by directing me to the right support channel. Instead myself and my rental agency client are left with a 4 month customer service nightmare.

Having said all of that: Zillow, I get it. I know you probably don’t want just anyone submitting feeds due to feed spam and listing scams. Other aggregation services that pretty much list whatever you throw at them similar to Ron Burgundy reading whatever you put on his teleprompter, are rife with scammers. I understand why you might not want to let just anyone participate. But you can make that a heck of a lot clearer.

And last: what advice can I offer to my future self, and those like me?

Don’t sell Zillow integration services to small real estate agencies and small rental agents. Or possibly to anyone.This has been a disaster of epic proportions for me. My business spent considerable development time and money building a WordPress plug-in for agents large and small to manage their listings from their website and feed them to aggregation services like Zillow, Trulia, and HotPads without duplicating their efforts. Based on past experience with Zillow we had no reason to expect it would be a tremendous failure.

We understand that the buck stops with us. I have a disappointed client. I have refunds to issue. But the most frustrating part is that this is all true in spite of the fact that I delivered a fully-functioning product. They have a feed that there is no technical problem with except that it doesn’t meet this minimum listing requirement, which was not communicated as a requirement to participate in the program in the first place.

I’ve lost a little money, and a lot of time on development. But the development hours pale in comparison to the amount of time wasted trying and failing to draw a conclusion to the situation due to Zillow’s lack of consistency and lack of communication.

I will not be offering Zillow feed integration services to customers in the future. But something tells me, this is exactly what Zillow wants.

Tips for UPS API Integration

I do a lot of shipping integrations for my manufacturing automation customers, and for my customer’s customers. While we always document these tips internally, I thought it would be useful to catalog and share them. Below are some helpful tips we’ve compiled for UPS API integration.

TIP #1: Customer Account Numbers Use the Number Zero, Not the Letter O

Customer account numbers are a series of six letters and digits.  If you have a UPS customer account that contains something circular, it’s always the number zero (“0”) and not the letter “O.” This tip comes directly from UPS API support.

TIP #2: UPS Mail Innovations Doesn’t Support Third Party Billing

UPS Mail Innovations is a unique shipping method that utilizes the local postal service to complete the final leg of your shipment. Unlike other shipping methods, it does not support third-party billing. That is, you cannot use one account to ship the package and bill the package to another UPS account using the BillThirdParty payment option. Mail Innovations shipments must be generated using the BillShipper option. That leads us to our next tip.

TIP #3: BillShipper Requires that you Add the Shipper Account as a Payment Option

To use the BillShipper payment option, you must add the account you’re billing for the shipment as a payment option in the UPS account being used to access the API.  You can do this by logging into the account on ups.com and selecting Payment Options. You’ll need a few pieces of information, including:

  • UPS Account Number
  • Default pick up Zip code
  • Invoice # from most recent account invoice
  • Date of most recent account invoice
  • Payment due amount from the last invoice
  • Control ID of the last invoice


Need Help Integrating with UPS?

Having trouble integrating with UPS? Don’t hesitate to contact Reich Web Consulting today.

  • This field is for validation purposes and should be left unchanged.

How to Add Social Media Icons to your WordPress Site Featured Image

How to Add Social Icons to Your WordPress Site

One of easiest and most effective ways to integrate your WordPress website into the world of social media is to add links to your social media profiles.  These links help your visitors find and follow your social profiles, and just about every website has them. There are a variety of ways to integrate social links or social icons into your WordPress website, and I’ll demonstate three methods in this article.

1. Choose a Theme That Supports Social Icons

If you’re in the early stages of developing your website, the simplest way to add icons for your social profiles to WordPress is to choose a theme that provides social links as a feature. Lots of themes have built in support for social media icons. All of my favorite premium themes support them including the theme I’m currently using on this site (Enfold). Lots of free themes in the WordPress Theme Directory support social icon, and even WordPress’ current default theme Twenty Sixteen has a social icon menu built in.

There are few things to keep in mind:

  • There are better reasons to choose a WordPress theme, and there are other ways to add social media icons. So if you’ve chosen a theme but it doesn’t support social media icons, you don’t necessarily need to discard it for that reason.
  • Make sure the theme supports all of your social media profiles, or provides a way to add new ones. I recently built a website for a well-known romance author and she needed an icon for Goodreads, a niche social network for authors and their fans. My theme didn’t support it directly but made it easy to add a new social network and icon.

Highlighted in this image is the social icon area built into Enfold, one of my favorite premium themes.

Highlighted in this image is the social icon area built into Enfold, one of my favorite premium themes.

2. Use a Plugin to Add Social Icon Support

You can use a plugin to add social icons to your website. Some plugins, like Social Icons, work by letting you manage a list of your social media profiles and then  the plugin displays the icons as a widget in one of your WordPress widget areas. Some like cbnet Social Menu use WordPress’ menu tool to manage your social icons. Choose a plugin wisely: make sure it has a high rating and good reputation, and that it’s author updates it regularly.

In this screenshot I've highlight the social icons that have been inserted with a plugin.

In this screenshot I’ve highlight the social icons that have been inserted with a plugin.

3. Manually Add Social Icon Support

If you’re not afraid of writing some code, adding your social icons to your WordPress theme is easy. You need to choose where in your theme you want to add the icons, insert some HTML code, and then add some styling to your theme’s style.css.  Here’s some sample code. Obviously your code will differ base on your theme and how you want to style your icons.


Add the following HTML to your theme to render a list of social icons. You could place this anywhere, but you’ll usually want your icons to appear in your header (header.php) or footer (footer.php):

<ul class="social-icons"> <li><a href="https://www.facebook.com/user"><em class="fa fa-facebook-square"></em></a></li> <li><a href="https://www.twitter.com/user"><em class="fa fa-twitter-square"></em></a></li> </ul>

CSS Code

Add the following CSS code to your theme’s style.css to style the list as a horizontal list of icons. You’ll need to modify the code to integrate the look and feel of the icons into your own theme.

/** * Load FontAwesome if your theme isn't already doing it. */ @import url(https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css); /** * Style and position the list. */ .social-icons { top: 0; right: 0; margin: 0; padding: 0; list-style: none; text-align: right; margin: 10px auto; max-width: 1174px; } /** * Style the list items. */ .social-icons li { padding: 0; display: inline-block; font-size: 30px; } /** * Override the colors of the FontAwesome icons to be appropriate for the * social network. */ .social-icons li .fa-facebook-square { color: #3e5b98; } .social-icons li .fa-twitter-square { color: #4da7de; }

In this image I've highlighted the social icons that I manually added to my theme code.

In this image I’ve highlighted the social icons that I manually added to my theme code.


There are a number of ways to easily add social media links and icons to your WordPress website using themes, plugins, and custom code.  But adding links to your social media profiles are just one way to integrate your website with social media! Stay tuned for more tutorials on integrating your WordPress website with social media.

Why Inline Styles Suck

I get it: sometimes project scope, cost, and time limitations get in the way of doing the right thing.  That’s why professionals who damn-well know better take shortcuts like using inline styles. These tactics rarely save time in the long-term. This article explains why and suggests some long-term solutions to the problem of inline styles.

What Is an Inline Style?

Inline styles are CSS styling rules that are embedded directly into your HTML markup in the form of either a <style> tag or the attribute style="".the tag  They’re the opposite of external style sheets, which are CSS styling rules defined in an external file that gets linked into your HTML the tag<link/>.

Both types of inline styles suck, and I’m about to tell you why.

Why Do Inline Styles Suck?

I’m of the opinion that we should avoid <style> and the style="" attribute except in the most basic situations.  Why would I make such bold assertion?  Because of experience, that’s why! There are many reasons that inline styles suck.

Inline Styles Defeat the Purpose of CSS: Separation of Concerns

If you’ve been in the web design business long enough, you’ll remember how hard our forefathers like Jeff Zeldman worked to pave the way for the semantic web (a pipe dream, for better or worse).

To sum it up, folks like Zeldman fought for all browsers to support some very basic features. They wanted support for XHTML: a markup language that defines the structure and meaning of the words on the page, and not so much their style. They wanted support for CSS: a language that describes how those words should look on screen, in print, and on various other devices. Their reasons?

  1. Web Standards. Sites were bloated with browser-specific code because no browser supported the “standards” in a standard way. An <h1> on one site may be a different size and weight from one browser to the next.
  2. Accessibility. Talented designers realized that out of necessity they were using semantic tags like  <table> and <h1>  – <h6>  to affect style and positioning, and it was making the web less accessible. Nonstandard devices such as screen readers were choking on the spaghetti code needed to make sites render on standard web browsers and devices.
  3. Page Weight. Marrying content to presentation meant that every page, no matter how similar it was to every other page on a site, had to download a fresh copy of all its styling. Divorcing presentation from markup makes the size of a page much smaller. A single style sheet can define the design for an entire website, and no matter how many pages a user views or how often the content changes, that style sheet need only be downloaded once.

Inline styles defeat many of the goals of semantic markup. Inline styles add to page weight and must download each time the page loads, even when the styling hasn’t changed. The style="" attribute is especially nasty: it remarries presentation and content, making it impossible for devices to style differently based on context.

And while most designers don’t give a damn about how an inline style might add a few bytes of page weight or how assistive technology might interpret their page, they probably do care about mobile.

I recently ran into a situation where dozen of pages created inside a CMS were given two-column layouts by using inline style attributes to define floats and static widths. This was fine before the mobile web was a thing and every  browser could handle a 960 Grid System layout. But by defining positioning inline on dozens of pages, the developer effectively made the job of making this site mobile friendly far more difficult. The Fiddle below shows what happens to these column definitions when they appear in a 960gs page versus mobile:

Inline Styles Defeat Style Sheet Optimization

There are several methods for loading CSS more efficiently, and none of them apply to inline styles:

  1. Combining External Resources. The first is to combine any external CSS resources into a single file. Even though the resulting file is just as big as the sum of it’s parts, it requires only a single browser request to fetch it.  On a site that loads numerous style sheets (for example, a WordPress site with a lot of plug-ins installed), the savings can be substantial.  Unfortunately internal styles are rarely, if ever, optimized by these tools.
  2. Minifying CSS. If you’re not minifying your CSS, you probably should be. Minification is the process of running your CSS scripts through a tool that removes any unnecessary content such as comments, white space, and redundant rules. Again most CMS packages can minify your CSS for you, but only if they’re in external style sheets.
  3. Caching.  Caching rules can be applied differently to different types of content.  Once design on a website is complete the style sheets will change very infrequently, so the environment can be configured to provide the user with a fresh copy of a site’s external CSS files very infrequently, limiting the time it takes the user to download the new file and conserving costly bandwidth for both the user and your website. Unfortunately if your style rules are part of the page content, your styles will be cached the same way as the rest of the page.

Inline Styles Make Finding the Source of a Style Difficult

Consider a pretty simple example.  You’ve got a website managed by a content management system and you want to change the styling on a particular page. (Let’s say it’s WordPress for this example, but it really doesn’t matter.)  First you need to find out where the current styling originates so you can change it. Being familiar with the CMS you know that styles could be set by:

  • The theme’s external style sheet style.css.
  • An external style sheet loaded by a plug-in.
  • An inline style in a <style>...</style> block hard-coded into one of the theme’s templates such as header.php, page.php, footer.php, etc. The possibilities are as numerous as the number of templates in the theme.
  • An inline style in a <style>...</style> block hard-coded into a plug-in. The possibilities are as numerous as the number of plug-ins you have installed.
  • An inline style in a <style>...</style> block hard-coded into the content of a page in the CMS. You’d have to login and update the page content to change the styling.
  • An inline style attached by a plugin like Jetpack Custom CSS.
  • An inline style in a style attribute hard-coded into one of the theme’s templates. Again, we have numerous possibilities for where it could be located.
  • An inline style in a style attribute hard-coded into a plug-in.
  • An inline style in a style attribute hard-coded into the content of a page in the CMS.
  • A style dynamically assigned to an element using JavaScript.

It’s pretty obvious that locating a style’s origin gets pretty complicated when you stop stashing styling rules in a common location like style.css. Tools like Firebug and Chrome’s Developer Tools can help you determine the source of a given style.  They’ll even tell you the exact line number in an external stylesheet where a style is defined, or tell you where in the HTML markup an inline style has been defined.

The key words in that statement are “in the HTML markup.”  Remember 20 seconds ago when I listed all the server-side code that could be generating inline markup? Tools like Firebug can only tell you where a style is defined in the HTML markup the browser receives. They can’t tell you which server-side code generated the markup. Relying on inline markup can leads to entire hours lost searching server-side code and database content just to figure out why a certain element is bold, the wrong color, or badly positioned.

Inline Styles Solve Today’s Problem & Creates Tomorrow’s

Inline styles contained in a   <style>...</style> block only affect elements on the page in which they live.  Styles in an   style="" attribute only affect the HTML element on which they’ve been defined.  So by their very nature inline styles create scenarios where copy/paste feels like the only solution, and by extension they introduce inconsistencies into your web design. Consider the code below. In the HTML markup we have a single <div/> with a class="message" and some inline styles to make it look like an error message.

We’re so thrilled with our new error message styling that we decide to use it on a few other pages! But since our styles are inline and we don’t want to waste time editing what already works and creating an external style sheet, we copy & paste what we already have.

Months later we realize that our background color isn’t exactly easy on the eyes and want to change it. First of all months have past and we may not even remember writing this code, and must track down where the styles are defined. Second, we realize because of our up-front laziness we now have to change it in several different places, and if we miss even one, our message styling won’t be consistent throughout the site. At this point we realize that it would have been far easier and far more consistent to just externalize our style in the first place. In the example below I’ve moved the styles to an external style sheet, where changes only need to be made once:

Why Do Developers Use Inline Styles?

All the points I’ve made in this article are pretty well-known.  So why do seasoned developers that ought to know better still keep using inline styles?

Excuse 1: Project Constraints

If you’ve been given a common task like changing the layout or the fonts on a single item or a single page, an inline style might feel like the best solution to that specific problem. The project scope might be “made this heading bolder” or “switch the Products Page two a two-column layout”, not “create a reusable style for page headers” or “create a responsive two-column layout for page Y.” Not only are you not getting paid to think about how your solution might effect the site in the future, your work culture might completely disincentivize doing things the right way by rewarding quick, billable solutions, no matter how hacky or void of forethought they may be.

Explain to your boss why you should take the time to solve the problem the right way, and do it. Unless you’re working with an inferior CMS that gets in the way of getting your work done, it shouldn’t take much longer than adding the CSS inline.

Excuse 2: Technical Constraints

Some content management systems don’t provide a way to target a specific piece of content with CSS other than including the CSS in the content itself. This was true in old versions of WordPress, and the problem still exists in themes that don’t follow the practice of calling  body_class() in their header templates.

Whether you’re working on a framework of your own design or an open source CMS, your workflow should provide a way to target specific pieces of content, and a common location for stashing CSS. If it doesn’t, your workflow should probably be improved. Here are two examples, one off-the-shelf and one custom:

  • In WordPress styling is stashed in the current template’s style.css file. Plug-ins should (but don’t always) import styles from their own style sheets. Each page you create provides a body class that allows you to target specific content from within the external style sheets, eliminating the need for in-line CSS.
  • In my employer’s in-house CMS, we stash CSS in /styles/custom.css. Each piece of content stored in the CMS has a unique id that is used to set a body class, which allows you to target specific content from custom.css, eliminating the need for in-line CSS.



Last Friday my entire day was consumed by fixing problems caused by other people’s erratic use of CSS. A perfectly good mobile template was blasted to bits by inline styles coded into page content saved in their live CMS.  While I’m sure there are some situations where an inline style might be the best solution, I have yet to run into any of them. Please style responsibly.