Tag Archives: news

How BBC Interactive Content Works Across AMP, Apps, And The Web

In the Visual Journalism team at the BBC, we produce exciting visual, engaging and interactive content, ranging from calculators to visualizations new storytelling formats.

Each application is a unique challenge to produce in its own right, but even more so when you consider that we have to deploy most projects in many different languages. Our content has to work not only on the BBC News and Sports websites but on their equivalent apps on iOS and Android, as well as on third-party sites which consume BBC content.

Now consider that there is an increasing array of new platforms such as AMP, Facebook Instant Articles, and Apple News. Each platform has its own limitations and proprietary publishing mechanism. Creating interactive content that works across all of these environments is a real challenge. I’m going to describe how we’ve approached the problem at the BBC.

Example: Canonical vs. AMP

This is all a bit theoretical until you see it in action, so let’s delve straight into an example.

Here is a BBC article containing Visual Journalism content:


Screenshot of BBC News page containing Visual Journalism content


Our Visual Journalism content begins with the Donald Trump illustration, and is inside an iframe

This is the canonical version of the article, i.e., the default version, which you’ll get if you navigate to the article from the homepage.

Now let’s look at the AMP version of the article:


Screenshot of BBC News AMP page containing same content as before, but content is clipped and has a Show More button


This looks like the same content as the normal article, but is pulling in a different iframe designed specifically for AMP

While the canonical and AMP versions look the same, they are actually two different endpoints with different behavior:

  • The canonical version scrolls you to your chosen country when you submit the form.
  • The AMP version doesn’t scroll you, as you cannot scroll the parent page from within an AMP iframe.
  • The AMP version shows a cropped iframe with a ‘Show More’ button, depending on viewport size and scroll position. This is a feature of AMP.

As well as the canonical and AMP versions of this article, this project was also shipped to the News App, which is yet another platform with its own intricacies and limitations. So how do we do support all of these platforms?

Tooling Is Key

We don’t build our content from scratch. We have a Yeoman-based scaffold which uses Node to generate a boilerplate project with a single command.

New projects come with Webpack, SASS, deployment and a componentization structure out of the box. Internationalization is also baked into our projects, using a Handlebars templating system. Tom Maslen writes about this in detail in his post, 13 tips for making responsive web design multi-lingual.

Out of the box, this works pretty well for compiling for one platform but we need to support multiple platforms. Let’s delve into some code.

Embed vs. Standalone

In Visual Journalism, we sometimes output our content inside an iframe so that it can be a self-contained “embed” in an article, unaffected by the global scripting and styling. An example of this is the Donald Trump interactive embedded in the canonical example earlier in this article.

On the other hand, sometimes we output our content as raw HTML. We only do this when we have control over the whole page or if we require really responsive scroll interaction. Let’s call these our “embed” and “standalone” outputs respectively.

Let’s imagine how we might build the “Will a robot take your job?” interactive in both the “embed” and “standalone” formats.


Two screenshots side by side. One shows content embedded in a page; the other shows the same content as a page in its own right.


Contrived example showing an ‘embed’ on the left, versus the content as a ‘standalone’ page on the right

Both versions of the content would share the vast majority of their code, but there would be some crucial differences in the implementation of the JavaScript between the two versions.

For example, look at the ‘Find out my automation risk’ button. When the user hits the submit button, they should be automatically scrolled to their results.

The “standalone” version of the code might look like this:

button.on('click', (e) => 
    window.scrollTo(0, resultsContainer.offsetTop);
);

But if you were building this as “embed” output, you know that your content is inside an iframe, so would need to code it differently:

// inside the iframe
button.on('click', () => 
    window.parent.postMessage( name: 'scroll', offset: resultsContainer.offsetTop , '*');
});

// inside the host page
window.addEventListener('message', (event) => 
    if (event.data.name === 'scroll') 
        window.scrollTo(0, iframe.offsetTop + event.data.offset);
    
});

Also, what if our application needs to go full screen? This is easy enough if you’re in a “standalone” page:

document.body.className += ' fullscreen';
.fullscreen 
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;


Screenshot of map embed with 'Tap to Interact' overlay, followed by a screenshot of the map in full screen mode after it has been tapped.


We successfully use full-screen functionality to make the most of our map module on mobile

If we tried to do this from inside an “embed,” this same code would have the content scaling to the width and height of the iframe, rather than the viewport:


Screenshot of map example as before, but full screen mode is buggy. Text from the surrounding article is visible where it shouldn't be.


It can be difficult going full screen from within an iframe

…so in addition to applying the full-screen styling inside the iframe, we have to send a message to the host page to apply styling to the iframe itself:

// iframe
window.parent.postMessage( name: 'window:toggleFullScreen' , '*');

// host page
window.addEventListener('message', function () 
    if (event.data.name === 'window:toggleFullScreen') 
       document.getElementById(iframeUid).className += ' fullscreen';
    
});

This can translate into a lot of spaghetti code when you start supporting multiple platforms:

button.on('click', (e) => 
    if (inStandalonePage()) 
        window.scrollTo(0, resultsContainer.offsetTop);
    
    else 
        window.parent.postMessage( name: 'scroll', offset: resultsContainer.offsetTop , '*');
    }
});

Imagine doing an equivalent of this for every meaningful DOM interaction in your project. Once you’ve finished shuddering, make yourself a relaxing cup of tea, and read on.

Abstraction Is Key

Rather than forcing our developers to handle these conditionals inside their code, we built an abstraction layer between their content and the environment. We call this layer the ‘wrapper.’

Instead of querying the DOM or native browser events directly, we can now proxy our request through the wrapper module.

import wrapper from 'wrapper';
button.on('click', () => 
    wrapper.scrollTo(resultsContainer.offsetTop);
);

Each platform has its own wrapper implementation conforming to a common interface of wrapper methods. The wrapper wraps itself around our content and handles the complexity for us.


UML diagram showing that when our application calls the standalone wrapper scroll method, the wrapper calls the native scroll method in the host page.


Simple ‘scrollTo’ implementation by the standalone wrapper

The standalone wrapper’s implementation of the scrollTo function is very simple, passing our argument directly to window.scrollTo under the hood.

Now let’s look at a separate wrapper implementing the same functionality for the iframe:


UML diagram showing that when our application calls the embed wrapper scroll method, the embed wrapper combines the requested scroll position with the offset of the iframe before triggering the native scroll method in the host page.


Advanced ‘scrollTo’ implementation by the embed wrapper

The “embed” wrapper takes the same argument as in the “standalone” example but manipulates the value so that the iframe offset is taken into account. Without this addition, we would have scrolled our user somewhere completely unintended.

The Wrapper Pattern

Using wrappers results in code that is cleaner, more readable and consistent between projects. It also allows for micro-optimisations over time, as we make incremental improvements to the wrappers to make their methods more performant and accessible. Your project can, therefore, benefit from the experience of many developers.

So, what does a wrapper look like?

Wrapper Structure

Each wrapper essentially comprises three things: a Handlebars template, wrapper JS file, and a SASS file denoting wrapper-specific styling. Additionally, there are build tasks which hook into events exposed by the underlying scaffolding so that each wrapper is responsible for its own pre-compilation and cleanup.

This is a simplified view of the embed wrapper:

embed-wrapper/
    templates/
        wrapper.hbs
    js/
        wrapper.js
    scss/
        wrapper.scss

Our underlying scaffolding exposes your main project template as a Handlebars partial, which is consumed by the wrapper. For example, templates/wrapper.hbs might contain:

<div class="bbc-news-vj-wrapper--embed">
    >your-application}
</div>

scss/wrapper.scss contains wrapper-specific styling that your application code shouldn’t need to define itself. The embed wrapper, for example, replicates a lot of BBC News styling inside the iframe.

Finally, js/wrapper.js contains the iframed implementation of the wrapper API, detailed below. It is shipped separately to the project, rather than compiled in with the application code — we flag wrapper as a global in our Webpack build process. This means that though we deliver our application to multiple platforms, we only compile the code once.

Wrapper API

The wrapper API abstracts a number of key browser interactions. Here are the most important ones:

scrollTo(int)

Scrolls to the given position in the active window. The wrapper will normalise the provided integer before triggering the scroll so that the host page is scrolled to the correct position.

getScrollPosition: int

Returns the user’s current (normalized) scroll position. In the case of the iframe, this means that the scroll position passed to your application is actually negative until the iframe is at the top of the viewport. This is super useful and lets us do things such as animate a component only when it comes into view.

onScroll(callback)

Provides a hook into the scroll event. In the standalone wrapper, this is essentially hooking into the native scroll event. In the embed wrapper, there will be a slight delay in receiving the scroll event since it is passed via postMessage.

viewport: height: int, width: int

A method to retrieve the viewport height and width (since this is implemented very differently when queried from within an iframe).

toggleFullScreen

In standalone mode, we hide the BBC menu and footer from view and set a position: fixed on our content. In the News App, we do nothing at all — the content is already full screen. The complicated one is the iframe, which relies on applying styles both inside and outside the iframe, coordinated via postMessage.

markPageAsLoaded

Tell the wrapper your content has loaded. This is crucial for our content to work in the News App, which will not attempt to display our content to the user until we explicitly tell the app our content is ready. It also removes the loading spinner on the web versions of our content.

List Of Wrappers

In the future, we envisage creating additional wrappers for large platforms such as Facebook Instant Articles and Apple News. We have created six wrappers to date:

Standalone Wrapper

The version of our content that should go in standalone pages. Comes bundled with BBC branding.

Embed Wrapper

The iframed version of our content, which is safe to sit inside articles or to syndicate to non-BBC sites, since we retain control over the content.

AMP Wrapper

This is the endpoint which is pulled in as an amp-iframe into AMP pages.

News App Wrapper

Our content must make calls to a proprietary bbcvisualjournalism:// protocol.

Core Wrapper

Contains only the HTML — none of our project’s CSS or JavaScript.

JSON Wrapper

A JSON representation of our content, for sharing across BBC products.

Wiring Wrappers Up To The Platforms

For our content to appear on the BBC site, we provide journalists with a namespaced path:

/include/[department]/[unique ID], e.g. /include/visual-journalism/123-quiz

The journalist puts this “include path” into the CMS, which saves the article structure into the database. All products and services sit downstream of this publishing mechanism. Each platform is responsible for choosing the flavor of content it wants and requesting that content from a proxy server.

Let’s take that Donald Trump interactive from earlier. Here, the include path in the CMS is:

/include/newsspec/15996-trump-tracker/english/index

The canonical article page knows it wants the “embed” version of the content, so it appends /embed to the include path:

/include/newsspec/15996-trump-tracker/english/index/embed

…before requesting it from the proxy server:

https://news.files.bbci.co.uk/include/newsspec/15996-trump-tracker/english/index/embed

The AMP page, on the other hand, sees the include path and appends /amp:

/include/newsspec/15996-trump-tracker/english/index/amp

The AMP renderer does a little magic to render some AMP HTML which references our content, pulling in the /amp version as an iframe:

<amp-iframe src="https://news.files.bbci.co.uk/include/newsspec/15996-trump-tracker/english/index/amp" width="640" height="360">
    <!-- some other AMP elements here -->
</amp-iframe>

Every supported platform has its own version of the content:

/include/newsspec/15996-trump-tracker/english/index/amp

/include/newsspec/15996-trump-tracker/english/index/core

/include/newsspec/15996-trump-tracker/english/index/envelope

...and so on

This solution can scale to incorporate more platform types as they arise.

Abstraction Is Hard

Building a “write once, deploy anywhere” architecture sounds quite idealistic, and it is. For the wrapper architecture to work, we have to be very strict on working within the abstraction. This means we have to fight the temptation to “do this hacky thing to make it work in [insert platform name here].” We want our content to be completely unaware of the environment it is shipped in — but this is easier said than done.

Features Of The Platform Are Hard To Configure Abstractly

Before our abstraction approach, we had complete control over every aspect of our output, including, for example, the markup of our iframe. If we needed to tweak anything on a per-project basis, such as add a title attribute to the iframe for accessibility reasons, we could just edit the markup.

Now that the wrapper markup exists in isolation from the project, the only way of configuring it would be to expose a hook in the scaffold itself. We can do this relatively easily for cross-platform features, but exposing hooks for specific platforms breaks the abstraction. We don’t really want to expose an ‘iframe title’ configuration option that’s only used by the one wrapper.

We could name the property more generically, e.g. title, and then use this value as the iframe title attribute. However, it starts to become difficult to keep track of what is used where, and we risk abstracting our configuration to the point of no longer understanding it. By and large, we try to keep our config as lean as possible, only setting properties that have global use.

Component Behaviour Can Be Complex

On the web, our sharetools module spits out social network share buttons that are individually clickable and open a pre-populated share message in a new window.


Screenshot of BBC sharetools section containg Twitter and Facebook social media icons.


BBC Visual Journalism sharetools present a list of social share options

In the News App, we don’t want to share through the mobile web. If the user has the relevant application installed (e.g. Twitter), we want to share in the app itself. Ideally, we want to present the user with the native iOS/Android share menu, then let them choose their share option before we open the app for them with a pre-populated share message. We can trigger the native share menu from the app by making a call to the proprietary bbcvisualjournalism:// protocol.


Screenshot of the share menu on Android with options for sharing via Messaging, Bluetooth, Copy to clipboard, and so on.


Native share menu on Android

However, this screen will be triggered whether you tap ‘Twitter’ or ‘Facebook’ in the ‘Share your results’ section, so the user ends up having to make their choice twice; the first time inside our content, and a second time on the native popup.

This is a strange user journey, so we want to remove the individual share icons from the News app and show a generic share button instead. We are able to do this by explicitly checking which wrapper is in use before we render the component.


Screenshot of the news app share button. This is a single button with the following text: 'Share how you did'.


Generic share button used in the News App

Building the wrapper abstraction layer works well for projects as a whole, but when your choice of wrapper affects changes at the component level, it’s very difficult to retain a clean abstraction. In this case, we’ve lost a little abstraction, and we have some messy forking logic in our code. Thankfully, these cases are few and far between.

How Do We Handle Missing Features?

Keeping abstraction is all well and good. Our code tells the wrapper what it wants the platform to do, e.g. “go full screen.” But what if the platform we’re shipping to can’t actually go full-screen?

The wrapper will try its best not to break altogether, but ultimately you need a design which gracefully falls back to a working solution whether or not the method succeeds. We have to design defensively.

Let’s say we have a results section containing some bar charts. We often like to keep the bar chart values at zero until the charts are scrolled into view, at which point we trigger the bars animating to their correct width.


Screenshot of a collection of bar charts comparing the user's area with the national averages. Each bar has its value displayed as text to the right of the bar.


Bar chart showing values relevant to my area

But if we have no mechanism to hook into the scroll position — as is the case in our AMP wrapper — then the bars would forever remain at zero, which is a thoroughly misleading experience.


Same screenshot of bar charts as before, but bars have 0&#37; width and the values of each bar are fixed at 0&#37;. This is incorrect.


How the bar chart could look if scrolling events aren’t forwarded

We are increasingly trying to adopt more of a progressive enhancement approach in our designs. For example, we could provide a button which will be visible for all platforms by default, but which gets hidden if the wrapper supports scrolling. That way, if the scroll fails to trigger the animation, the user can still trigger the animation manually.


Same screenshot of bar charts as the incorrect 0&#37; bar charts, but this time with a subtle grey overlay and a centered button inviting the user to 'View results'.


We could display a fallback button instead, which triggers the animation on click.

Plans For The Future

We hope to develop new wrappers for platforms such as Apple News and Facebook Instant Articles, as well as to offer all new platforms a ‘core’ version of our content out of the box.

We also hope to get better at progressive enhancement; succeeding in this field means developing defensively. You can never assume all platforms now and in the future will support a given interaction, but a well-designed project should be able to get its core message across without falling at the first technical hurdle.

Working within the confines of the wrapper is a bit of a paradigm shift, and feels like a bit of a halfway house in terms of the long-term solution. But until the industry matures onto a cross-platform standard, publishers will be forced to roll out their own solutions, or use tooling such as Distro for platform-to-platform conversion, or else ignore entire sections of their audience altogether.

It’s early days for us, but so far we’ve had great success in using the wrapper pattern to build our content once and deliver it to the myriad of platforms our audiences are now using.

Smashing Editorial
(rb, ra, il)

See the original post:  

How BBC Interactive Content Works Across AMP, Apps, And The Web

Web Development Reading List #188: Real-World Accessibility, Flexbox Madness, And The Ephemerality Of Things We Build

CSS is an amazing tool which we constantly use but we don’t seem to honor it appropriately. Whenever I see the growing browser support of the :focus-within selector, the much wanted justify-content: space-evenly for Flexbox or how great CSS Grids already work, I feel really grateful to have such awesome tools available to work with.
And with advanced new media queries such as prefers-reduced-motion, screen and (color), or pointer, we get amazing tools to improve accessibility and usability of our websites.

Continued: 

Web Development Reading List #188: Real-World Accessibility, Flexbox Madness, And The Ephemerality Of Things We Build

Web Development Reading List #187: Webpack 3, Assisted Writing, And Automated Chrome Testing

This week, we’ll explore some rather new concepts: What happens if we apply artificial intelligence to text software, for example? And why would a phone manufacturer want its business model to be stolen by competitors? We’ll also take a look at how we can use the new headless Chrome browser for automated testing and learn to build smarter JavaScript bundles with Webpack 3’s new scope hoisting. Sometimes it’s easy to be excited about all the improvements and new things our industry has to offer.

See the article here: 

Web Development Reading List #187: Webpack 3, Assisted Writing, And Automated Chrome Testing

Web Development Reading List #185: Safari 11, New Edge Build, Chrome 59, And CSS Optimization Insights

This week was full of great browser vendor news: Safari 11 was announced with long-awaited features such as WebRTC and tracking protection, and a new Edge build with new CSS features is now available, too. But the past few days also had some valuable articles up their sleeves: about implementing HTTP/2 push, using datetime-local, and slimming down your CSS, for example. I collected everything in this reading list for you, so you don’t miss out on anything.

See original article: 

Web Development Reading List #185: Safari 11, New Edge Build, Chrome 59, And CSS Optimization Insights

Web Development Reading List #182: IPFS Wikipedia, New Webpack CLI, And CSS Grid Breakout

When did you take your last vacation? For many of us, it was probably a long time ago. However, since quite a while, I stumble across more and more stories about companies that take unusual steps vacation-wise. Companies giving their employees a day off each week in summer or going on vacation together as a team building event instead of traveling somewhere just to work.
But while there’s a new generation building their dream work environments, a lot of people still suffer from very bad working conditions.

See more here – 

Web Development Reading List #182: IPFS Wikipedia, New Webpack CLI, And CSS Grid Breakout

Web Development Reading List #177: Getting Started With Components, CT-Header, And New Regular Expressions

From time to time, we need to take some time off, and actually, I’m glad that this reading list is a bit shorter as the ones you’re used to. Because one thing that really stuck with me this week was Eric Karjaluoto’s article.
In his article, he states that, “Taking pride in how busy we are is one of the worst ideas we ever had.” So, how about reading just a few articles this week for a change and then take a complete weekend off to recharge your battery?

Read this article:

Web Development Reading List #177: Getting Started With Components, CT-Header, And New Regular Expressions

Web Development Reading List #159: Code Splitting, A New Bundler, And Blake2x

As developers, are we paid to write code? This challenging question raises concerns about product quality, code quality, and our purpose as developers in a world of coded applications. You’ll find an interesting post that dives deeper into the matter in the “Work & Life” section of our reading list this week.
But we have other amazing resources to look at this week, too: new tools, new tutorials, and we’ll also take some time to reconsider CSS print styles.

View original post here – 

Web Development Reading List #159: Code Splitting, A New Bundler, And Blake2x

Facebook Organic Reach is Dying: Here’s Why It’s a Good Thing

Facebook reach
More and more our News Feeds are full of updates from friends… not companies — but there are benefits to this. Image via Shutterstock.

Facebook wears many hats. It does everything, and is everything. It’s where we turn to celebrate many important life milestones, share our lives with our friends, organize events, consume media and much, much more. But for marketers, it’s an advertising tool.

Social media marketing has changed a great deal over the past few years. One of the biggest changes is Facebook’s shift away from organic reach into a paid marketing channel.

If you manage a Facebook Page, I’m sure you’re familiar with this subject, and you’ve probably noticed a sharp drop in the number of people who are seeing and interacting with your content organically.

As a marketer, this change has been tough to stomach. It’s now much harder to reach your audience than it was a few years ago. And with recent updates that Facebook is, again, shifting its algorithm to focus on friends and family, it’ll be harder still to reach people who are already fans of your page.

Facebook organic reach is hard
TFW you can almost reach your audience… but not quite. Image via Giphy.

Before we dive into why the plight of organic reach is a good thing, let’s first take a look at what brought along this decline in the first place.

Want more awesome content to help you crush your marketing goals?

Sign up to get the latest digital marketing tips delivered straight to your inbox.
By entering your email you’ll receive weekly Unbounce Blog updates and other resources to help you become a marketing genius.

Understanding how social reach is declining

In 2014, Social@Ogilvy released its much-cited report, “Facebook Zero: Considering Life After the Demise of Organic Reach.”

In the report, Ogilvy documented the harsh decline of organic reach between October 2013 and February 2014. In that short period of time, organic reach dropped to around 6% for all pages, and for large pages with more than 500,000 likes, the number was just 2%.

Ogilvy graph

Based on this data, a Facebook Page with around 20,000 fans could expect fewer than 1,200 people to see its posts, and a page with 2 million fans would, on average, reach only 40,000 fans.

The reasoning behind this change from Facebook’s perspective is twofold, as Facebook’s VP of Advertising Technology, Brian Boland, explained in a blog post.

The first reason for the decline in organic reach is purely the amount of content being shared to Facebook. Advances in smartphone technology means we can now create and share this content with just a few swipes of the finger or taps on a screen. More and more of our friends and favorite brands are also active on the platform, meaning competition for attention is higher. Boland explains:

There is now far more content being made than there is time to absorb it. On average, there are 1,500 stories that could appear in a person’s News Feed each time they log onto Facebook. For people with lots of friends and Page likes, as many as 15,000 potential stories could appear any time they log on.

The second reason for the decline in organic reach on Facebook is how the News Feed works. Facebook’s number one priority is to keep its 1.5 billion users happy, and the best way to do that is by showing only the most relevant content in their News Feeds.

Of the 1,500+ stories a person might see whenever they log onto Facebook, News Feed displays approximately 300. To choose which stories to show, News Feed ranks each possible story (from more to less important) by looking at thousands of factors relative to each person.

To a marketer, this may feel like a negative, but it’s actually a good thing, because what we’re left with now is a far more powerful marketing tool than we had when reach was free.

Let me explain…

Why the decline of organic reach is a good thing

When a social network first achieves mainstream popularity (think Facebook circa 2009, Instagram in 2014-15, Snapchat in 2016) organic reach rules the roost. As a marketer, it’s all about figuring out what content your audience craves and giving it to them.

Then, we hit a peak, and suddenly the social network all but transforms into a pay-to-play platform — bringing with it another huge marketing opportunity. At Buffer, it’s something we like to call The Law of the Double Peak:

Buffer double peak

Facebook hit the organic peak in 2014, and since then reach has declined to a point where it’s almost at zero now. But, on the other hand, we’re left with a far more powerful advertising tool than we had before.

It’s also important to remember that before social media — with print, radio, TV, banner ads, direct mail or any other form of advertising — there was no such thing as organic reach. You couldn’t create a piece of content and get it seen by thousands (even millions) with no budget.

Facebook, now, is probably one of the most cost-effective digital ad products we’ve ever seen. It’s the best way to reach a highly targeted audience and drive awareness about your product or service, and probably an even better marketing channel than it was back in 2012 when organic reach hit its peak.

4 ways to maximize the paid marketing opportunities on Facebook

Once you’re over the fact that not everyone on Facebook gets to discover your brand for free anymore…

1. Ensure your ads are relevant

With more than 3 million advertisers all competing for attention in more than a billion users’ News Feeds, Facebook uses what’s called an ad auction to deliver ads.

The ad auction pairs individual ads with particular people looking for an appropriate match. The social network’s ad auction is designed to determine the best ad to show to a person at a given point in time. This means a high-quality, hyper-relevant ad can beat an ad that has a higher advertiser bid, but is lower quality and less relevant.

The two major factors you need to work on to ensure Facebook sees your ad as relevant are your targeting and ad creative.

For example, if you’re targeting a broad audience such as men and women, ages 18–25, living in the United Kingdom, chances are your ad may not be relevant to every person. However, if you were to break your audience down into smaller, more specific groups your message may be more relevant (and therefore successful).

2. Test different messages and creative

There are endless opportunities for testing on Facebook Ads: titles, texts, links, images, age, gender, interests, locations and so on.

The image is the first thing people see when your ad shows up in their News Feed. It’s what grabs their attention and makes them stop and click, which means it’s essential to get the image right. Though, you probably won’t hit the nail on the head first time ‘round. Thankfully, Facebook allows you to upload multiple images for each advert and optimizes to display best performing ones.

Your creative can have a huge difference when it comes to conversions. AdEspresso recommends coming up with at least four different Facebook Ad variations and then testing each one. For example, you might test two different images with two different copy texts (2 images x 2 texts = 4 variations).

AdEspresso also found that creative with a picture of a person performs far better:

Facebook ad variations

When you create ads, plan out a number of variations — changing copy, images and CTAs in order to discover what works best for each audience you’re targeting.

Want more awesome content to help you crush your marketing goals?

Sign up to get the latest digital marketing tips delivered straight to your inbox.
By entering your email you’ll receive weekly Unbounce Blog updates and other resources to help you become a marketing genius.

3. Be specific with your content

Combining the first two points above, targeting to a specific segment using creative that is specifically built for that target audience is incredibly powerful.

Many businesses have a range of customers, all with slightly different needs. For each customer your business is targeting, jot down as much information as you can about them and try to form a few customer personas to create specific ads for.

Then, with your target personas in place, think about how you can use Facebook Ads to target each individual group. This could mean creating an ad set for each group and testing different images and copy within your ads to see what works best for each group.

By tailoring ads to specific personas, you can vastly improve your advert’s relevancy and also serve the needs of your customer better.

4. Pay attention to real metrics

With social media, it can be easy to fall into the trap of measuring only soft metrics — the things that don’t correlate directly with sales or revenue growth, but can still be good indicators of performance. On Facebook, this means things such as Likes, Comments and Shares.

When it comes to paid marketing channels, like Facebook Ads, it’s important to have some solid goals in mind and pay attention to the metrics that translate into your ultimate goal. For example, having a post receive a few hundred Likes or a high engagement rate could be seen as success, but that’s probably not the ultimate goal of your campaign.

Paid advertising on Facebook is a lot like paid-for marketing has always been. For 90% the end goal is sales or, for larger companies, brand awareness. And with paid-for ads you’ll want to be a little stricter with yourself when it comes to measurement. That’s not to say ALL advertising on Facebook must be purely focused on selling — that strategy likely wouldn’t work — but certainly any specific advertising campaigns should be focused on increasing your bottom line.

How do you use Facebook?

I’d love to hear your thoughts on the evolution of Facebook as a marketing channel. How have your strategies changed over recent years? Are you one of the 3 million businesses who advertise on the platform? I’d love to hear your learnings and perspectives too.

Thanks for reading! And I’m excited to join the conversation in the comments.

See original article here: 

Facebook Organic Reach is Dying: Here’s Why It’s a Good Thing

Web Development Reading List #149: CSS Dynamic Colors, Refactoring CSS, And CSP Hashing

Even though we think everything happens in real-time nowadays, we need patience. While technology has been capable of real-time for long now, the “bottleneck” are human beings. Whether it’s a pull request that’s waiting for review since days or weeks or an email response, we need to keep in mind that delays might happen for a good reason.
Different people have different priorities, they might be focusing on something else at the moment, or they just take a break.

Read article here:

Web Development Reading List #149: CSS Dynamic Colors, Refactoring CSS, And CSP Hashing

Web Development Reading List #148: CSS Color Syntax Change, Browser News, And Hidden Expectations

I shut down my browser on Wednesday, accidentally having a setting switched on that clears history and all sessions. First, I was sad to have lost many tabs with articles I stored “for later”. At the same time, it felt refreshing, liberating to have a clean browser window with zero tabs open. So my new goal is to start work in the morning with a completely clean browser window at least once a week.

Read original article:  

Web Development Reading List #148: CSS Color Syntax Change, Browser News, And Hidden Expectations