As Women’s History Month draws to a close, Moz CEO Sarah Bird reflects on the contributions women have made to the SEO industry, and highlights the work we still have to do.
from The Moz Blog https://ift.tt/2PMP6kU
via IFTTT
As Women’s History Month draws to a close, Moz CEO Sarah Bird reflects on the contributions women have made to the SEO industry, and highlights the work we still have to do.
Here’s a fabulous post by Vitaly Friedman that looks at how to make accessible front-end components and what problems there are today when it comes to building them.
There’s so much great info packed into this one post that I’m going to keep it open in a tab for quite some time. But I have two thoughts here. First, just skimming through the article is enough to make anyone realize that accessibility is a complex subject and it’s so very easy to get things wrong; colors, images, text, HTML, mouse pointer vs. touch, small screens vs. large screens, charts and data viz, form components, layout and semantic ordering. The list goes on and on. It’s clear to me now (and I am late to the party) that accessibility is a full-time job.
Second, Vitaly makes note of some of the excellent work that the Government Digital Service (GDS) is doing in the UK by releasing open-source components such as accessible-autocomplete. And I have to say, I think the work that GDS is doing is so very inspiring to me as a web designer and developer.
Here’s a story: a few years ago I had to book an appointment to get a driver’s license. I hopped on the website and, immediately, I recognized that it was using the GDS design system. That gave me a great sigh of relief, but then I found myself sailing through this form at lightning speed. By the end, I realized that this is what every website should feel like; I used the site, did what I needed to do as quickly as possible, and then left.
It was one of the most shocking experiences for me as a web designer because there was no cruft, no junk, and no messing around with the experience in any way. It was fast, didn’t break down, crash the browser, or confuse me at all. The form inputs were big and clickable and the correct keyboard was selected when I viewed it on my phone. All of this accessibility work that they’ve poured into making things just work is a joyous thing.
This reminds me of something that Jeremy Keith wrote about the other day when he used another government website to get vaccinated:
[…] it’s a sequence of short forms, clearly labelled. Semantic accessible HTML, some CSS, and nothing more. If your browser doesn’t support JavaScript (or you’ve disabled it for privacy reasons), that won’t make any difference to your experience. This is the design system in action and it’s an absolute pleasure to experience.
[…] Maybe I’ll never need to visit that URL again. In the case of the NHS, I hope I won’t need to visit again. I just need to get in, accomplish my task, and get out again. This is where the World Wide Web shines.
Direct Link to Article — Permalink
The post Where the World Wide Web Shines appeared first on CSS-Tricks.
You can support CSS-Tricks by being an MVP Supporter.
I would hope all our web designer/developer spidey senses trigger when the solution to an accessibility problem isn’t “fix the issue” but rather “add extra stuff to the page.” This Overlay Fact Sheet website explains that. An “Overlay” is one of those “add extra stuff to the page” things, ostensibly for improving accessibility. Except, even though marketing may suggest they are a silver bullet to accessibility, they are… not.
The site does a much better job laying that out than I can, so go check it out. As I write, it’s signed by 352 people, mostly people who are accessibility professionals.
Direct Link to Article — Permalink
The post Overlay Fact Sheet appeared first on CSS-Tricks.
You can support CSS-Tricks by being an MVP Supporter.
We’re going to create an impressive transition effect between images that’s, dare I say, very simple to implement and apply to any site. We’ll be using the kampos library because it’s very good at doing exactly what we need. We’ll also explore a few possible ways to tweak the result so that you can make it unique for your needs and adjust it to the experience and impression you’re creating.
Take one look at the Awwwards Transitions collection and you’ll get a sense of how popular it is to do immersive effects, like turning one media item into another. Many of those examples use WebGL for the job. Another thing they have in common is the use of texture mapping for either a displacement or dissolve effect (or both).
To make these effects, you need the two media sources you want to transition from and to, plus one more that is the map, or a grid of values for each pixel, that determines when and how much the media flips from one image to the next. That map can be a ready-made image, or a <canvas>
that’s drawn upon, say, noise. Using a dissolve transition effect by applying a noise as a map is definitely one of those things that can boost that immersive web experience. That’s what we’re after.
Before we can get to the heavy machinery, we need a simple DOM scene. Two images (or videos, if you prefer), and the minimum amount of JavaScript to make sure they’re loaded and ready for manipulation.
<main>
<section>
<figure>
<canvas id="target">
<img id="source-from" src="path/to/first.jpg" alt="My first image" />
<img id="source-to" data-src="path/to/second.jpg" alt="My second image" />
</canvas>
<figure>
</section>
</main>
This will give us some minimal DOM to work with and display our scene. The stage is ready; now let’s invite in our main actors, the two images:
// Notify when our images are ready
function loadImage (src) {
return new Promise(resolve => {
const img = new Image();
img.onload = function () {
resolve(this);
};
img.src = src;
});
}
// Get the image URLs
const imageFromSrc = document.querySelector('#source-from').src;
const imageToSrc = document.querySelector('#source-to').dataset.src;
// Load images and keep their promises so we know when to start
const promisedImages = [
loadImage(imageFromSrc),
loadImage(imageToSrc)
];
The scene is set, the images are fetched — let’s make some magic! We’ll start by creating the effects we need. First, we create the dissolve map by creating some noise. We’ll use a Classic Perlin noise inside a turbulence effect which kind of stacks noise in different scales, one on top of the other, and renders it onto a <canvas>
in grayscale:
const turbulence = kampos.effects.turbulence({ noise: kampos.noise.perlinNoise });
This effect kind of works like the SVG feTurbulence
filter effect. There are some good examples of this in “Creating Patterns With SVG Filters” from Bence Szabó.
Second, we set the initial parameters of the turbulence effect. These can be tweaked later for getting the specific desired visuals we might need per case:
// Depending of course on the size of the target canvas
const WIDTH = 854;
const HEIGHT = 480;
const CELL_FACTOR = 2;
const AMPLITUDE = CELL_FACTOR / WIDTH;
turbulence.frequency = {x: AMPLITUDE, y: AMPLITUDE};
turbulence.octaves = 1;
turbulence.isFractal = true;
This code gives us a nice liquid-like, or blobby, noise texture. The resulting transition looks like the first image is sinking into the second image. The CELL_FACTOR
value can be increased to create a more dense texture with smaller blobs, while the octaves=1
is what’s keeping the noise blobby. Notice we also normalize the amplitude to at least the larger side of the media, so that texture is stretched nicely across our image.
Next we render the dissolve map. In order to be able to see what we got, we’ll use the canvas that’s already in the DOM, just for now:
const mapTarget = document.querySelector('#target'); // instead of document.createElement('canvas');
mapTarget.width = WIDTH;
mapTarget.height = HEIGHT;
const dissolveMap = new kampos.Kampos({
target: mapTarget,
effects: [turbulence],
noSource: true
});
dissolveMap.draw();
We are going to pause here and examine how changing the parameters above affects the visual results. Now, let’s tweak some of the noise configurations to get something that’s more smoke-like, rather than liquid-like, say:
const CELL_FACTOR = 4; // instead of 2
And also this:
turbulence.octaves = 8; // instead of 1
Now we have a more a dense pattern with eight levels (instead of one) superimposed, giving much more detail:
Fantastic! Now back to the original values, and onto our main feature…
It’s time to create the transition effect:
const dissolve = kampos.transitions.dissolve();
dissolve.map = mapTarget;
dissolve.high = 0.03; // for liquid-like effect
Notice the above value for high
? This is important for getting that liquid-like results. The transition uses a step function to determine whether to show the first or second media. During that step, the transition is done smoothly so that we get soft edges rather than jagged ones. However, we keep the low edge of the step at 0.0
(the default). You can imagine a transition from 0.0
to 0.03
is very abrupt, resulting in a rapid change from one media to the next. Think of it as clipping.
On the other hand, if the range was 0.0
to 0.5
, we’d get a wider range of “transparency,” or a mix of the two images — like we would get with partial opacity — and we’ll get a smoke-like or “cloudy” effect. We’ll try that one in just a moment.
Before we continue, we must remember to replace the canvas we got from the document with a new one we create off the DOM, like so:
const mapTarget = document.createElement('canvas');
We’re almost there! Let’s create our compositor instance:
const target = document.querySelector(‘#target’);
const hippo = new kampos.Kampos({target, effects: [dissolve]});
And finally, get the images and play the transition:
Promise.all(promisedImages).then(([fromImage, toImage]) => {
hippo.setSource({media: fromImage, width, height});
dissolve.to = toImage;
hippo.play(time => {
// a sin() to play in a loop
dissolve.progress = Math.abs(Math.sin(time * 4e-4)); // multiply time by a factor to slow it down a bit
});
});
Sweet!
OK, we got that blobby goodness. We can try playing a bit with the parameters to get a whole different result. For example, maybe something more smoke-like:
const CELL_FACTOR = 4;
turbulence.octaves = 8;
And for a smoother transition, we’ll raise the high edge of the transition’s step function:
dissolve.high = 0.3;
Now we have this:
And, for our last plot twist, let’s also animate the noise itself! First, we need to make sure kampos will update the dissolve map texture on every frame, which is something it doesn’t do by default:
dissolve.textures[1].update = true;
Then, on each frame, we want to advance the turbulence time
property, and redraw it. We’ll also slow down the transition so we can see the noise changing while the transition takes place:
hippo.play(time => {
turbulence.time = time * 2;
dissolveMap.draw();
// Notice that the time factor is smaller here
dissolve.progress = Math.abs(Math.sin(time * 2e-4));
});
And we get this:
That’s it!
This is just one example of what we can do with kampos for media transitions. It’s up to you now to mix the ingredients to get the most mileage out of it. Here are some ideas to get you going:
Whatever you do, be sure to give us a shout about it in the comments.
The post Nailing That Cool Dissolve Transition appeared first on CSS-Tricks.
You can support CSS-Tricks by being an MVP Supporter.
This literal tech talk (YouTube video embedded in there) by Zach Leatherman is a good time. The talk is sprinkled with fun trickery, so I’m just taking notes on some on it here:
contenteditable
on the <body>
makes the whole page editable! Did you know document.designMode = "on"
does the same thing in JavaScript? (More on making DevTools a design tool.)CMD
+ click into the editor where you want another one to be, or make it part of a snippet.system-ui
. Firefox doesn’t seem to support that, so I guess we need the whole stack. I wonder how close we are to just needing that one value. Iain Bean has more on this in his “System fonts don’t have to be ugly” post.box-decoration-break
is a nice little touch for “inline headers.” The use of @supports
here makes great sense as it’s not just that one property in use, but several. So, in a non-support situation, you’d want to apply none of it.<progress>
in some <li>
elements to compare rendering strategies is a neat way to get some perfect UI without even a line of CSS.I think Zach’s overall point is strong: we should question any Single-Page-App-By-Default website building strategy.
As a spoonful of baby bear porridge here, I’d say I’m a fan of both static site generators and JavaScript frameworks. JavaScript frameworks offer some things that are flat-out good ideas for building digital products: components and state. Sometimes that means that client-side rendering is actually helpful for the interactivity and overall feel of the site, but it’s unfortunate when client-side rendering comes along for the ride by default instead of as a considered choice.
Direct Link to Article — Permalink
The post This Web Site is a Tech Talk appeared first on CSS-Tricks.
You can support CSS-Tricks by being an MVP Supporter.
Most inputs have something in common — they are happiest with a companion label! And the happiness doesn’t stop there. Forms with proper inputs and labels are much easier for people to use and that makes people happy too.
In this post, I want to focus on situations where the lack of a semantic label and input combination makes it much harder for all sorts of people to complete forms. Since millions of people’s livelihoods rely on forms, let’s get into the best tips I know for creating a fulfilling and harmonious relationship between an input and a label.
Content warning: In this post are themes of love and relationships.
The love story starts here! Let’s cover the basics for creating happy labels and inputs.
There are two ways to pair a label and an input. One is by wrapping the input in a label (implicit), and the other is by adding a for
attribute to the label and an id
to the input (explicit).
Think of an implicit label as hugging an input, and an explicit label as standing next to an input and holding its hand.
<label>
Name:
<input type="text" name="name" />
</label>
An explicit label’s for
attribute value must match its input’s id
value. For example, if for
has a value of name
, then id
should also have a value of name
.
<label for="name">Name: </label>
<input type="text" id="name" name="name" />
Unfortunately, an implicit label is not handled correctly by all assistive technologies, even if for
and id
attributes are used. Therefore, it is always the best idea to use an explicit label instead of an implicit label.
<!-- IMPLICIT LABEL (not recommended for use) - the label wraps the input. -->
<label>
Name:
<input type="text" name="name" />
</label>
<!-- EXPLICIT LABEL (recommended for use) - the label is connected to an input via "for" and "id" -->
<label for="explicit-label-name">Name: </label>
<input type="text" id="explicit-label-name" name="name" />
Each separate input element should only be paired with one label. And a label should only be paired with one input. Yes, inputs and labels are monogamous. ♥️
Note: There’s one sort of exception to this rule: when we’re working with a group of inputs, say several radio buttons or checkboxes. In these cases, a <legend>
element is used to group certain input elements, such as radio buttons, and serves as the accessible label for the entire group.
An input with a type="submit"
or type="button"
does not need a label — the value
attribute acts as the accessible label text instead. An input with type="hidden"
is also fine without a label. But all other inputs, including <textarea>
and <select>
elements, are happiest with a label companion.
The content that goes inside of a label should:
One useful thing you can do with the content in a label is add formatting hints. For example, the label for <input type="date" id="date">
will be <label for="date">
as we’d expect. But then we can provide a hint for the user that the date needs to be entered in a specific format, say DD-DD-YYYY
, in the form of a <span>
between the label and input that specifies that requirement. The hint not only specifies the date format, but has an id
value that corresponds to an aria-describedby
attribute on the input.
<!-- Describes what the input is for - should be plain text only -->
<label for="date">Start date</label>
<!-- Describes additional information, usually about formatting -->
<span id="date-format">(DD-MM-YYYY):</span>
<input type="date" id="date" aria-describedby="date-format" min="2021-03-01" max="2031-01-01" />
This way, we get the benefit of a clear label that describes what the input is for, and a bonus hint to the user that the input needs to be entered in a specific format.
The following tips go beyond the basics to explain how to make sure a label and input are as happy as can be.
There is a WCAG success criterion that states the visual order of a page should follow the order in which elements appear in the DOM. That’s because:
A user with low vision who uses a screen magnifier in combination with a screen reader may be confused when the reading order appears to skip around on the screen. A keyboard user may have trouble predicting where focus will go next when the source order does not match the visual order.
Think about it. If we have some standard HTML where the label comes before the input:
<label for="orange">Orange</label>
<input type="checkbox" id="orange" name="orange">
That places the label before the input in the DOM. But now let’s say our label and form are inside a flexible container and we use CSS order
to reverse things where the input visually comes before the label:
label { order: 2; }
input { order: 1; }
A screen reader user, who is navigating between elements, might expect the input to gain focus before the label because the input comes first visually. But what really happens is the label comes into focus instead. See here for the difference between navigating with a screen reader and a keyboard.
So, we should be mindful of that. It is conventional to place the label on the right-hand side of the input for checkboxes and radio buttons. This can be done by placing the label after the input in the HTML, ensuring the DOM and visual order match.
<form>
<!-- Checkbox with label on the right -->
<span>
<input type="checkbox" id="orange" name="orange">
<label for="orange">Orange</label>
</span>
<!-- Radio button with label on the right -->
<span>
<input type="radio" id="banana" name="banana">
<label for="banana">Banana</label>
</span>
<!-- Text input with label on the left -->
<span>
<label for="apple">How do you like them apples?</label>
<input type="text" id="apple" name="apple">
</span>
</form>
Whether an input is written from scratch or generated with a library, it is a good idea to check your work using a screen reader. This is to make sure that:
for
and id
attributes.Over the last few years, I have used JavaScript libraries, like downshift, to build complex form elements such as autocomplete or comboboxes on top of native HTML ones, like inputs or selects. Most libraries make these complex elements accessible by adding ARIA attributes with JavaScript.
However, the benefits of native HTML elements enhanced using JavaScript are totally lost if JavaScript is broken or disabled, making them inaccessible. So check for this and provide a server-rendered, no-JavaScript alternative as a safe fallback.
Check out these basic form tests to determine how an input and its companion label or legend should be written and announced by different screen readers.
Connecting a label and an input is important, but just as important is keeping the label visible. Clicking or tapping a visible label focuses its input partner. This is a native HTML behavior that benefits a huge number of people.
Imagine a label wanting to proudly show its association with an input:
That said, there are going to be times when a design calls for a hidden label. So, if a label must be hidden, it is crucial to do it in an accessible way. A common mistake is to use display: none
or visibility: hidden
to hide a label. These CSS display properties completely hide an element — not only visually but also from screen readers.
Consider using the following code to visually hide labels:
/* For non-natively-focusable elements. For natively focusable elements */
/* Use .visually-hidden:not(:focus):not(:active) */
.visually-hidden {
border-width: 0 !important;
clip: rect(1px, 1px, 1px, 1px) !important;
height: 1px !important;
overflow: hidden !important;
padding: 0 !important;
position: absolute !important;
white-space: nowrap !important;
width: 1px !important;
}
Kitty Giraudel explains in depth how to hide content responsibly.
To preserve and maintain a healthy relationship between inputs and labels, there are some things not to do when pairing them. Let’s get into what those are and how to prevent them.
There are certain types of inputs that are unsupported In some older desktop browsers. For example, an input that is type="date"
isn’t supported in Internet Explorer (IE) 11, or even in Safari 141 (released September 2020). An input like this falls back to type="text"
. If a date input does not have a clear label, and it automatically falls back to a text input in older browsers, people may get confused.
Here is why a placeholder
attribute on an input should not be used in place of a label:
placeholder
is in danger of being cut-off on smaller devices, or when a page is translated in the browser. In contrast, the text content of a label can easily wrap onto a new line.placeholder
text on their large retina screen, in a well-lit room, in a distraction-free environment, doesn’t mean everyone else can. A placeholder
can make even those with good vision scrunch their eyes up and eventually give up on a form.placeholder
becomes invisible — both visually and to screen readers. If someone has to back-track to review information they’ve entered in a form, they’d have to delete what was entered just to see the placeholder again.placeholder
attribute is not supported in IE 9 and below, and disappears when an input is focused in IE 11. Another thing to note: the placeholder color is unable to be customized with CSS in IE 11.Placeholders are like the friend that shows up when everything is perfect, but disappears when you need them most. Pair up an input with a nice, high-contrast label instead. Labels are not flaky and are loyal to inputs 100% of the time.
The Nielsen Norman Group has an in-depth article that explains why placeholders in form fields are harmful.
When no label is present, some screen readers will look for adjacent text and announce that instead. This is a hit-and-miss approach because it’s possible that a screen reader won’t find any text to announce.
The below code sample comes from a real website. The label has been substituted with a <span>
element that is not semantically connected to the input.
<div>
<span>Card number</span>
<div>
<input type="text" value="" id="cardNumber" name="cardNumber" maxlength="40">
</div>
</div>
The above code should be re-written to ensure accessibility by replacing the span with a label with for="cardNumber"
on it. This is by far the most simple and robust solution that benefits the most people.
While a label could be substituted with a span that has an id
with a value matching the input’s aria-labelledby
attribute, people won’t be able to click the span to focus the input in the same way a label allows. It is always best to harness the power of native HTML elements instead of re-inventing them. The love story between native input and label elements doesn’t need to be re-written! It’s great as-is.
Only plain text should be included inside a label. Avoid inserting things such as headings, or interactive elements such as links. Not all screen readers will announce a label correctly if it contains something other than plain text. Also, if someone wants to focus an input by clicking its label, but that label contains a link, they may click the link by mistake.
<form>
<div>
<!-- Don't do this -->
<input type="checkbox" id="t-and-c" name="name" />
<label for="t-and-c">I accept the <a href="https://link.com">terms and conditions</a></label>
</div>
<div>
<!-- Try this -->
<input type="checkbox" id="t-and-c2" name="name" />
<label for="t-and-c2">I accept the terms and conditions.</label>
<span>Read <a href="https://link.com">terms and conditions</a></span>
</div>
</form>
I always find that real-life examples help me to properly understand something. I searched the web and found examples of labels and inputs from a popular component library and website. Below, I explain where the elements fall short and how they can be improved to ensure a better pairing.
MaterialUI is a React component library based on Google’s design system. It includes a text input component with a floating label pattern that has become a popular go-to for many designers and developers:
Clicking on the input feels smooth and looks great. But that’s the problem. Its qualities are mostly skin-deep.
At the time of writing this post, some issues I found with this component include:
id
and aria-describedby
. This means that not all screen readers will be able to associate the helper message with the input.Adam Silver also explains why float labels are problematic and gets into a detailed critique of Material’s text input design.
The Huffpost website has articles containing a newsletter subscription form:
At the time of writing this blog post, the email input that Huffpost uses could benefit from a number of improvements:
aria-label
attribute on the input.placeholder
and input values are a tiny 11px, which can be hard to read.A surprising number of people struggle to enter information into poorly-constructed inputs. That list includes people with cognitive, motor and physical disabilities, autism spectrum disorders, brain injuries, and poor vision. Other people who struggle include those in a hurry, on a poor connection, on a small device, on an old device, and unfamiliar with digital forms, among many others.
Additionally, there are numerous reasons why JavaScript might break or be switched off in a browser, meaning inputs become dysfunctional or completely inaccessible. There are also people who are fully capable of viewing a web page but who may choose to use a keyboard along with a screen reader.
The message I want to get across is that happy label and input pairs are crucial. It doesn’t matter if your form is beautiful if it is unusable. I can bet that almost everyone would rather fill out an ugly but easy-to-use form rather than a pretty one that causes problems.
I want to warmly thank the following people for helping me with this post: Eric Eggert, Adam Silver, Dion Dajka, and Kitty Giraudel. Their combined accessibility knowledge is a force to be reckoned with!
The post HTML Inputs and Labels: A Love Story appeared first on CSS-Tricks.
You can support CSS-Tricks by being an MVP Supporter.
Dave and I launched a Patreon for ShopTalk Show. You get two completely priceless things for backing us:
I think the Discord might be my favorite thing we ever done. Sorry if I’m stoking the FOMO there, but just saying, it’s a good gang. My personal intention is to be helpful in there, but everyone else is so helpful themselves that I’ve actually learned more than I’ve shared.
Direct Link to Article — Permalink
The post ShopTalk Patreon appeared first on CSS-Tricks.
You can support CSS-Tricks by being an MVP Supporter.
Posted by Cyrus-Shepard
Link building isn't always easy, but if you want to rank with SEO, links are often the cost of admission.
While Google says SEOs sometimes focus too much on links, links remain one of the few confirmed ranking factors. Indeed, every study over the past decade shows a high correlation between links and ranking. And while links alone can't guarantee a #1 spot at the top of Google, previous research has shown that it's nearly impossible to rank without any links at all.
For many, link building also presents a challenge. Folks get sincerely frustrated with wasted link building efforts, poor outreach processes, and lack of results.
It doesn't have to be that way.
Good link building actually helps everyone involved: the content owner, the linker, the audience, and search engines alike. Google evaluates links in so many ways, you could say its search engine couldn't exist without them. Good link building also encourages the creation of useful content and good marketing practices. When done right, link building can also be a joy (and profitable!).
Moz first published the Beginner's Guide to Link Building in 2014. Back then, the SEO world was still adjusting to the fallout of Google's Penguin Algorithm, which punished sites engaging in manipulative link building practices. The SEO world was looking to transition to more holistic, value-added forms of link building that wouldn't run afoul of Google's initiatives to sweep the web of shady practices.
Enter Paddy Moogan.
At the time, Paddy was already a respected voice among link builders, and had authored one of the few good books on link building. It was the same year that he and co-founder Matt Beswick conceived Aira, the digital marketing agency that would compel them to new heights. Moz was honored to have Paddy write the first edition of the Beginner's Guide to Link Building.
Now, in 2021, Paddy has done it again.
A lot has changed in link building since 2014, and weirdly, much has stayed the same. Many of the tools and tactics have certainly evolved, along with Google's algorithm (rel=ugc anyone?). As we worked with Paddy to update this edition of the guide, we realized how so many of the fundamentals of link building remain as true today as they did when we launched the first edition of the guide. As Paddy writes:
"Arguably, link building these days is more akin to great marketing, and the organizations who understand this are usually the ones who win long term."
Without links, it's likely Google would have never been invented in the first place. Understanding how websites link to one another allowed Google's founders to create a search engine so superior to any other, that it grew to world domination. In fact, over 20 years later, links remain one of the most consistent Google ranking signals that we know of.
In this chapter, learn the fundamentals of why link building is important, how they help websites to rank, and other ways in which links are important to a web-based business.
Read Chapter 1 - What Is Link Building & Why Is It Important?
The truth is, not all links are created equal. In truth, the web consists of billions of links. Google, in its ranking algorithms, may only consider a fraction of these links. Indeed, algorithms like Penguin, released years ago, are specifically designed to ignore many types of links.
Understanding the types of links that you actually need, and that actually help you to rank, is crucial to effective link building.
This chapter covers:
Read Chapter 2 - Types Of Links
It all starts with a plan.
Some websites are able to attract links without much forethought, but this is rare. In truth, most successful sites have a plan for attracting links sustainably and at scale. Planning the right strategy in advance can make the difference between success and wasted effort.
Questions covered include:
Read Chapter 3 - Structuring a Link Building Campaign
Want to know what separates successful link builders from unsuccessful ones?
This is a big, important chapter, involving a bit of competitive SEO research to lay the foundation in advance of your link-building campaign to better ensure success.
This includes identifying the types of content already earning links, the audiences linking to them, how to find contact information, and more.
Read Chapter 4 - Finding your audience to get links from
Outreach good. Outreach bad.
Outreach has earned a rough reputation in SEO. We've nearly all been the recipient of really bad, really terrible outreach emails.
Good outreach makes all the difference.
Good outreach doesn't get marked as spam. Good outreach actually adds value for the person you're contacting. Good outreach builds links -- and relationships.
In this chapter, learn the exact outreach tactics agencies use for successful link building campaigns, including detailed tips and real-world email templates to find inspiration.
Read Chapter 5 - Link Building Outreach
This is what you came here for, right?
There are hundreds of legitimate link-building tactics. Which one(s) you choose will depend on your business goals, available resources, your niche, and available time.
A few of the tactics covered include:
Read Chapter 6 - Link Building Tactics
If you build links, will traffic come?
Building links doesn't happen in a vacuum. Regardless if you work for an agency, in-house, or build links for your own projects, measuring the success of your efforts is vitally important.
In this chapter, explore and understand how the proper use of metrics such as Domain Authority, Page Authority, and even PageRank help in link building and reporting.
Also, look at how anchor text and raw link counts may or may not influence your link-building campaigns. For more advanced link builders, even the position of the link on the page may be tracked!
Read Chapter 7 - Link Building Measurement and Metrics
Updating the link building guide was a ton of fun. Paddy was an absolute joy to work with, and his experience and expertise added immense value.
We also wanted to include real-world examples from some of the top link builders working in the industry. To this end, we reached out to experts such as:
Collectively, these individuals have built thousands of links for some of the most successful brands and campaigns on the planet. They generously contributed their expertise to the guide, and we've sprinkled this wisdom throughout.
What are your greatest link building tips? Let us know in the comments below.
Read The Beginner's Guide to Link Building
Sign up for The Moz Top 10, a semimonthly mailer updating you on the top ten hottest pieces of SEO news, tips, and rad links uncovered by the Moz team. Think of it as your exclusive digest of stuff you don't have time to hunt down but want to read!
David Bushell in ”Changing CSS for Good“:
I’m dropping “
left
“ and “right
“ from my lexicon. The new CSS normal is all about Logical Properties and Values […] It can be as easy as replacing left/right with inline start/end. Top/bottom with block start/end. Normal inline flow, Flexbox, and Grid layouts reverse themselves automatically.
I figured it made sense as a “You want…” style post. Geoff has been documenting these properties nicely in the Almanac.
The post You want margin-inline-start appeared first on CSS-Tricks.
You can support CSS-Tricks by being an MVP Supporter.
Hello! Satarupa Chatterjee from Cloudinary. There is a big change coming from Google in May 2021 having to do with their Core Web Vitals (CWVs). It’s worth paying attention here, as this is going to be a SEO factor.
I recently spoke with Tamas Piros about CWVs. The May 2021 update will factor in CWVs, along with other factors like mobile-friendliness and safe browsing, to generate a set of benchmarks for search rankings. Doubtless, the CWVs will directly affect traffic for websites and apps alike. Tamas is a developer-experience engineer at Cloudinary, a media-optimization expert, and a Google developer-expert in web technologies and web performance.
Here’s a written version of the video above, where the questions (Qs) are me, Satarupa, asking and Tamas answering (As).
A: As a dominant force in the search space, Google has researched in depth what constitutes a superb user experience, arriving at three important factors, which the company calls, collectively, the Core Web Vitals.
Before explaining them, I’d like to recommend an informative article, published last May on the Chromium Blog, titled The Science Behind Web Vitals. At the bottom of the piece are links to papers on the research that led to the guidelines for accurately evaluating user experiences.
Now back to the three Core Web Vitals. The first one affects page-load speed, which Google calls Largest Contentful Paint (LCP) with a recommendation of 2.5 seconds or less for the largest element on a page to load.
The second metric is First Input Delay (FID), which is a delta between a user trying to interact with a page, and the browser effectively executing that action. Google recommends 100 milliseconds or less.
The third and last metric is Cumulative Layout Shift (CLS), which measures how stable a site is while it’s loading or while you’re interacting with it. In other words it is a measurement of individual layout shifts as well as unexpected layout shifts that happen during the lifespan of a page. The calculation involves impact and distance fractions which are multiplied together to give a final value. Google advocates this value to be 0.1 or less.
A: Behind the ranking of Google search results are many factors, such as whether you use HTTPS and how you structure your content. Let’s not forget that relevant and well-presented content is as important as excellent page performance. The difference that core web vitals will make cannot be overstated. Google returns multiple suggestions for every search, however remember that good relevance is going to take priority. In other words good page experience will not override having great relevant content For example, if you search for Cloudinary, Google will likely show the Cloudinary site at the top of the results page. Page experience will become relevant when there are multiple available results, for a more generic search such as ‘best sports car’. In this case Google establishes that ranking based on the page’s user experience, too, which is determined by the Core Web Vitals.
A: Businesses should focus primarily on meeting or staying below the threshold of the Core Web Vitals. However, they must also keep in mind that their page load times could be affected by other metrics, such as the length of time the first purchase takes and the first contentful paint.
For example, to find out what contributes to a bad First Input Delay—the FID, check the total blocking time and time to interact. Those are also vitals, just not part of the Core Web Vitals. You can also customize metrics with the many robust APIs from Google.. Such metrics could prove to be invaluable in helping you identify and resolve performance issues.
A: What’s important to remember with regards to LCP is that we are talking about the largest piece of content that gets loaded on a page, and that is visible in the viewport (that is, it’s visible above the fold). Due to popular UX design patterns it’s likely that the largest, visible element is a hero image.
Google watches for <img>
elements as well as <image>
elements inside an SVG element. Video elements are considered too but only if they contain a poster attribute. Also of importance to Google are block-level elements, such as text-related ones like <h1>
, <h2>
, etc., and <span>
.
All that means that you must load the largest piece of content as fast as possible. If your LCP is a hero image, be sure to optimize it—but without degrading the visual effects. Check out Cloudinary’s myriad effective and intuitive options for optimization. If you can strike a good balance between the file size and the visual fidelity of your image, your LCP will shine.
A: According to Google, sites that meet the thresholds of the Core Web Vitals enjoy a 24-percent lower abandonment rate. The more you adhere to Google’s guidelines, the more engaging your site or app becomes and the faster your sales will grow. Needless to say, an appealing user experience attracts visitors and retains them, winning you an edge over the competition. Of course bear in mind the other search optimization guidelines set out by Google.
Again, be sure to optimize images, especially the most sizable one in the viewport, so that they load as fast as possible.
A: Late last year, Google held a conference and there were multiple talks touching upon this exact subject. All major changes will go into effect on a per-year basis, and Google has committed to announcing them well in advance.
Behind the scenes, Google is constantly collecting data from the field and checking them against user expectations. The first contentful paint, which I mentioned before, is under consideration as another Core Web Vital. Also, Google is thinking about reducing the yardstick for the First Input Delay metric—the FID, remember?—from 100 milliseconds to 75 or even 50.
Beyond that, Google has received a lot of feedback about some of the Core Web Vitals not working well for single-page apps. That’s because those apps are loaded only once. Even if they score an ideal Cumulative Layout Shift—that’s CLS—as you click around the page, things might move around and bring down the score. Down the road, Google might modify CLS to better accommodate single-page apps.
Also on Google’s radar screen are metrics for security, privacy, and accessibility. Google promises to fine-tune the current metrics and launch new ones more frequently than major releases, including the introduction of new Core Web Vital metrics.
So, change is the only constant here. I see a bright future for the vitals and have no doubt that we’re in good hands. Remember that Google vigilantly collects real user data as analytics to help figure out the appropriate standards. As long as you keep up with the developments and ensure that your site or app comply with the rules, you’ll get all greens throughout the scoreboard. That’s a great spot to be in.
Cloudinary offers myriad resources on media experience (MX), notably the MX Matters podcast, which encompasses experts’ take on the trends in today’s visual economy along with bulletins on new products and enhancements. Do check them out.
The post Deliver Enhanced Media Experiences With Google’s Core Web Vitals appeared first on CSS-Tricks.
You can support CSS-Tricks by being an MVP Supporter.
There is a lot of hype on the :is()
pseudo-selector lately, probably because now that Safari 14 has it, it’s supported across all the major browsers. You’ve got Miriam tweeting about it, Kevin Powell doing a video, Šime getting it into the Web Platform News, and Robin mentioning it. Bramus really puts a point on it with these “three important facts”:
1. The selector list of
:is()
is forgiving
2. The specificity of:is()
is that of its most specific argument
3.:is()
does not work with pseudo-element selectors (for now)
Plus, of course, it’s main functionality which is making otherwise rather verbose, complex, and error-prone selectors easier to write. The specificity thing is extra-interesting. Miriam notes some trickery you could do with it, like juicing up specificity without actually selecting anything.
Say you wanted to use the .button
class to select, but give it a ton of specificity
:is(.button, #increase#specificity) {
/* specificity is now (0, 1, 0, 0) instead of (0, 0, 1, 0)
}
I’ve done silly stuff like this in the past:
.button.button.button {
/* forcing the selector to be (0, 0, 3, 0) instead of (0, 0, 1, 0) */
/* doesn't actually require element to have three button classes lol */
}
The :is()
trick seems a little more understandable to me.
But what if you want to go the other way with specificity and lower it instead? Well, that’s the whole point of the :where()
pseudo-selector. Functionally, it’s exactly the same as :is()
. You give it a comma-separated list of things to select as part of the selector chain, and it does, with the same forgiving nature. Except, the specificity of the entire :where()
part is zero (0).
Kevin showed off an interesting gotcha with :is()
in the video:
.card :is(.title, p) {
color: red;
}
.card p {
color: yellow;
}
You might think yellow
will win out here, but the presence of .title
in that :is()
selector on top makes the specificity of that selector (0, 0, 2, 0) winning out over the (0, 0, 1, 1) below.
This is where we could consider using :where()
instead! If we were to use the :where()
pseudo-selector instead:
.card :where(.title, p) {
color: red;
}
.card p {
color: yellow;
}
Then yellow would win, because the top selector lowers to (0, 0, 1, 0) specificity, losing to the bottom selector’s (0, 0, 1, 1).
Which one should you use? Ya know what, I’m not really sure if there is super solid time-tested advice here. At least we have both options available, meaning if you get into a pickle, you’ve got tools to use. Time has taught me that keeping specificity low is generally a healthier place to be. That gives you room to override, where if you’re riding high with specificity you have fewer options. But the zero specificity of :where()
is pretty extreme and I could see that leading to confusing moments, too. So my gut is telling me you might wanna start with :is()
, unless you notice you need to mix in a higher-specificity selector; if you do, back off to :where()
.
The post :where() has a cool specificity trick, too. appeared first on CSS-Tricks.
You can support CSS-Tricks by being an MVP Supporter.
Google has said that Web Core Vitals (WCV) are going to be an SEO factor, and the date is nigh: May 2021. So, I’m seeing some scrambling to make sure those metrics are good. Ya know, the acronym soup: CLS, LCP, and FID. There is starting to be more and more tooling to measure and diagnose problems. Hopefully, once diagnosed, you have some idea how to fix them. Like if you have crappy CLS, it’s because you load in stuff (probably ads) that shifts layout, and you should either stop doing that or make space for them ahead of time so there is less shifting.
But what about LCP? What if you have this big hero image that is taking a while to paint and it’s giving you a crappy LCP number? Chris Castillo’s trick is to just not load the hero background image at all until a user interacts in some way. Strikes me as weird, but Chris did some light testing and found some users didn’t really notice:
Although this accomplishes the goal, it’s not without a cost. The background image will not load until the user interacts with the screen, so something needs to be used as a fallback until the image can be loaded. I asked a few friends to load the page on their phones and tell me if they found anything strange about the page, and none of them noticed anything “off”. What I observed is that the few friends I asked to test this all had their fingers on the screen or quickly touched the screen when the page was loading, so it happened so quickly they didn’t notice.
It’s a fine trick that Chris documents, but the point is fooling a machine into giving you better test scores. This feels like the start of a weird new era of web performance where the metrics of web performance have shifted to user-centric measurements, but people are implementing tricky strategies to game those numbers with methods that, if anything, slightly harm user experience.
Direct Link to Article — Permalink
The post Tricking WCV appeared first on CSS-Tricks.
You can support CSS-Tricks by being an MVP Supporter.
Auditing CSS is not a common task in a developer’s everyday life, but sometimes you just have to do it. Maybe it’s part of a performance review to identify critical CSS and reduce unused selectors. Perhaps is part of effort to improve accessibility where all the colors used in the codebase evaluated for contrast. It might even be to enforce consistency!
Whatever the case and whenever that moment arrives, I usually reach for some of the tools I‘ll cover in the article. But before that, let’s see what it even means to “audit” CSS in the first place.
Generally, code auditing involves analyzing code to find bugs or other irregularities, like possible performance issues. For most programming languages, the concept of auditing code is relatively straightforward: it works or it doesn’t. But CSS is a specific language where errors are mostly ignored by browsers. Then there’s the fact that you could achieve the same style in many different ways. This makes CSS a little tricky to audit, to say the least.
Finding those errors might be prevented by using an extension for your favorite code editor or setting up a linter or code checker. But that is not what I want to show here, and that is not enough. We could still use too many colors, typographic definitions, or z-indexes, all of which could lead to a messy, unmaintainable, unstable CSS codebase.
To truly audit CSS, we would need to dig deeper and find places that are not considered best practices. To find those places, we could use the following tools.
Let’s take a look at the Chrome DevTools tools for CSS auditing. I’m using Brave here, which is Chromium-based. You might also want to check out this article by Umar Hansa, who compiled a whole bunch of great DevTool features that released in 2020.
If you like inspecting CSS code manually, there is the Inspect tool. Using that, we could see the CSS code applied to a specific element. Using the “Inspect arrow” we could even see additional details about colors, fonts, size and accessibility.
There’s a lot of practical details in the DevTools interface, but my favorite is the Grid and Flex inspector. To enable them, go to the Settings (a little gear icon at the top right of the DevTools), click on Experiments, then enable CSS Grid and Flexbox debugging features. Although this tool is mainly used for debugging layout issues, I sometimes use it to quickly determine if CSS Grid or Flexbox is even used on the page at all.
Inspecting CSS is pretty basic, and everything needs to be done manually. Let’s look at some more advanced DevTools features.
CSS Overview is one of them. To enable CSS Overview tool, go to the Settings, click on Experiments, and enable CSS Overview option. To open the CSS Overview panel, you could use the CMD
+Shift
+P
shortcut, type “css overview,” then select “Show CSS Overview.” This tool summarizes CSS properties like colors, fonts, contrast issues, unused declarations, and media queries. I usually use this tool to get the “feel” of how good or poor CSS code is. For example, if there are “50 shades of gray” or too many typographic definitions, that means that the style guide wasn’t respected, or one might not even exist.
The Coverage tool shows the amount and the percentage of code used on the page. To view it, use the CMD
+Shift
+P
shortcut, type “coverage,” select Show Coverage, and click on the “refresh” icon.
You could filter only CSS files by typing “.css” in the URL filter input. I usually use this tool to understand the delivery technique of the site. For example, if I see that the coverage is pretty high, I could assume that the CSS file is generated for each page separately. It may not be critical data to know, but sometimes it helps to understand the caching strategy.
The Rendering panel is another useful tool. To open the Rendering panel, use CMD
+Shift
+P
again, type “rendering” this time, and choose the “Show Rendering” option. This tool has many options, but my favorite ones are:
These tools are something that the regular audit doesn’t imply, but I find it essential to understand if the CSS code is performant and doesn’t drain a device’s energy.
Other options may be more beneficial for debugging issues, like emulation and disabling of various features, forcing the prefers-color-scheme
feature or print media type, and disabling local fonts.
Another tool for auditing the performance CSS code is the Performance Monitor. To enable it, use CMD
+Shift
+P
again, type “performance monitor,” and select the Show Performance Monitor option. I usually use this tool to see how many recalculations and layouts are triggered when interacting with the page, or when the animation occurs.
The Performance panel shows a detailed view of all browser events during page load. To enable the Performance tool, do CMD
+Shift
+P
, type “performance,” select Show Performance, then click the “reload” icon. I usually enable the “Screenshots” and “Web Vitals” options. The most interesting metrics to me are First Paint, First Contentful Paint, Layout Shifts, and Largest Contentful Paint. There is also a pie chart showing the Painting and Rendering time.
DevTools might not be considered a classical auditing tool, but it helps us understand which CSS features are used, the efficiency of the code, and how it performs — all of which are key things to audit.
DevTools is just one tool that is packed with a lot of features. But there are other available tools we can use to audit CSS.
Specificity Visualizer shows the specificity of CSS selectors in the codebase. Simply visit the site and paste in the CSS.
The main chart displays the specificity in relation to the location in the stylesheet. The other two charts show the usage of specificities. I often use this site to find “bad” selectors. For example, if I see many specificities marked as red, I could easily conclude that the code could be better. It is helpful to save the screenshots for reference as you work to improve things.
CSS Specificity Graph Generator is a similar tool for visualizing specificity. It shows a slightly different chart that might help you see how your CSS selectors are organized by specificity. As it says on the tool’s page, “spikes are bad, and the general trend should be towards higher specificity later in the stylesheet.” It would be interesting to discuss that further, but it’s out of scope for this article. However, Harry Roberts did write about it extensively in his article “The Specificity Graph” which is worth checking out.
CSS Stats is another tool that provides analytics and visualizations for your stylesheets. In fact, Robin wrote about it a little while back and showed how he used it to audit the stylesheet at his job.
All you need to do is to enter the URL of the site and hit Enter
. The information is segmented into meaningful sections, from declaration count to colors, typography, z-indexes, specificity, and more. Again, you might want to store the screenshots for later reference.
Project Wallace is made by Bart Veneman, who already introduced the project here on CSS-Tricks. The power of Project Wallace is that it can compare and visualize changes based on imports. That means you could see previous states of your CSS code base and see how your code changes between states. I find this feature quite useful, especially when you want to convince someone that the code is improved. The tool is free for a single project and offers paid plans for more projects.
In addition to DevTools and online tools, there are command line interface (CLI) tools that can help audit CSS.
One of my favorite CLI tools is Wallace. Once installed, type wallace
and then the site name. The output shows everything you need to know about the CSS code for the site. My favorite things to look at are the number of times !important
is used, as well as how many IDs are in the code. Another neat piece of information is the top specificity number and how many selectors use it. These might be red flags for “bad” code.
What I like the most about this tool is that it extracts all of the CSS code from the site, not only external files, but also inline code as well. That is why the report from CSS Stats and Wallace mismatch.
The csscss CLI tool shows which rules share the same declarations. This is useful for identifying duplicated code and opportunities to reduce the amount of code that’s written. I would think twice before doing that as it might not be worthwhile, especially with today’s caching mechanisms. It is worth mentioning that csscss requires Ruby.
Other CSS tools might not be used for auditing but are still useful. Let’s list those, too:
CSS is everywhere around us, and we need to consider it a first-class citizen of every project. It does not matter what other people think about your CSS, but what you think about it really does matter. If your CSS is organized and well-written, you will spend less time debugging it and more time developing new features. In an ideal world, we would educate everyone to write good CSS, but that takes time.
Let today be the day when you start caring for your CSS code.
I know that auditing CSS isn’t going to be fun for everyone. But if you run your code against any of these tools and try to improve even one part of your CSS codebase, then this post has done its job.
I am thinking about CSS code more and more lately, and I am trying to make more developers write CSS code more respectfully. I even started a new project at css-auditors.com (yay for hyphenated domain names!) that’s dedicated to auditing CSS.
If you know of any other tools, let me know in the comments.
The post Tools for Auditing CSS appeared first on CSS-Tricks.
You can support CSS-Tricks by being an MVP Supporter.
These things called passkeys sure are making the rounds these days. They were a main attraction at W3C TPAC 2022 , gained support in Saf...