How to Write a Blog Post Outline for WordPress (8 Steps)

Want to learn how to write a blog post outline for WordPress?

Wring a blog post outline takes the stress out of having to start your draft from scratch. With an outline, you can overcome writer’s block and order your blog post in a logical, easy-to-read structure.

In this article, we’ll share our step-by-step guide on how to write a blog post outline for your WordPress website.

How to write a blog post outline for WordPress

Why Do You Need a Blog Post Outline?

If you’re a content writer, blogger, or content manager, you may be wondering whether it’s really worth the trouble to write an outline for a blog post.

The truth is, if you really want to write a great blog post, you’ll need to write an outline first. Here’s why:

Outlines Beat Blank Page Syndrome

Every writer knows the feeling of opening their Google Doc or the WordPress editor and staring at the blank page. You may feel overwhelmed, maybe start to sweat, and then overthink the entire post and even procrastinate the writing entirely.

With outlines, you’ll never feel intimidated before writing a new blog post. You’ll break down your posts into topics, subheadings, and talking points so you know what to write about.

Outlines Help You Write Faster

Creating an outline upfront is another way to front-load your research. You can analyze competitors in search results to plan your content. This prevents you from being stuck with research during the writing process.

Separating research from writing ensures you have all the necessary resources in hand when it’s time to write. That way, writing blog posts becomes a breeze.

Outlines Get You and Your Editor On the Same Page

If you work closely with a content manager or editor, you may want to run your outline with them before writing. It gives both people an idea of what sections to focus on, what elements to include or omit, and a general angle to write the article.

The last thing you want to do is have to rewrite an entire piece because you misunderstood what the article should’ve been about.

Outlines Help You Answer the Most Important Questions

One of the best ways to rank your content is to answer questions that people are most commonly asking.

You can use the Keyword Generator Tool from WPBeginner. It’s a free way to generate hundreds of keyword ideas and popular questions on Google. This ensures your blog content will be optimized to match user search intent.

That said, here are the 8 steps to writing the best blog post outline to help you write high-quality content that search engines love.

You can use the links below to jump to any step you want, in case you’re already in the process of outlining a blog post.

Step 1. Choose Your Topic

Creating a blog post outline starts with knowing what you want to write about. That means you’ll need to decide on a topic.

Start by brainstorming a few blog topics you’d like to cover. If you’re already familiar with the niche, there may be a few burning issues you want to address.

Otherwise, a good way to find topics is to use All in One SEO’s Search Statistics feature. All in One SEO is the best content optimization tool for WordPress sites, giving you insights on improving your SEO to boost rankings.

Essentially, the Search Statistics function provides a central location to see how your content is doing on Google.

This lets you keep tabs on your blog’s content performance through the content ranking report. As a result, you can identify opportunities for complementary keywords to the blog posts you already rank for.

Start by installing and activating the AIOSEO plugin. If you need instructions, follow our tutorial on how to install a WordPress plugin.

Once activated, go to the All in One SEO ≫ Search Statistics in the WordPress dashboard.

Search statistics in the all in one seo menu

Once you’re in the Search Statistics dashboard, you’ll see SEO Statistics, Keyword Positions, and Content Performance.

Scroll down, and under the Content Performance tab, you’ll find the Top Pages, Top Losing, and Top Winning keywords. This report gives you crucial data like Clicks, Impressions, Position, and the Difference in ranking position.

Search statistics content performance

You should review your Top Pages and note all the keywords performing well for you.

Use Similar Tools

Additionally, you can use a tool like Semrush to find blog post topics. You’ll navigate to their Content Marketing ≫ Topic Research.

Choose a topic and hit ‘Get content ideas.’ In this case, we’ll use one of our top-performing keywords, ‘how to garden,’ to find new keywords.

Topic research in SEMRush

If you want to find trending topics, just toggle the switch beside ‘Trending subtopics first.’ You notice a list of cards, and each of them includes a topic followed by subtopic headlines.

Browse through the headlines to find any topics that resonate with your audience. Once you find one, click ‘Show more.’

SEMRush content marketing topics

You’ll see an expanded list of headlines, related questions, and related searches around the topic.

This should give you enough blog post ideas to create an entire content calendar.

Blog post topics in SEMRush

Pick one topic you want to write about first and then move on to the next step.

Step 2. Figure Out Your Content Format

There’s no magic formula that works for every type of content. Sometimes, the format is obvious. If you’re covering a topic on ‘how to start a garden,’ it will probably be a step-by-step guide. If you’re writing about gardening tips, it may be a listicle.

But it’s not always so straightforward. Is the topic ‘best gardening tool’ a list of gardening tools, a review of a particular equipment, or an opinion article about the best tool?

The best way to decide is to simply check what’s ranking for that topic on Google. After a quick Google search, you’ll see that people searching for the ‘best gardening tools’ are actually looking for a list of tools for that topic.

Best gardening tools

Now you know it’s better to choose a listicle as the content format for this topic.

That said, here are some of the most popular content formats and when to use them.

  • How-to posts: When you need to teach readers how to do something step by step.
  • List posts: Share a curated list of great ideas in one place.
  • Beginner’s guide posts: When you want to simplify a technical topic to a new audience.
  • ‘What is’ posts: When you need to define a term or answer a question.
  • X vs. Y posts: When comparing what makes your product better than a competitor.
  • Statistics post: When you want to provide a comprehensive list of stats about a particular industry.
  • News posts: When you want to announce a new product or feature you plan to release.
  • Case study posts: For deep dives into a subject backed by heavy research.

Each of these post types may have an outline that looks different, but the same steps go into creating each one.

Step 3. Decide on Your Article’s Angle

With any topic, you can choose which direction you want to take. For example, if your topic is ‘how to plant a garden,’ then you may have to decide if you mean a flower garden or a vegetable garden.

The angle makes your article interesting and unique to readers. One of the easiest ways to come up with an angle you should cover is to look at top-ranking pages on Google.

At WPBeginner, we always angle our blog posts to help small businesses like yours. Take our blog post covering the ‘best email marketing services.’

Rather than have a huge list of everything, our experts have chosen services that cater the best to small businesses because that’s what our audience really wants.

Best email marketing services for small businesses

As you can see in the image above, we rank number 1 for the topic, and the number 2 result from Brevo is also looking at business email services.

If you find that the top search results are approaching the topic from a particular perspective, you should adjust your own outline to match so that you can outrank them.

Step 4. Analyze the Top-Ranking Pages and Figure Out What You Need to Cover

Once you have the angle, you’re ready to start building the actual structure and layout of your outline.

While you can use ChatGPT prompts to write an outline, we recommend manually analyzing top posts in search to see what actually ranks.

First, you can open up a new post on WordPress. To do this, go to Posts ≫ Add New in your WordPress admin area.

Add new blog post

You’ll be directed to a blank page where you write your blog post.

We recommend writing the outline in the block editor of WordPress so that you can use AIOSEO‘s features to optimize your blog post along the way.

For example, you can scroll down to ‘AIOSEO Settings.’ Next to ‘Post Title,’ you can type in your blog post title and see if you meet the character count requirements.

Post title in All in One SEO

Next, you want to analyze the top-ranking content on Google to determine what headings and information to cover.

Type in your search query into the search engine and click on all the top-ranking posts.

Pest control for gardens

Also, be sure to look at the People Also Ask section in Google search results.

It compiles the most commonly asked questions on a topic.

People also ask section

You may want to cover these questions as a heading or FAQ section to ensure you’re thoroughly answering all the queries searchers are looking for.

Remember, it is important to group the headings and organize them in a logical manner.

For example, before the reader can dive into the solution, you need to explain the problem.

That’s why you should include headings such as ‘What are garden pests’ and ‘Types of garden pests to look out for.’ Then, you would dive into the methods for keeping pests out of your garden. In the end, you would maybe add the question, ‘What is the best treatment for garden pests?’ so users know the most effective solution.

Blog outline in WordPress

And if you want to improve the user experience, you can also add a table of contents to your blog post outline.

If you’re using AIOSEO, you can easily add a Table of Contents using the block editor by simply typing in ‘/toc’ and selecting the ‘AIOSEO – Table of Contents’ block.

AIl in One SEO table of contents

A table of contents will appear within your blog post that links to each of the headings below the block.

Having one of these helps readers easily navigate to any section of the blog post so they can quickly find the information they need without wasting time reading background information they may already know.

Step 5. Add Bullets Under Each Heading

Once you have your main headings, you can flesh out each section so you know what you’ll be writing in each section and what information to include.

Simply write the main points for each section on the information you’re going to cover, examples you’re going to highlight, and stats you’re going to cite.

Make sure to gather all your research articles as well. That way, you can cite these sources or know when to refer to them when writing your piece. You can source your research anywhere, including other top-ranking content, social media, YouTube, or scientific papers.

After adding bullet points under each section, you should also add internal links to include in each section. Internal linking is an important aspect of SEO, and every piece of content should include them.

With All in One SEO’s Link Assistant feature, you can easily find linking opportunities for your blog posts. First, head over to All in One SEO ≫ Link Assistant in WordPress.

Internal linking with link assistant

Next, simply go to the ‘Links Reports’ tab. This is where you’ll find all of your posts and their internal and external links for each of them.

On this page, you can filter by Linking Opportunities or Orphaned Posts.

Links reports in All in One SEO

Linking Opportunities is where you’ll find suggestions on where to add internal links in each post, while the Orphaned Posts show you all the articles that don’t have any internal links to them.

The Links Report also shows a table with columns for the number of links in each post, if they’re internal or external, and the number of suggestions AIOSEO has for new links you can include.

Under the Linking Opportunities section at the top, just choose a post in which you want to add internal links. In this case, pick the blog post outline you’ve started.

Link suggestion

You’ll see suggestions to add internal links. Simply review the phrases and click ‘Add Link’ to include them in your blog outline.

You can also click ‘Dismiss Suggestion’ if you don’t find a link suggestion suitable.

Add internal link suggestion

Before you move on to the next steps, you want to check whether your outline structure makes sense. Ask yourself questions like:

  • Does the post cover the most important questions the audience wants to know?
  • Does the article answer the main question quickly?
  • Is this post structured in a way that makes sense?
  • Is all of the information on this page necessary?

If you make the reader’s experience a top priority, you’ll stay on the right track. Make sure that your headings accurately reflect the key takeaways of your post to improve readability.

Step 6. Create a Compelling Post Title

Your post title can have a huge impact on your SEO rankings and traffic. Its primary job is to tell search engines and visitors what they can expect from a blog post.

First impressions matter, and your blog post’s title is the first thing visitors will see when performing a search. This is your chance to make a great first impression.

To better optimize your on-page SEO, we recommend using the Headline Analyzer from All in One SEO.

Head over to All in One SEO ≫ SEO Analysis in your WordPress dashboard. Then click on the ‘Headline Analyzer’ tab.

Type in your title into the search bar and click ‘Analyze.

Headline analyzer in All in One SEO

From there, it’ll give you suggestions and tell you your title is optimized for search.

You may get feedback telling you that your character or word count is too short or doesn’t have enough emotional appeal to it to grab attention.

Headline analyzer score

Here are the main factors that All in One SEO Headline Analyzer uses to grade your title:

  • Word Balance: This helps you find the perfect balance between common, uncommon, emotional, and power words. Emotional words drive more clicks and power to make your title stand out.
  • Sentiment: The Headline Analyzer checks whether your title has a neutral, positive, or negative sentiment. Positive emotions result in the most click-throughs. For example, our blog post ‘Best Blogging Niche – 7 That Will Make Money (Easily)‘ has a positive sentiment.
  • Character and word count: Your title will be judged by how many characters and words it contains. Headlines about 55 characters long will display fully in search results, and titles should be over 5 words.

You can also use WPBeginner’s free Headline Analyzer for more help in crafting engaging blog post titles.

For more information, please see our guide on how to use a headline analyzer in WordPress to improve SEO titles.

When writing blog posts, it’s a good idea to include related keywords to help search engines better understand your article.

Specifically, you want to find LSI keywords (latent semantic indexing). These are words and phrases that closely tie to the target keyword but aren’t quite synonyms.

For example, if you write about ‘pest control for gardens,’ LSI keywords may include ‘natural pest control’ and ‘organic pest prevention methods.’

LSI keywords are important because they help search engines understand the overall topic of the blog post.

Search engines scan your content for contextually related words to determine your article topic and relevance to the query. LSI keywords also help you rank in the right queries and put your content in front of the right audience.

You’ll want to jot down a small list of important LSI keywords and try to add them in sections of your post where they may fit.

To find LSI keywords, you can use the WPBeginner Keyword Research Tool. It’s completely free to use, and you’ll receive hundreds of keyword ideas.

You can organize keywords by different types of questions as well, which is a great way to find more subtopics for your blog post.

WPBeginner keyword generator tool

When you’ve found the keywords you want to focus on, you can check to see their volume and difficulty by using keyword research tools like Ahrefs or Semrush.

In this example, we’ll use the Semrush Keyword Magic tool to generate related long-tail keyword phrases.

Visitors who come to your website via long-tail keywords are often further along in their buying journey or looking for specific information. This makes them more likely to convert into customers.

Start by entering a single seed keyword into the Semrush Keyword Magic Tool and hit ‘Search.’

Seed keyword in SEMRush keyword magic tool

Next, review the suggested keywords of related topics to find niche long-tail phrases.

Going back to our gardening example, the results in the screenshot below have plenty of related keywords:

List of keywords in SEMRush

Also, you can sort by Questions to sort out question-based keywords. There are even options to choose how you want the results to match your initial search.

Match modifiers include Broad Match, Phrase Match, Exact Match, or Related. Use these to broaden or narrow down the keyword selection to your liking.

Underneath that, you have the option to filter by Search Volume, Keyword Density (how hard it is to rank for a specific keyword), Intent, CPC, and others.

Filters for SEMRush keyword magic tool

You can also use the Google Autocomplete to find LSI keywords.

Just type in your phrase and review the suggestions.

Google autocomplete

Another method is to look at related searches at the bottom of the search results.

Like the autocomplete suggestions, they provide clues about related words and phrases worth mentioning in your blog post.

Related searches

Step 8: Complete Your Outline

At this point, you should have a fully fleshed-out draft with all of your headings, subheadings, and any important bullet points. You’ve included any research articles and keywords in front of you, giving you all the information needed to write a great blog post.

Here’s what a complete blog outline in WordPress may look like. Keep in mind that this process is highly flexible, and you may need to adjust the outline based on your needs.

Example blog outline

Before you begin writing, it’s a good idea to send your outline to an editor, colleague, or content manager. They can point out things you’ve missed or inaccuracies.

Once everything looks good to go, you’re ready to begin your draft.

We hope this article has helped you learn how to write an in-depth outline for blog posts that actually drive traffic. If you want to learn more about blogging, you can check out our post on how to start a WordPress blog or our post on how to increase your blog traffic.

If you liked this article, then please subscribe to our YouTube Channel for WordPress video tutorials. You can also find us on Twitter and Facebook.

The post How to Write a Blog Post Outline for WordPress (8 Steps) first appeared on WPBeginner.

Fancy Image Decorations: Outlines and Complex Animations

We’ve spent the last two articles in this three-part series playing with gradients to make really neat image decorations using nothing but the <img> element. In this third and final piece, we are going to explore more techniques using the CSS outline property. That might sound odd because we generally use outline to draw a simple line around an element — sorta like border but it can only draw all four sides at once and is not part of the Box Model.

We can do more with it, though, and that’s what I want to experiment with in this article.

Fancy Image Decorations series

Let’s start with our first example — an overlay that disappears on hover with a cool animation:

We could accomplish this by adding an extra element over the image, but that’s what we’re challenging ourselves not to do in this series. Instead, we can reach for the CSS outline property and leverage that it can have a negative offset and is able to overlap its element.

img {
  --s: 250px; /* the size of the image */
  --b: 8px;   /* the border thickness*/
  --g: 14px;  /* the gap */
  --c: #4ECDC4;

  width: var(--s);
  aspect-ratio: 1;
  outline: calc(var(--s) / 2) solid #0009;
  outline-offset: calc(var(--s) / -2);
  cursor: pointer;
  transition: 0.3s;
}
img:hover {
  outline: var(--b) solid var(--c);
  outline-offset: var(--g);
}

The trick is to create an outline that’s as thick as half the image size, then offset it by half the image size with a negative value. Add in some semi-transparency with the color and we have our overlay!

Diagram showing the size of the outline sround the image and how it covers the image on hover.

The rest is what happens on :hover. We update the outline and the transition between both outlines creates the cool hover effect. The same technique can also be used to create a fading effect where we don’t move the outline but make it transparent.

Instead of using half the image size in this one, I am using a very big outline thickness value (100vmax) while applying a CSS mask. With this, there’s no longer a need to know the image size — it trick works at all sizes!

Diagram showing how adding a mask clips the extra outline around the image.

You may face issues using 100vmax as a big value in Safari. If it’s the case, consider the previous trick where you replace the 100vmax with half the image size.

We can take things even further! For example, instead of simply clipping the extra outline, we can create shapes and apply a fancy reveal animation.

Cool right? The outline is what creates the yellow overlay. The clip-path clips the extra outline to get the star shape. Then, on hover, we make the color transparent.

Oh, you want hearts instead? We can certainly do that!

Imagine all the possible combinations we can create. All we have to do is to draw a shape with a CSS mask and/or clip-path and combine it with the outline trick. One solution, infinite possibilities!

And, yes, we can definitely animate this as well. Let’s not forget that clip-path is animatable and mask relies on gradients — something we covered in super great detail in the first two articles of this series.

I know, the animation is a bit glitchy. This is more of a demo to illustrate the idea rather than the “final product” to be used in a production site. We’d wanna optimize things for a more natural transition.

Here is a demo that uses mask instead. It’s the one I teased you with at the end of the last article:

Did you know that the outline property was capable of so much awesomeness? Add it to your toolbox for fancy image decorations!

Combine all the things!

Now that we have learned many tricks using gradients, masks, clipping, and outline, it’s time for the grand finale. Let’s cap off this series by combine all that we have learned the past few weeks to showcase not only the techniques, but demonstrate just how flexible and modular these approaches are.

If you were seeing these demos for the first time, you might assume that there’s a bunch of extra divs wrappers and pseudo-elements being used to pull them off. But everything is happening directly on the <img> element. It’s the only selector we need to get these advanced shapes and effects!

Wrapping up

Well, geez, thanks for hanging out with me in this three-part series the past few weeks. We explored a slew of different techniques that turn simple images into something eye-catching and interactive. Will you use everything we covered? Certainly not! But my hope is that this has been a good exercise for you to dig into advanced uses of CSS features, like gradients, mask, clip-path, and outline.

And we did everything with just one <img> element! No extra div wrappers and pseudo-elements. Sure, it’s a constraint we put on ourselves, but it also pushed us to explore CSS and try to find innovative solutions to common use cases. So, before pumping extra markup into your HTML, think about whether CSS is already capable of handling the task.

Fancy Image Decorations series


Fancy Image Decorations: Outlines and Complex Animations originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

Using the `outline` Property as a Collapsable Border

The outline property in CSS draws a line around the outside of an element. This is quite similar to the border property, the main exception being that outline isn’t a part of the box model. It is often used for highlighting elements, for example, the :focus style.

In this article, let’s put a point on it, leaning into what outline is good at:

  1. They can be collapsed with each other (trickery!) because they technically “take up no space.”
  2. Showing and hiding outlines, or changing outline-width, doesn’t trigger layouts (which is good for performant animations and transitions).

Easier faux-table cell borders

Below is an example of a list that is laid out as a grid, making it look a bit like a table layout. Every cell has a minimum width, and will grow/shrink as the container becomes wider/narrower.

We could use border to pull this off, like this:

But in order to make an even border around each cell — never doubling up or missing — it’s a cumbersome process. Above, I used a border on all sides of each “cell” then negative margins to overlap them and prevent doubling. That meant clipping off the border on two sides, so the borders had to be re-applied there on the parent. Too much fiddly work, if you ask me.

Even having to hide the overflow is a big ask, which you have to do because, otherwise, you’ll trigger scrollbars unless you resort to even thicker trickery, like using absolutely-positioned pseudo elements.

Showing a flat table with seven columns and four rows, each cell numbered sequentially, 1 through 28. The table has a white background and block text and the borders are black around each cell with ample padding.

Check out the same result, visually, only using outline instead:

The code here is much cleaner. There is no real trickery at play. Each “cell” just has an outline around it, and that’s it.

Border in animation

Changing border-width will always trigger layout, no matter if it is actually needed.

Showing the paint rendering results from a performance test where a layout change is shown in the middle of the results taking 58.4 milliseconds to complete.

In addition, due to Chrome’s special handling of sub-pixels for border widths, animating the border-width property makes the entire border shake (which I think is strange). Firefox doesn’t have this issue.

Showing another performance test, this time with no layout triggered in the results.

There are pros and cons when it comes to animating borders. Check out Stephen Shaw’s post from a while back for an example of the performance implications.

There are some gotchas

Of course there are. Like most other CSS properties, there are a few “gotchas” or things to know when working with the outline property:

  1. Rounded outlines are only supported in Firefox at the time of writing. I imagine other browsers will eventually support them as well.
  2. An outline always goes around all the sides. That is to say it’s not a shorthand property like, say, border; so no outline-bottom, and so on.

But we can work around these limitations! For example, we can use add a box-shadow with no blur radius as an alternative. But remember: box-shadow has a higher performance cost than using either outline and border.

That’s it!

Will you always be working on something that calls for faking a table with an unordered list? Unlikely. But the fact that we can use outline and its lack of participation in the box model makes it interesting, particularly as a border alternative in some cases.

Maybe something like this tic-tac-toe board Chris put together several years ago could benefit from outline, instead of resorting to individually-crafted cell borders. Challenge accepted, Mr. Coyier? 😉


The post Using the `outline` Property as a Collapsable Border appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Platform News: Rounded Outlines, GPU-Accelerated SVG Animations, How CSS Variables Are Resolved

In the news this week, Firefox gets rounded outlines, SVG animations are now GPU-accelerated in Chrome, there are no physical units in CSS, The New York Times crossword is accessible, and CSS variables are resolved before the value is inherited.

Let’s jump in the news!

Rounded outlines are coming to Firefox

The idea to have the outline follow the border curve has existed ever since it became possible to create rounded borders via the border-radius property in the mid 2000s. It was suggested to Mozilla, WebKit, and Chromium over ten years ago, and it’s even been part of the CSS UI specification since 2015:

The parts of the outline are not required to be rectangular. To the extent that the outline follows the border edge, it should follow the border-radius curve.

Fast-forward to today in 2021 and outlines are still rectangles in every browser without exception:

But this is finally starting to change. In a few weeks, Firefox will become the first browser with rounded outlines that automatically follow the border shape. This will also apply to Firefox’s default focus outline on buttons.

Three sets of round yellow buttons, comparing how Chrome, Firefox, and Safari handle outlines.

Please star Chromium Issue #81556 (sign in required) to help prioritize this bug and bring rounded outlines to Chrome sooner rather than later.

SVG animations are now GPU-accelerated in Chrome

Until recently, animating an SVG element via CSS would trigger repaint on every frame (usually 60 times per second) in Chromium-based browsers. Such constant repainting can have a negative impact on the smoothness of the animation and the performance of the page itself.

The latest version of Chrome has eliminated this performance issue by enabling hardware acceleration for SVG animations. This means that SVG animations are offloaded to the GPU and no longer run on the main thread.

Side by side comparison of the Performance tab in Chrome DevTools.
In this example, the SVG circle is continuously faded in and out via a CSS animation (see code)

The switch to GPU acceleration automatically made SVG animations more performant in Chromium-based browsers (Firefox does this too), which is definitely good news for the web:

Hooray for more screen reader-accessible, progressively enhanced SVG animations and less Canvas.

There cannot be real physical units in CSS

CSS defines six physical units, including in (inches) and cm (centimeters). Every physical unit is in a fixed ratio with the pixel unit, which is the canonical unit. For example, 1in is always exactly 96px. On most modern screens, this length does not correspond to 1 real-world inch.

The FAQ page of the CSS Working Group now answers the question why there can’t be real physical units in CSS. In short, the browser cannot always determine the exact size and resolution of the display (think projectors). For websites that need accurate real-world units, the Working Group recommends per-device calibration:

Have a calibration page, where you ask the user to measure the distance between two lines that are some CSS distance apart (say, 10cm), and input the value they get. Use this to find the scaling factor necessary for that screen (CSS length divided by user-provided length).

This scaling factor can then be set to a custom property and used to compute accurate lengths in CSS:

html {
  --unit-scale: 1.428;
}

.box {
  /* 5 real-world centimeters */
  width: calc(5cm * var(--unit-scale, 1));
}

The Times crossword is accessible to screen reader users

The NYT Open team wrote about some of the improvements to the New York Times website that have made it more accessible in recent years. The website uses semantic HTML (<article>, <nav>, etc.), increased contrast on important components (e.g., login and registration), and skip-to-content links that adapt to the site’s paywall.

Furthermore, the Games team made the daily crossword puzzle accessible to keyboard and screen reader users. The crossword is implemented as a grid of SVG <rect> elements. As the user navigates through the puzzle, the current square’s aria-label attribute (accessible name) is dynamically updated to provide additional context.

Screenshot of the crossword game with an open screen reader dialog announcing what is on the screen.
The screen reader announces the clue, the number of letters in the solution, and the position of the selected square

You can play the mini crossword without an account. Try solving the puzzle with the keyboard.

CSS variables are resolved before the value is inherited

Yuan Chuan recently shared a little CSS quiz that I didn’t answer correctly because I wasn’t sure if a CSS variable (the var() function) is resolved before or after the value is inherited. I’ll try to explain how this works on the following example:

html {
  --text-color: var(--main-color, black);
}

footer {
  --main-color: brown;
}

p {
  color: var(--text-color);
}

The question: Is the color of the paragraph in the footer black or brown? There are two possibilities. Either (A) the declared values of both custom properties are inherited to the paragraph, and then the color property resolves to brown, or (B) the --text-color property resolves to black directly on the <html> element, and then this value is inherited to the paragraph and assigned to the color property.

Two CSS rulesets, one as Option A and the other as Option B, both showing how variables are inherited and resolved between elements.

The correct answer is option B (the color is black). CSS variables are resolved before the value is inherited. In this case, --text-color falls back to black because --main-color does not exist on the <html> element. This rule is specified in the CSS Variables module:

It is important to note that custom properties resolve any var() functions in their values at computed-value time, which occurs before the value is inherited.


The post Platform News: Rounded Outlines, GPU-Accelerated SVG Animations, How CSS Variables Are Resolved appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

:focus-visible Support Comes to Firefox

Look at that! The :focus-visible pseudo-selector is now supported in Firefox, as of version 85 which shipped yesterday. I had to rush over to the MDN Docs just to confirm, and yep, the :focus-visible page has been updated to reflect the news.

What’s so cool about :focus-visible? It’s all about the blue focus ring that displays around elements that are in focus. It’s sort of a happy medium between loving the outline for accessibility purposes (gotta know what element is selected when tabbing on a keyboard) but not-really-loving how it looks (gotta have everything follow brand).

The strategy has largely been an all-or-nothing choice between using a custom outline when any element is in :focus (great, but that means for both keyboard tabbing and mouse clicks) or ditching the outline altogether (not great, like ever). :focus-visible accomplishes the same thing as :focus, but uses a browser’s knowledge of user inputs (or heuristics) to determine whether the focus is coming from a keyboard or a mouse.

(Are a browser’s heuristics perfect at determining the input? That depends. Things get murky once we start factoring in things like touch interactions.)

That means, we get to remove the default focus ring (yay!) for the right types of interactions (double yay!) and display our own custom styles while we’re at it (triple yay!). Allow me to pluck Andy Adams’ fine example straight from our almanac. Note that :focus-visible cannot remove the focus ring like :focus can, so the two are used together:

.next-image-button:focus {
  outline: none;
}

.next-image-button:focus-visible {
  outline: 3px solid blanchedalmond; /* That'll show 'em */
}

Chrome implemented :focus-visible back in 2018. Firefox had it’s own prefixed version, :-moz-focusring, prior to this implementation. Safari? Go vote for the feature!

Igalia is gathering funding and working on getting it into Safari! Here’s Brian Kardell on this.


The post :focus-visible Support Comes to Firefox appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

The :focus-visible Trick

Always worth repeating: all interactive elements should have a focus style. That way, a keyboard user can tell when they have moved focus to that element.

But if you use :focus alone for this, it has a side effect that a lot of people don’t like. It means that when you click (with a mouse) on an interactive element, you’ll see the focus style. Arguably, you don’t need that feedback as a mouse user, because you just moved your cursor there and clicked. Whatever you think of that, it’s annoyed so many people over the years that they remove focus styles entirely, which is a gnarly net loss for accessibility on the web.

What if we could apply focus styles only when the keyboard is used to focus something, not the mouse? Lea Verou put a finger on this a few years back:

That was in response to Chrome dropping the feature behind a flag. Clever clever.

Fast forward a couple of years, Chrome is releasing it without a flag. They are on board with Lea’s idea:

By combining :focus-visible with :focus you can take things a step further and provide different focus styles depending on the user’s input device. This can be helpful if you want the focus indicator to depend on the precision of the input device:

/* Focusing the button with a keyboard will show a dashed black line. */
button:focus-visible {
  outline: 4px dashed black;
}
  
/* Focusing the button with a mouse, touch, or stylus will show a subtle drop shadow. */
button:focus:not(:focus-visible) {
  outline: none;
  box-shadow: 1px 1px 5px rgba(1, 1, 0, .7);
}

I might suggest trying those selectors without the button, making them globally applied!

There is more to dig into, so I’ll link up some more stuff here:

  • The Chromium Blog post covers the heuristics of the selector. It’s tricky. It’s like there is an algorithm to determine if :focus-visible is going to match or not, which you just largely need to trust. It also covers the idea that Firefox has long had :-moz-focusring, but the behavior is different enough that they don’t recommend using it if you’re shooting for consistent behavior.
  • Matthias Ott blogged about it with some good info, like using the official polyfill and how to look at the styles properly in DevTools (there is a new checkbox for it).
  • We’ve covered this before. In that, we noted Lea’s tweet that she thought usage would explode when it ships for real. Let’s see (and hope)!
  • Our almanac entry has a bunch of details.


The post The :focus-visible Trick appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Copy the Browser’s Native Focus Styles

Remy documented this the other day. Firefox supports a Highlight keyword and both Chrome and Safari support a -webkit-focus-ring-color keyword. So if you, for example, have removed focus from something and want to put it back in the same style as the browser default, or want to apply a focus style to an element when it isn’t directly in focus itself, this can be useful.

For example:

button:focus + span {
  outline: 5px auto Highlight;
  outline: 5px auto -webkit-focus-ring-color;
}

Looks good to me. It’s especially helpful with the sorta weird new Chrome double-outline style that would be slightly tricky to replicate otherwise.

Chrome 84
Safari 13.1
Firefox 80


The post Copy the Browser’s Native Focus Styles appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Having a Little Fun With Custom Focus Styles

Every front-end developer has dealt or will deal with this scenario: your boss, client or designer thinks the outline applied by browsers on focused elements does not match the UI, and asks you to remove it. Or you might even be looking to remove it yourself.

So you do a little research and find out that this is strongly discouraged, because the focus outline is there for a reason: it provides visual feedback for keyboard navigation (using the Tab key), letting users who can't use a mouse or have a visual impairment know where they are on the screen.

This button shows a focus state with Chrome's default outline style.

That doesn't mean you're stuck with this outline, though. Instead of removing it, you can simply replace it with something else. That way, you’ll keep your interface accessible and get more flexibility on how it looks, so you can better match your UI.

You can start by removing the default browser outline by selecting the focused state of the element and applying outline: none. Then, you may choose from each of the options ahead to replace it:

Change the background color

This works best for elements that can be filled, such as buttons. Select the focused state of the element and apply a contrasting background color to it. The higher the contrast the better because subtle changes may not be strong enough visual cues, particularly in cases where with color blindness and low-vision.

In the example below, both background and border color change; you may pick either or both.

Click or focus with the Tab key to view how this state looks.

See the Pen
Elements replacing native outline focus with background color
by Lari (@larimaza)
on CodePen.

Change the text color

If the element has any text, you can select the focused state and change its color. This also works for icons applied with mask-image; you can select the icon as a descendant of the focused element and change its background color, like the example button below.

See the Pen
Elements replacing native outline focus with text and icon color
by Lari (@larimaza)
on CodePen.

Again, contrast is key. You may also consider using an underline on text links and making it part of the changed state because, as the Web Content Accessibility Guidelines state:

Color is not used as the only visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element. (Level A)
Understanding Success Criterion 1.4.1

Apply a box shadow

The box-shadow property can do exactly the same job as the outline, except it's much more powerful — you can now control its color, opacity, offset, blur radius and spread radius. And if a border-radius is specified, the box shadow follows the same rounded corners.

See the Pen
Elements replacing native outline focus with box shadow
by Lari (@larimaza)
on CodePen.

You can get really creative with this technique (seriously though, don't do this):

See the Pen
Elements replacing native outline focus with insane box shadow
by Lari (@larimaza)
on CodePen.

This works for virtually any type of focusable element, like toggles, checkboxes, radio buttons and slides.

See the Pen
Toggle and radio button replacing native outline focus with box shadow
by Lari (@larimaza)
on CodePen.

Increase the element's size

As an alternative to color change, you may also resort to subtle size modification as focus feedback. In this example, we're using transform: scale.

See the Pen
Elements replacing native outline focus with transform scale
by Lari (@larimaza)
on CodePen.

The key here is subtlety. Extreme size changes may cause content reflow, not to mention a poor experience for those who prefer reduced motion.

Replicate existing hover styles

If the element already has a contrasting hover style, you can simply take that style and apply it for the focused state as well. This is a rather elegant solution, as you don't have to add any new colors or outlines to the interface.

Here’s an example where both the focus and hover states adopt a high contrast to the background of an element’s default style:

See the Pen
Elements replacing native outline focus with hover styles
by Lari (@larimaza)
on CodePen.

Bonus: Customize the default outline

Everything we’ve looked at so far takes the assumption that we want to remove the focus outline altogether. We don’t have to! In fact, it’s a border that we can customize.

button:focus {
  outline: 3px dashed orange;
}

That’s shorthand and could have been written this way if we want to fine-tune the styles:

button:focus {
  outline-width: 3px;
  outline-style: dashed;
  outline-color: orange;
}

One additional superpower we have is the outline-offset property, which is separate from the outline shorthand property but can be used alongside it to change the position of the focus ring:

button:focus {
  outline: 3px dashed orange;
  outline-offset: 10px;
}

Conclusion

You can mix and match all of these options to get custom styles that look appropriate for each component type within your interface.

And it’s worth repeating: Don't forget to use stark color contrasts and other visual cues in addition to color when adopting custom focus states. Sure, we all want an experience that aligns with our designs, but we can adhere to good accessibility practices in the process. The W3C recommends this tool to test the contrast of colors values against the WCAG guidelines.

The post Having a Little Fun With Custom Focus Styles appeared first on CSS-Tricks.

SVG Filter Effects: Outline Text with <feMorphology>

SVGFilterEffects_Morphology_featured

Last week, in the first post of this series on SVG filter effects, we covered the basics of SVG filters—how to create them and how to use them. We also covered a few of the most frequently used filter operations (a.k.a. filter primitives). We will be reusing a little of what we covered in the first post in this article. So, unless you’re already familiar with those, I recommend taking a few minutes to read that article before moving forward with this one.

<feMorphology> is one of my favorite SVG filter operations. It is one of the simplest operations, too, and the results of applying it to different elements are predictable most of the time.

What is Morphing?

To morph means to transform or alter the form or the shape of an object.

The morphology filter operates on the form of an object. It provides two predefined shape transformations: erosion (a.k.a thinning, or shrinking) and dilation (a.k.a. thickening, or expanding). In other words, the feMorphology primitive can be used to shrink or expand elements.

Technically speaking, both these operations operate on a pixel level, expanding a pixel into its neighboring pixels (dilate) or crumbling the neighboring pixels at the edges of the pixel being operated on (erode), while still maintaining strokes around the edge of that pixel. The amount by which a pixel is dilated, or the number of neighboring pixels used to “stretch” or “expand” a pixel upon, is determined by a radius parameter.

<feMorphology 
    in=".." result=".." 
    operator="dilate || erode" radius="">
</feMorphology>

You can think of the morphing radius as the radius of a circle or ellipse; any neighboring pixels that lie within the circle determined by this radius and starting at the input pixel then counts as a neighboring pixel and will be used in the dilation or erosion effect.

In reality, though, the radius actually defines the size of a kernel known as the structuring element and which looks more like a matrix. For now, it’s enough to think about it in terms of a small rectangle whose width and height are determined in pixels specified in the radius attribute.

Effect of erosion using a 3x3 structuring element (kernel).

To use the filter we don’t need to get into the nerdy details of what morphing does on a pixel level. Suffice it to know that you can provide one or two radius values to feMorphology that will determine the amount by which your element will be shrunk or expanded. If you provide two numbers in the radius attribute, the first one will correspond to the x-radius and the second one will determine the y-radius.

Morphing Images

When the feMorphology operation is applied to images, it results in two, usually predictable, results:

  • The image size (dimensions) get smaller if the erode operator is used, and larger if the dilate operator is used.
  • With either operator, the image looks like it’s been painted with a large painting brush, with not a lot of fine detail in it.

So, assuming we want to apply the morphing effect to an image, our code would look as simple as this:

<svg width="450" height="300" viewBox="0 0 450 300">
    <filter id="erode">
        <feMorphology operator="erode" radius="3"></feMorphology>
    </filter>
    <image xlink:href="..." width="90%" height="90%" x="10" y="10" filter="url(#erode)"></image>
</svg>

In this snippet, we are eroding (shrinking) the (pixels in the) image by 3 pixels. The following image shows the result of this code. Notice how the size of the image is slightly smaller on the right:

The result (on the right) of applying the erode morphing effect to the image on the left.
The result (on the right) of applying the erode morphing effect to the image on the left.

Now, if we keep the same morph radius and change the operator from erode to dilate, the effect looks similar, but also distinctively different:

The result (on the right) of applying the dilate morph operation to the image on the left.
The result (on the right) of applying the dilate morph operation to the image on the left.

In both cases, the image looks like an abstract painted version of itself, and its overall size changes as its pixels expand or shrink.

But in addition to the these results, probably the first thing you’ll notice is the difference in colors resulting from each of these two effects: erode produces an image that has more dark pixels, whereas dilate produces a light output. This is due to the fact that:

  • erode (the default value) sets each pixel to its darkest or most transparent neighbor, respectively for each of the R, G, B, and A channels, and
  • dilate sets each channel of each pixel to match the brightest or least transparent value from its neighbors, for each channel respectively.

All this technicality aside, applying feMorphology to images will almost always have the same result: a shrunken or expanded low-detail paint-like version of the image with either dark or light main strokes.

See the Pen feMorphology on an image by Sara Soueidan (@SaraSoueidan) on CodePen.light

When applied to single-color elements, however, such as text, feMorphology only shrinks or expands the element—no noticeable pixel color changes happen because we only have one color to work with anyway…

Adding Colored Outline to Text with feMorphology

We can currently add an outline to text in SVG using the stroke attribute on that text.

<!-- Adding an outline to SVG text using strokes -->
<text font-size="80px" dx="100" dy="200" font-weight="700" stroke="deepPink" stroke-width="3px">Stroked Text</text>

By adding a stroke, the stroke is usually centered at the edges of the text so that half of its thickness overlaps with the text itself, making the text thinner, even when it’s not supposed to. Instead of reducing the thickness of the text to add an outline, we should be able to expand (or dilate) the text so that the thickness of the outline or stroke is added to that of the text. We can do that using feMorphology.

Unless otherwise styled, text usually comes in one color. So, applied to text, feMorphology allows us to shrink or thicken that text. Once the text is thickened using feMorphology, it can be used as input to other filter primitives which then allow us to create text outlines the way they are meant to be created.

Before we dig into how to do that, here is an image showing the difference between text with a stroke outline and an outline added using feMorphology.

Screen Shot 2019-01-08 at 13.39.46
Notice how the stroked text in the middle has become thinner after adding the stroke outline, compared to the text dilated using feMorphology.

So, let’s create a colored piece of text with an outline. We’ll take it step by step. This is the result we will be aiming for:

Screen Shot 2019-01-08 at 18.06.37

So we’ll start with an SVG containing our text and a filter that starts with a simple dilation operation. The amount you dilate the text by depends on the thickness of the outline that you want.

<svg width="900" height="200" viewBox="100 0 900 200">
    <filter id="outline">
        <feMorphology in="SourceAlpha" result="DILATED" operator="dilate" radius="4"></feMorphology>
    </filter>

    <!-- DILATED TEXT -->
    <text font-size="85px" dx="125" dy="130" font-weight="700" filter="url(#outline)">upgrade yourself</text>
</svg>

The above code will get the alpha channel of the text—which is just a black version of the text—and will thicken it by 4px. The result of the code at this point looks like this:

Screen Shot 2019-01-08 at 18.10.25

..compared to the original text which has a dark navy blue fill color:

Screen Shot 2019-01-08 at 18.11.13

In order to create the outline effect, we will layer the original text on top of the dilated text, which will leave only the edges of the dilated text (the additional 4px) visible behind the original text, thus making them look like an outline. Overlaying the text on top of its outline (the dilated text) will be achieved using feMerge. We covered feMerge in the previous article.

Another thing we want to do before we position the outline behind the text is to colorize this outline. Also similar to what we did in the previous article, we will flood the filter region area with the color we want, and then composite the color layer with the dilated text layer (our outline) using the in operator. As a result, only the parts of the flood color that intersect with the dilated text will be rendered and the color will be blended with that text, thus colorizing it. Finally, we will merge the resulting colored outline with the original text to get the result we want. Our code now looks like this:

<svg width="900" height="200" viewBox="100 0 900 200">
    <filter id="outline">
        <feMorphology in="SourceAlpha" result="DILATED" operator="dilate" radius="4"></feMorphology>
        
        <feFlood flood-color="#32DFEC" flood-opacity="1" result="PINK"></feFlood>
        <feComposite in="PINK" in2="DILATED" operator="in" result="OUTLINE"></feComposite>

        <feMerge>
            <feMergeNode in="OUTLINE" />
            <feMergeNode in="SourceGraphic" />
        </feMerge>
    </filter>

    <!-- DILATED TEXT -->
    <text font-size="85px" dx="125" dy="130" font-weight="700" filter="url(#outline)">upgrade yourself</text>
</svg>

Creating a filter effect in SVG is a matter of thinking of the final result in terms of smaller operations, and using the result of one operation as input to another, and finally merging any layers we have created to achieve the final result.

The following is a live demo of the above code:

See the Pen Colored Text Outline with feMorphology by Sara Soueidan (@SaraSoueidan) on CodePen.light

The fill color of the text can be specified either in your CSS or on the text element using the fill attribute. The color of the outline can be tweaked in the flood-color attribute of the feFlood primitive.

Knocking the Text Out

In addition to adding an outline to text by dilating its alpha channel and layering it behind the text, we can create outline-only text, a.k.a. knockout text, meaning that the inside of the text will be “carved out” so you can see the background behind it through the outline. An example of such effect might look like the text in the following GIF, which shows a background changing color, and how that background can be seen within our text. This is the demo we will be creating in this section:

bird-GIF-svg

This effect is easier to create, and the code required to make it is noticeably shorter. The main difference here is that instead of layering the source text on top of the dilated text, we will use that source text to cut out the inner parts of the dilated text. This means that only the added thickness of the dilated text will remain, while the inside will be removed, thus giving us our outline.

We can do that by compositing the source text with the dilated text. Our source text will go on top, and the dilated text will be its backdrop. Using the out composite operator, only the parts of the backdrop that do not overlap with the source layer will be rendered, which in our case means that only our outline will be rendered.

<svg width="900" height="450" viewBox="0 0 900 450">
    <filter id="outliner">

        <!-- Start by grabbing the alpha channel of the text and dilating it-->
        <feMorphology operator="dilate" radius="8" in="SourceAlpha" result="THICKNESS" />
        
         <!-- Next, grab the original text (SourceGraphic) and use it to cut out the inside of the dilated text -->
        <feComposite operator="out" in="THICKNESS" in2="SourceGraphic"></feComposite>
    </filter>

    <text dx="100" dy="300" filter="url(#outliner)" letter-spacing="10px">SVG Rocks</text>
</svg>

Using a nice font face, our demo now looks like this:

Screen Shot 2019-01-08 at 18.33.21

Cool. Now, what if you want to change the color of the outline? You’d have to use the feFlood primitive again and composite the Flood color with the outline. And then every time you want to change the color of the outline, you’d have to do the same over and over again. This is, admittedly, too tedious. Fortunately, there is a simpler way.

If instead of grabbing and dilating the alpha channel of the text (which is black by default) you grab the source text itself (which could have any fill color!) and dilate it, and then use the text again to carve out the inside of the dilated text, you end up with an outline that comes from the source text itself. This means that the color of that outline will always be the same as the color of the source text. And since we can define the fill color of the source text in CSS, this means that you have an outline text that is separated from its styles. (Yay separation of concerns!) You can then apply the filter to any piece of text, and change the color of that text in the CSS any time you need to, without having to tweak the filter’s code. Our improved code now looks like this:

<svg width="900" height="450" viewBox="0 0 900 450">
    <filter id="outliner">

        <!-- Start by grabbing the source graphic (the text) and dilating it-->
        <feMorphology operator="dilate" radius="8" in="SourceGraphic" result="THICKNESS" />
        
         <!-- Then use the text (the SourceGraphic) again to cut out the inside of the dilated text -->
        <feComposite operator="out" in="THICKNESS" in2="SourceGraphic"></feComposite>
    </filter>

    <text dx="100" dy="300" filter="url(#outliner)" letter-spacing="10px">SVG Rocks</text>
</svg>

In our style sheet, we can choose the outline color as well as the SVG background color. You can also choose to have an image behind the text inside the SVG. I’m using CSS animations in the code below to animate the color of the background, for no reason other than it being cool.

svg text {
    font-family: 'Bangers', cursive;
    font-size: 150px;
    letter-spacing: 13px;
    fill: #000; /* This fill color determines the color of the outline */
}

svg {
    background-color: gold;
    animation: colorsssss 2s linear infinite;
    animation-delay: 3s;
}

@keyframes colorsssss {
    50% {
        background-color: deepPink;
    }
}

The above SVG filter is reusable across SVG as well as HTML. If you want to apply it to an HTML element, you can do that using the filter property; just place the filter in your HTML and “call” it in your CSS:

h2 {
    filter: url(#outliner);

    /* You can change the color of the outline here by changing the color of the heading */
    color: deepPink;
}

And our finished demo that includes an HTML heading with the filter applied to it:

See the Pen (Text) Outlines (Only) by Sara Soueidan (@SaraSoueidan) on CodePen.light

My favorite thing about this filter recipe is that it can be used as a visual enhancement. If a browser does not support SVG filters, or if it does not support CSS filters, or it does not support applying SVG filters to HTML elements, the user will get the original text without the outline/knockout effect applied to it. Oh, and the cherry on top of the cake? Both the SVG and the HTML text will be fully accessible, searchable and selectable. Yay progressive enhancement! Yay SVG!

Final Words

Using just two filter operations in SVG, you can apply an outlined text effect to your SVG or HTML text content. Place this filter in your HTML and use and reuse it as often as you need.

In the next article in this series, we will have a look at the <feComponentTransfer>, one of my favorite filter primitives, and see how it works and what effects we can create with it. Stay tuned.

SVG Filter Effects: Outline Text with <feMorphology> was written by Sara Soueidan and published on Codrops.