Wednesday, 26 February 2020

Let’s Say You Were Going to Write a Blog Post About Dark Mode

This is not that blog post. I'm saying let's say you were.

This is not a knock any other blog posts out there about Dark Mode. There are lots of good ones, and I'm a fan of any information-sharing blog post. This is more of a thought exercise on what I think it would take to write a really great blog post on this subject.

  • You'd explain what Dark Mode is. You wouldn't dwell on it though, because chances are are people reading a blog post like this already essentially know what it is.
  • You'd definitely have a nice demo. Probably multiple demos. One that is very basic so the most important lines of code can be easily seen. Perhaps something that swaps out background-color and color. The other demo(s) will deal with more complex and real-world scenarios. What do you do with images and background images? SVG strokes and fills? Buttons? Borders? Shadows? These are rare things that sites have, so anyone looking at designing a Dark Mode UI will come across them.
  • You'd deal with the fact that Dark Mode is a choice that can happen at the operating system level itself. Fortunately, we can detect that in CSS, so you'll have to cover how.
  • JavaScript might need to know about the operating system choice as well. Perhaps because some styling is happening at the JavaScript level, but also because of this next thing.
  • Dark Mode could (should?) be a choice on the website as well. That servers cases where, on this particular site, a user prefers a choice opposite of what their operating system preference is.
  • Building a theme toggle isn't a small job. If your site has authentication, that choice should probably be remembered at the account level. If it doesn't, the choice should be remembered in some other way. One possibility is localStorage, but that can have problems, like the fact that CSS is generally applied to a page before JavaScript executes, meaning you're facing a "flash of incorrect theme" situation. You might be needing to deal with cookies so that you can send theme-specific CSS on each page load.
  • Your blog post would include real-world examples of people already doing this. That way, you can investigate how they've done it and evaluate how successful they were. Perhaps you can reach out to them for comment as well.
  • You'll be aware of other writing on this subject. That should not dissuade you from writing about the subject yourself, but a blog post that sounds like you're the first and only person writing about a subject when you clearly aren't has an awkward tone to it that doesn't come across well. Not only can you learn from others' writing, but you can also pull from it and potentially take it further.
  • Since you'll be covering browser technology, you'll be covering the support of that technology across the browser landscape. Are there notable exceptions in support? Is that support coming? Have you researched what browsers themselves are saying about the technology?
  • There are accessibility implications abound. Dark Mode itself can be considered an accessibility feature, and there are tangential accessibility issues here too, like how the toggle works, how mode changes are announced, and a whole new set of color contrasts to calculate and get right. A blog post is a great opportunity to talk about all that. Have you researched it? Have you talked to any people who have special needs around these features? Any experts? Have you read what accessibility people are saying about Dark Mode?

That was all about Dark Mode, but I bet you could imagine how considering all these points could benefit any blog post covering a technical concept.

The post Let’s Say You Were Going to Write a Blog Post About Dark Mode appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/381jJXb
via IFTTT

Chameleonic Header

Nice demo from Sebastiano Guerriero. When a fixed-position header moves from overlapping differently-colored backgrounds, the colors flop out to be appropriate for that background. Sebastiano's technique is very clever, involving multiple copies of the header within each section (where the copies are hidden from screenreaders) which are all positioned on top of each other and then revealed as the new section comes, thanks to each section having a clip-path around it.

A bonafide CSS trick if I've ever seen one.

It makes me wish there was an easier way of doing it. Like, what if there was some magical value of mix-blend-mode that would handle it? I got close enough that it gives me hope.

Direct Link to ArticlePermalink

The post Chameleonic Header appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/2uDXZ5Z
via IFTTT

Weaving a Line Through Text in CSS

Earlier this year, I came across this demo by Florin Pop, which makes a line go either over or under the letters of a single line heading. I thought this was a cool idea, but there were a few little things about the implementation I felt I could simplify and improve at the same time.

First off, the original demo duplicates the headline text, which I knew could be easily avoided. Then there's the fact that the length of the line going through the text is a magic number, which is not a very flexible approach. And finally, can't we get rid of the JavaScript?

So let's take a look into where I ended up taking this.

HTML structure

Florin puts the text into a heading element and then duplicates this heading, using Splitting.js to replace the text content of the duplicated heading with spans, each containing one letter of the original text.

Already having decided to do this without text duplication, using a library to split the text into characters and then put each into a span feels a bit like overkill, so we're doing it all with an HTML preprocessor.

- let text = 'We Love to Play';
- let arr = text.split('');

h1(role='image' aria-label=text)
  - arr.forEach(letter => {
    span.letter #{letter}
  - });

Since splitting text into multiple elements may not work nicely with screen readers, we've given the whole thing a role of image and an aria-label.

This generates the following HTML:

<h1 role="image" aria-label="We Love to Play">
  <span class="letter">W</span>
  <span class="letter">e</span>
  <span class="letter"> </span>
  <span class="letter">L</span>
  <span class="letter">o</span>
  <span class="letter">v</span>
  <span class="letter">e</span>
  <span class="letter"> </span>
  <span class="letter">t</span>
  <span class="letter">o</span>
  <span class="letter"> </span>
  <span class="letter">P</span>
  <span class="letter">l</span>
  <span class="letter">a</span>
  <span class="letter">y</span>
</h1>

Basic styles

We place the heading in the middle of its parent (the body in this case) by using a grid layout:

body {
  display: grid;
  place-content: center;
}
Screenshot of grid layout lines around the centrally placed heading when inspecting it with Firefox DevTools.
The heading doesn't stretch across its parent to cover its entire width, but is instead placed in the middle.

We may also add some prettifying touches, like a nice font or a background on the container.

Next, we create the line with an absolutely positioned ::after pseudo-element of thickness (height) $h:

$h: .125em;
$r: .5*$h;

h1 {
  position: relative;
  
  &::after {
    position: absolute;
    top: calc(50% - #{$r}); right: 0;
    height: $h;
    border-radius: 0 $r $r 0;
    background: crimson;
  }
}

The above code takes care of the positioning and height of the pseudo-element, but what about the width? How do we make it stretch from the left edge of the viewport to the right edge of the heading text?

Line length

Well, since we have a grid layout where the heading is middle-aligned horizontally, this means that the vertical midline of the viewport coincides with that of the heading, splitting both into two equal-width halves:

SVG illustration. Shows how the vertical midline of the viewport coincides with that of the heading and splits both into equal width halves.
The middle-aligned heading.

Consequently, the distance between the left edge of the viewport and the right edge of the heading is half the viewport width (50vw) plus half the heading width, which can be expressed as a % value when used in the computation of its pseudo-element's width.

So the width of our ::after pseudo-element is:

width: calc(50vw + 50%);

Making the line go over and under

So far, the result is just a crimson line crossing some black text:

What we want is for some of the letters to show up on top of the line. In order to get this effect, we give them (or we don't give them) a class of .over at random. This means slightly altering the Pug code:

- let text = 'We Love to Play';
- let arr = text.split('');

h1(role='image' aria-label=text)
  - arr.forEach(letter => {
    span.letter(class=Math.random() > .5 ? 'over' : null) #{letter}
  - });

We then relatively position the letters with a class of .over and give them a positive z-index.

.over {
  position: relative;
  z-index: 1;
}

My initial idea involved using translatez(1px) instead of z-index: 1, but then it hit me that using z-index has both better browser support and involves less effort.

The line passes over some letters, but underneath others:

Animate it!

Now that we got over the tricky part, we can also add in an animation to make the line enter in. This means having the crimson line shift to the left (in the negative direction of the x-axis, so the sign will be minus) by its full width (100%) at the beginning, only to then allow it to go back to its normal position.

@keyframes slide { 0% { transform: translate(-100%); } }

I opted to have a bit of time to breathe before the start of the animation. This meant adding in the 1s delay which, in turn, meant adding the backwards keyword for the animation-fill-mode, so that the line would stay in the state specified by the 0% keyframe before the start of the animation:

animation: slide 2s ease-out 1s backwards;

A 3D touch

Doing this gave me another idea, which was to make the line go through every single letter, that is, start above the letter, go through it and finish underneath (or the other way around).

This requires real 3D and a few small tweaks.

First off, we set transform-style to preserve-3d on the heading since we want all its children (and pseudo-elements) to a be part of the same 3D assembly, which will make them be ordered and intersect according to how they're positioned in 3D.

Next, we want to rotate each letter around its y-axis, with the direction of rotation depending on the presence of the randomly assigned class (whose name we change to .rev from "reverse" as "over" isn't really suggestive of what we're doing here anymore).

However, before we do this, we need to remember our span elements are still inline ones at this point and setting a transform on an inline element has absolutely no effect.

To get around this issue, we set display: flex on the heading. However, this creates a new issue and that's the fact that span elements that contain only a space (" ") get squished to zero width.

Screenshot showing how the span containing only a space gets squished to zero width when setting `display: flex` on its parent.
Inspecting a space only <span> in Firefox DevTools.

A simple fix for this is to set white-space: pre on our .letter spans.

Once we've done this, we can rotate our spans by an angle $a... in one direction or the other!

$a: 2deg;

.letter {
  white-space: pre;
  transform: rotatey($a);
}

.rev { transform: rotatey(-$a); }

Since rotation around the y-axis squishes our letters horizontally, we can scale them along the x-axis by a factor ($f) that's the inverse of the cosine of $a.

$a: 2deg;
$f: 1/cos($a)

.letter {
  white-space: pre;
  transform: rotatey($a) scalex($f)
}

.rev { transform: rotatey(-$a) scalex($f) }

If you wish to understand the why behind using this particular scaling factor, you can check out this older article where I explain it all in detail.

And that's it! We now have the 3D result we've been after! Do note however that the font used here was chosen so that our result looks good and another font may not work as well.

The post Weaving a Line Through Text in CSS appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/2wKdMAQ
via IFTTT

In-Browser Performance Linting With Feature Policies

Here’s a neat idea from Tim Kadlec. He uses the Modheader extension to toggle custom headers in his browser. It also lets him see when images are too big and need to be optimized in some way. This is a great way to catch issues like this in a local environment because browsers will throw an error and won’t display them at all!

As Tim mentions, the trick is with the Feature Policy header with the oversized-images policy, and he toggles it on like this:

Feature-Policy: oversized-images ‘none’;

Tim writes:

By default, if you provide the browser an image in a format it supports, it will display it. It even helpful scales those images so they look great, even if you’ve provided a massive file. Because of this, it’s not immediately obvious when you’ve provided an image that is larger than the site needs.

The oversized-images policy tells the browser not to allow any images that are more than some predefined factor of their container size. The recommended default threshold is 2x, but you are able to override that if you would like.

I love this idea of using the browser to do linting work for us! I wonder what other ways we could use the browser to place guard rails around our work to prevent future mistakes...

Direct Link to ArticlePermalink

The post In-Browser Performance Linting With Feature Policies appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/2uSklkw
via IFTTT

How Low Can #1 Go? (2020 Edition)

Posted by Dr-Pete

Being #1 on Google isn't what it used to be. Back in 2013, we analyzed 10,000 searches and found out that the average #1 ranking began at 375 pixels (px) down the page. The worst case scenario, a search for "Disney stock," pushed #1 all the way down to 976px.

A lot has changed in seven years, including an explosion of rich SERP (Search Engine Results Page) features, like Featured Snippets, local packs, and video carousels. It feels like the plight of #1 is only getting worse. So, we decided to run the numbers again (over the same searches) and see if the data matches our perceptions. Is the #1 listing on Google being pushed even farther down the page?

I try to let the numbers speak for themselves, but before we dig into a lot of stats, here's one that legitimately shocked me. In 2020, over 1,600 (16.6%) of the searches we analyzed had #1 positions that were worse than the worst-case scenario in 2013. Let's dig into a few of these ...

What's the worst-case for #1?

Data is great, but sometimes it takes the visuals to really understand what's going on. Here's our big "winner" for 2020, a search for "lollipop" — the #1 ranking came in at an incredible 2,938px down. I've annotated the #1 position, along with the 1,000px and 2,000px marks ...

At 2,938px, the 2020 winner comes in at just over three times 2013's worst-case scenario. You may have noticed that the line is slightly above the organic link. For the sake of consistency and to be able to replicate the data later, we chose to use the HTML/CSS container position. This hits about halfway between the organic link and the URL breadcrumbs (which recently moved above the link). This is a slightly more conservative measure than our 2013 study.

You may also have noticed that this result contains a large-format video result, which really dominates page-one real estate. In fact, five of our top 10 lowest #1 results in 2020 contained large-format videos. Here's the top contender without a large-format video, coming in at fourth place overall (a search for "vacuum cleaners") ...

Before the traditional #1 organic position, we have shopping results, a research carousel, a local pack, People Also Ask results, and a top products carousel with a massive vertical footprint. This is a relentlessly commercial result. While only a portion of it is direct advertising, most of the focus of the page above the organic results is on people looking to buy a vacuum.

What about the big picture?

It's easy — and more than a little entertaining — to cherry-pick the worst-case scenarios, so let's look at the data across all 10,000 results. In 2013, we only looked at the #1 position, but we've expanded our analysis in 2020 to consider all page-one organic positions. Here's the breakdown ...

The only direct comparison to 2013 is the position #1 row, and you can see that every metric increased, some substantially. If you look at the maximum Y-position by rank, you'll notice that it peaks around #7 and then begins to decrease. This is easier to illustrate in a chart ...

To understand this phenomenon, you have to realize that certain SERP features, like Top Stories and video carousels, take the place of a page-one organic result. At the same time, those features tend to be longer (vertically) than a typical organic result. So, a page with 10 traditional organic results will in many cases be shorter than a page with multiple rich SERP features.

What's the worst-case overall?

Let's dig into that seven-result page-one bucket and look at the worst-case organic position across all of the SERPs in the study, a #7 organic ranking coming in at 4,487px ...

Congratulations, you're finally done scrolling. This SERP has seven traditional organic positions (including one with FAQ links), plus an incredible seven rich features and a full seven ads (three are below the final result). Note that this page shows the older ad and organic design, which Google is still testing, so the position is measured as just above the link.

How much do ads matter?

Since our 2013 study (in early 2016), Google removed right-hand column ads on desktop and increased the maximum number of top-left ads from three to four. One notable point about ads is that they have prime placement over both organic results and SERP features. So, how does this impact organic Y-positions? Here's a breakdown ...

Not surprisingly, the mean and median increase as ad-count increases – on average, the more ads there are, the lower the #1 organic position is. So why does the maximum Y-position of #1 decrease with ad-count? This is because SERP features are tied closely to search intent, and results with more ads tend to be more commercial. This naturally rules out other features.

For example, while 1,270 SERPs on February 12 in our 10,000-SERP data set had four ads on top, and 1,584 had featured snippets, only 16 had both (just 1% of SERPs with featured snippets). Featured snippets naturally reflect informational intent (in other words, they provide answers), whereas the presence of four ads signals strong commercial intent.

Here's the worst-case #1 position for a SERP with four ads on top in our data set ...

The college results are a fairly rare feature, and local packs often appear on commercial results (as anyone who wants to buy something is looking for a place to buy it). Even with four ads, though, this result comes in significantly higher than our overall worst-case #1 position. While ads certainly push down organic results, they also tend to preclude other rich SERP features.

What about featured snippets?

In early 2014, a year after our original study, Google launched featured snippets, promoted results that combine organic links with answers extracted from featured pages. For example, Google can tell you that I am both a human who works for Moz and a Dr. Pepper knock-off available at Target ...

While featured snippets are technically considered organic, they can impact click-through rates (CTR) and the extracted text naturally pushes down the organic link. On the other hand, Featured Snippets tend to appear above other rich SERP features (except for ads, of course). So, what's the worst-case scenario for a #1 result inside a featured snippet in our data set?

Ads are still pushing this result down, and the bullet list extracted from the page takes up a fair amount of space, but the absence of other SERP features above the featured snippet puts this in a much better position than our overall worst-case scenario. This is an interesting example, as the "According to mashable.com ..." text is linked to Mashable (but not considered the #1 result), but the images are all linked to more Google searches.

Overall in our study, the average Y-position of #1 results with featured snippets was 99px lower/worse (704px) than traditional #1 results (605px), suggesting a net disadvantage in most cases. In some cases, multiple SERP features can appear between the featured snippet and the #2 organic result. Here's an example where the #1 and #2 result are 1,342px apart ...

In cases like this, it's a strategic advantage to work for the featured snippet, as there's likely a substantial drop-off in clicks from #1 to #2. Featured snippets are going to continue to evolve, and examples like this show how critical it is to understand the entire landscape of your search results.

When is #2 not worth it?

Another interesting case that's evolved quite a bit since 2013 is brand searches, or as Google is more likely to call them, "dominant intent" searches. Here's a SERP for the company Mattress Firm ...

While the #1 result has solid placement, the #2 result is pushed all the way down to 2,848px. Note that the #1 position has a search box plus six full site-links below it, taking up a massive amount of real estate. Even the brand's ad has site-links. Below #1 is a local pack, People Also Ask results, Twitter results from the brand's account, heavily branded image results, and then a product refinement carousel (which leads to more Google searches).

There are only five total, traditional organic results on this page, and they're made up of the company's website, the company's Facebook page, the company's YouTube channel, a Wikipedia page about the company, and a news article about the company's 2018 bankruptcy filing.

This isn't just about vertical position — unless you're Mattress Firm, trying to compete on this search really doesn't make much sense. They essentially own page one, and this is a situation we're seeing more and more frequently for searches with clear dominant intent (i.e. most searchers are looking for a specific entity).

What's a search marketer to do?

Search is changing, and change can certainly be scary. There's no question that the SERP of 2020 is very different in some ways than the SERP of 2013, and traditional organic results are just one piece of a much larger picture. Realistically, as search marketers, we have to adapt — either that, or find a new career. I hear alpaca farming is nice.

I think there are three critical things to remember. First, the lion's share of search traffic still comes from traditional organic results. Second, many rich features are really the evolution of vertical results, like news, videos, and images, that still have an organic component. In other words, these are results that we can potentially create content for and rank in, even if they're not the ten blue links we traditionally think of as organic search.

Finally, it's important to realize that many SERP features are driven by searcher intent and we need to target intent more strategically. Take the branded example above — it may be depressing that the #2 organic result is pushed down so far, but ask yourself a simple question. What's the value of ranking for "mattress firm" if you're not Mattress Firm? Even if you're a direct competitor, you're flying in the face of searchers with a very clear brand intent. Your effort is better spent on product searches, consumer questions, and other searches likely to support your own brand and sales.

If you're the 11th person in line at the grocery checkout and the line next to you has no people, do you stand around complaining about how person #2, #7, and #9 aren't as deserving of groceries as you are? No, you change lines. If you're being pushed too far down the results, maybe it's time to seek out different results where your goals and searcher goals are better aligned.

Brief notes on methodology

Not to get too deep in the weeds, but a couple of notes on our methodology. These results were based on a fixed set of 10,000 keywords that we track daily as part of the MozCast research project. All of the data in this study is based on page-one, Google.com, US, desktop results. While the keywords in this data set are distributed across a wide range of topics and industries, the set skews toward more competitive "head" terms. All of the data and images in this post were captured on February 12, 2020. Ironically, this blog post is over 26,000 pixels long. If you're still reading, thank you, and may God have mercy on your soul.


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!



from The Moz Blog https://ift.tt/2VpFgpY
via IFTTT

Tuesday, 25 February 2020

Responsive Grid Magazine Layout in Just 20 Lines of CSS

I was recently working on a modern take of the blogroll. The idea was to offer readers a selection of latest posts from those blogs in a magazine-style layout, instead of just popping a list of our favorite blogs in the sidebar.

The easy part was grabbing a list of posts with excerpts from our favorite RSS feeds. For that, we used a WordPress plugin, Feedzy lite, which can aggregate multiple feeds into a single time-ordered list — perfect for showcasing their latest offerings. The hard part was making it all look awesome.

The plugin’s default list UI is rather bland, so I wanted to style it to look like a newspaper or magazine website with a mixture of smaller and larger “featured content” panels.

This seems like an ideal case for CSS Grid! Create a grid layout for different layouts, say, one five-column layout and one three-column layout, then use media queries to switch between them at different break points. Right? But do we actually need those media queries — and all the hassle of identifying break points — when we can use grid’s auto-fit options to automatically create a fluid responsive grid for us? 

The approach sounded tempting, but when I started introducing column-spanning elements, I ran into trouble with the grid overflowing on narrow screens. Media queries appeared to be the only solution. That is, until I found a workaround!

After looking at several tutorials on CSS Grid, I found that they largely fall into two camps:

  1. Tutorials that show you how to create an interesting layout with spanned elements, but for a fixed number of columns.
  2. Tutorials that explain how to make a responsive grid that resizes automatically, but with all of the grid items the same width (i.e. without any spanned columns).

I want to make the grid do both: create a fully responsive fluid layout that includes responsively resizing multi-column elements as well.

The beauty is that once you understand the limitations of responsive grids, and why and when column spans break grid responsiveness, it is possible to define a responsive magazine/news style layout in just a dozen lines of code plus one simple media query (or even with no media queries if you are willing to limit your span options).

Here’s a visual showing the RSS plugin right out of the box and what it’ll look like after we style it up. 

(Demo)

This magazine-style grid layout is fully responsive with the colored featured panels adjusting dynamically as the number of columns change. The page displays around 50 posts, but the layout code is agnostic as to the number of items displayed. Ramp up the plugin to show 100 items and the layout stays interesting all the way down.

All of this is achieved using only CSS and with only a single media query to deal with a single column display on the narrowest of screens (i.e. smaller than 460px).

Incredibly, this layout only took 21 lines of CSS (excluding global content styling). However, to achieve such flexibility in such a few lines of code, I had to dig deep into the more obscure parts of some of  CSS Grid and learn how to work around some of its inherent limitations.

The essential elements of the code that produce this layout is incredibly short and a testament to the awesomeness of CSS Grid:

.archive {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  grid-gap: 32px;
  grid-auto-flow: dense;
}

/* Extra-wide grid-posts */
.article:nth-child(31n + 1) {
  grid-column: 1 / -1;
}
.article:nth-child(16n + 2) {
  grid-column: -3 / -1;
}
.article:nth-child(16n + 10) {
  grid-column: 1 / -2;
}

/* Single column display for phones */
@media (max-width: 459px) {
  .archive {
    display: flex;
    flex-direction: column;
  }
}

The techniques in this article could be used equally well to style any dynamically generated content such as the output from a latest posts widget, archive pages or search results.

Creating a responsive grid

I have set up seventeen items displaying a variety of mock content — headlines, images and excerpts — which are all contained in a wrapper

<div class="archive">
  <article class="article">
    <!-- content -->
  </article>
  
  <!-- 16 more articles -->
  
</div>

The code that turns these items into a responsive grid is remarkably compact:

.archive {
  /* Define the element as a grid container */
  display: grid;
  /* Auto-fit as many items on a row as possible without going under 180px */
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  /* A little spacing between articles */
  grid-gap: 1em;
}

Notice how the heights of the rows automatically adjust to accommodate the tallest content in the row. If you change the width of the Pen, you will see the items grow and shrink fluidly and the number of columns change from one to five, respectively.

The CSS Grid magic at play here is the auto-fit keyword that works hand-in-hand with the minmax() function that’s applied to grid-template-columns.

How it works

We could have achieved the five-column layout alone using this:

.archive {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
}

However, this would create five columns that grow and shrink with different screen widths, but always stay at five columns, resulting in them becoming ridiculously narrow on small screens. The first thought might be to create a bunch of media queries and redefine the grid with different numbers of columns. That would work fine, but with the auto-fit keyword, it is all done automatically.

For auto-fit to work the way we want, we need to use the minmax() function. This tells the browser how small the columns can be squeezed down to followed by the maximum width they can expand to. Any smaller, and it will automatically reduce the number of columns. Any larger, and the number of columns increases.

.archive {
  grid-template-columns: repeat (auto-fit, minmax(180px, 1fr));
}

In this example, the browser will fit in as many columns as it can 180px wide. If there is space left over the columns will all grow equally by sharing the remaining space between them —  that’s what the 1fr value is saying: make the columns equal fractions of the available width. 

Drag the window out and as the available space increases the columns all grow equally to use up any additional space. The columns will keep growing until the available space allows for an additional 180px column, at which point a whole new column appears. Decrease the screen width, and the process reverses, perfectly adjusting the grid all the way down to a single column layout. Magic!

And you get all this responsiveness out of just one line of code. How cool is that? 

Creating spans with “autoflow: dense”

So far, we have a responsive grid but all items the same width. For a news or magazine layout we need some content to be featured by spanning two or more columns or even, perhaps, to span all the columns.

To create multi-column spans we can add the column-span feature to the grid items we want to take up more space. For example, if we want the third item in our list to be two columns wide we can add:

.article:nth-child(3) {
  grid-column: span 2;
}

However, once we start adding spans a number of problems can arise. First, gaps may appear in the grid because a wide item may may not fit on the row, so grid auto-fit pushes it onto the next line, leaving a gap where it would have been:

The easy fix is adding grid-auto-flow: dense to the grid element which tells the browser to fill in any gaps with other items, effectively making the narrower content flow around the wider items like this:

Note that the items are now out of order, with the fourth item coming before the third item, which is double the width. There is no way round this as far as I can tell, and it is one of the limitations you have to accept with CSS Grid.

Check out Geoff Graham’s "The Auto-Flowing Powers of Grid’s Dense Keyword” for an introduction to grid-auto-flow: dense with examples of how it behaves.

Ways to specify spans

There are several ways to indicate how many columns an item should span. The easiest is to apply grid-columns: span [n] to one of the items, where n  is the number of columns the element will span. The third item in our layout has grid-column: span 2, which explains why it is double the width of other items that only span a single column.

Other methods require you to explicitly define grid lines. The numbering system for grid lines is as follows:

Grid lines can be specified from left-to-right using positive values (e.g. 1, 2, 3) or negative values (e.g. -1, -2, -3) to go from right-to-left. These can be used to place items on the grid using the grid-column property like this:

.grid-item {
  grid-column: (start track) / (end track);
}

So, this gives us additional ways to specify a spanned item. This is especially flexible as either the start or end value can be replaced with the span keyword. For example, the three-column blue box in the example above could be created by adding any of the following to the eighth grid item:

  • grid-column: 3 / 6
  • grid-column: -4 / -1
  • grid-column: 3 / span 3
  • grid-column: -4 / span 3
  • grid-column: span 3 / -1
  • Etc.

On a non-responsive (i.e. fixed columns) grid, these all produce the same effect (like the blue box above), however, if the grid is responsive and the number of columns changes, their differences start to become apparent. Certain column spans break the  layout with an auto-flowing grid, making the two techniques appear incompatible. Fortunately, there are some solutions which allow us to combine the two successfully. 

First, however, we need to understand the problem.

Overflow side-scrolling problems

Here are some featured areas created using the notation above:

(Demo)

It all looks good at full-width (five columns) but when resized to what should be two columns, the layout breaks like this:

 As you can see, our grid has lost its responsiveness and, although the container has shrunk, the grid is trying to maintain all five columns. To do so, it has given up trying to keep equal-width columns, and the grid is breaking out of the right-hand side of its container, causing horizontal scrolling.

Why is this? The problem comes about because the browser is trying to honor the explicit grid lines we named. At this width, the auto-fit grid should implicitly be displaying two columns, but our grid line numbering system contradicts this by explicitly referring to the fifth grid line. This contradiction leads to the mess. To display our implicit two-column grid correctly, the only line numbers allowed are 1, 2 and 3 and -3, -2, -1, like this:

But if any of our grid items contains grid-column references that lie outside this, such as grid line number 4, 5 or 6 (or -4, -5 or -6), the browser is getting mixed messages. On the one hand, we have asked it to automatic create flexible columns (which should implicitly give us two columns at this screen width) but we have also explicitly referred to grid lines that don’t appear in a two-column grid. When there is a conflict between implicit (automatic) columns and an implicit number of columns, grid always defers to the explicit grid; hence the unwanted columns and horizontal overflow (which has also been aptly named CSS data loss). Just like using grid line numbers, spans can also create explicit columns. So, grid-column: span 3 (the eighth grid item in the demo) forces the grid to explicitly adopt at least three columns, whereas we want it, implicitly display two.

At this point it might seem like the only way forward is to use media queries to change the grid-column values at the width where our layout breaks — but not so fast! That’s what I assumed at first. But after thinking it though a bit more and playing around with various options, I found there are a limited set of workarounds that work all the way down to two columns, leaving just one media query to cover a single column layout for the narrowest screens.

The solutions

The trick, I realized, is to only specify spans using grid lines that appear in the narrowest grid you intend to display. That is a two-column grid in this case. (We will use a media query to cover the single column scenario for very narrow screens.) That means we can safely use grid lines 1, 2 and 3 (or -3, -2 and -1) without breaking the grid.

I initially thought that meant limiting myself to a maximum span of two columns, using combinations of the following:

  • grid column: span 2
  • grid-column: 1 /3
  • grid-column: -3 / -1

Which remains perfectly responsive right down to two columns:

Although this works, it is rather limiting from a design perspective, and not particularly exciting. I wanted to be able to create spans that would be three, four or even five columns wide on large screens. But how? My first thought was that I would have to resort to media queries (OMG old habits die hard!) but I was trying to get away from that approach and think differently about responsive design.

Taking another look at what we can do with just 1 to 3 and -3 to -1, I gradually realized that I could mix positive and negative line numbers for the grid column’s start and end values ,such as 1/-3 and 2/-2. At first glance, this does not seem very interesting. That changes when you realize where these lines are located as you resize the grid: these spanned elements change width with the screen size. This opened up a whole new set of possibilities for responsive column spans: items that will span different numbers of columns as the screen gets wider, without needing media queries.

The first example I discovered is grid-column: 1/-1.This makes the item act like a full-width banner, spanning from the first to the last column at all column numbers. it even works down to one column wide!

By using grid-column: 1/-2, a left-aligned nearly-full-width span could be created that would always leave a one column item to the right of it. When shrunk to two columns it would shrink responsively to a single column. Surprisingly, it even works when shrunk to a single column layout. (The reason seems to be that grid will not collapse an item to zero width, so it remains one column wide, as does grid-column: 1/1.) I assumed grid-column: 2/-1 would work similarly, but aligned with the right-hand edge, and for the most part it does, except at one column display when it causes overflow.

Next I tried 1/-3  which worked fine on wider screen, showing at least three columns, and smaller screens, showing one column. I thought it would do something weird on a two-column grid as the first grid line is the same as the grid line with -3. To my surprise, it still displays fine as a single-column item. 

After a lot of playing around, I came up with eleven possible grid column values using grid line numbers from the two-column grid. Surprisingly, three of these work right down to single-column layouts. Seven more work down to two columns and would only need a single media query to deal with single column display.

Here is the full list:

Responsive grid-column values, showing how they display at different screen sizes in an auto-fit grid. (Demo)

As you can see, although this is a limited subset of every possible responsive span, there are actually a lot of possibilities.

  • 2/-2 is interesting as it creates a centered span which works all the way down to one column! 
  • 3/-1 is  least useful as it causes overflow even with two-columns.
  • 3/-3 was a surprise.

By using a variety of grid-column values from this list, it is possible to create an interesting and fully responsive layout. Using a single media query for the narrowest single-column display, we have ten different grid-column span patterns to play with.  

The single-column media query is generally straightforward as well. The one on this final demo reverts to using flexbox at smaller screens:

@media (max-width: 680px) {
  .archive {
    display: flex;
    flex-direction: column;
  }

  .article {
    margin-bottom: 2em;
  }
}

Here is the final grid which, as you can see, is fully responsive from one to five columns:

(Demo)

Using :nth-child() to repeat variable length displays

The last trick I used to get my code down to two dozen lines was the :nth-child(n) selector which I used to style multiple items in my grid. I wanted my span styling to apply to multiple items in my feed, so that the featured post boxes appeared regularly throughout the page. To start with I used a comma-separated selector list, like this:

.article:nth-child(2),
.article:nth-child(18),
.article:nth-child(34),
.article:nth-child(50)  {
  background-color: rgba(128,0,64,0.8);
  grid-column: -3 / -1;
}

But I soon found this cumbersome, especially as I had to repeat this list for each child element I wanted to style within each article — such as the title, links and so on. During prototyping, if I wanted to play around with the position of my spanned elements, I had to manually change the numbers in each of these lists, which was tedious and error prone.

That’s when I realized that I could use a powerful feature :nth-child pseudo-selector instead of a simple integer as I had used in the list above. :nth-child(n) can also take an equation, such as :nth-child(2n+ 2), which will target every second child element.

Here is how I used the :nth-child([formula]) to create the blue full-width panels in my grid which appear at the very top of the page, and is repeated just over half way down:

.article:nth-child(31n + 1) {
  grid-column: 1 / -1;
  background: rgba(11, 111, 222, 0.5);
}

The bit in the brackets (31n + 1 ) ensures that the 1st, 32nd, 63rd, etc. child is selected. The browser runs a loop starting with n=0 (in which case 31 * 0 + 1 = 1), then n=1 (31 * 1 + 1 = 32), then n=2 (31 * 2 + 1 = 63). In the last case, the browser realizes that  there is no 63rd child item so it ignores that, stops looping, and applies the CSS to the 1st and 32nd children.

I do something similar for the purple boxes which alternate down the page from right-to-left:

.article:nth-child(16n + 2) {
  grid-column: -3 / -1;
  background: rgba(128, 0, 64, 0.8);
}

.article:nth-child(16n + 10) {
  grid-column: 1 / -2;
  background: rgba(128, 0, 64, 0.8);
}

The first selector is for the right-hand purple boxes. The 16n + 2 makes sure that the styling applies to every 16th grid item, starting with the second item.

The second selector targets the right-hand boxes. It uses the same spacing (16n) but with a different offset (10). As a result, these boxes appear regularly on the right-hand side for grid items 10, 26, 42, etc.

When it comes to the visual styling for these grid items and their contents, I used another trick to reduce repetition. For styles that both boxes share (such as the background-color, for example) a single selector can be used to target both:

.article:nth-child(8n + 2) {
  background: rgba(128, 0, 64, 0.8);
  /* Other shared syling */
}

This will target items 2, 10, 18, 26, 34, 42, 50, and so forth.  In other words,  it selects both the left- and right-hand featured boxes.

It works because 8n is exactly half of 16n, and because the offsets used in the two separate selectors have a difference of 8 (i.e. the difference between +10 and +2 is 8) 

Final thoughts

Right now, CSS Grid can be used to create flexible responsive grids with minimal code, but this does come with some significant limitations on positioning elements without the retrograde step of using media queries.

It would be great to be able to specify spans that would not force overflow on smaller screens. At the moment, we effectively tell the browser, “Make a responsive grid, please,” which it does beautifully. But when we continue by saying, “Oh, and make this grid item span four columns,” it throws a hissy-fit on narrow screens, prioritizing the four-column span request rather than the responsive grid. It would be great to be able to tell grid to prioritize responsiveness over our span request. Something like this:

.article {
  grid-column: span 3, autofit;
}

Another issue with responsive grids is the last row. As the screen width changes the last row will frequently not be filled. I spent a long time looking for a way to make the last grid item span (and hence fill) the remaining columns, but it seems you can’t do it in Grid right now. It would be nice if we could specify the item’s start position with a keyword like auto meaning, “Please leave the left-hand edge wherever it falls.” Like this:

.article {
  grid-column: auto, -1;
}

…which would make the left-hand edge span to the end of the row.

The post Responsive Grid Magazine Layout in Just 20 Lines of CSS appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/2uslRJF
via IFTTT

Are H1 Tags Necessary for Ranking? [SEO Experiment]

Posted by Cyrus-Shepard

In earlier days of search marketing, SEOs often heard the same two best practices repeated so many times it became implanted in our brains:

  1. Wrap the title of your page in H1 tags
  2. Use one — and only one — H1 tag per page

These suggestions appeared in audits, SEO tools, and was the source of constant head shaking. Conversations would go like this:

"Silly CNN. The headline on that page is an H2. That's not right!"
"Sure, but is it hurting them?"
"No idea, actually."

Over time, SEOs started to abandon these ideas, and the strict concept of using a single H1 was replaced by "large text near the top of the page."

Google grew better at content analysis and understanding how the pieces of the page fit together. Given how often publishers make mistakes with HTML markup, it makes sense that they would try to figure it out for themselves.

The question comes up so often, Google's John Muller addressed it in a Webmaster Hangout:

"You can use H1 tags as often as you want on a page. There's no limit — neither upper nor lower bound.
H1 elements are a great way to give more structure to a page so that users and search engines can understand which parts of a page are kind of under different headings, so I would use them in the proper way on a page.
And especially with HTML5, having multiple H1 elements on a page is completely normal and kind of expected. So it's not something that you need to worry about. And some SEO tools flag this as an issue and say like 'oh you don't have any H1 tag' or 'you have two H1 tags.' From our point of view, that's not a critical issue. From a usability point of view, maybe it makes sense to improve that. So, it's not that I would completely ignore those suggestions, but I wouldn't see it as a critical issue.
Your site can do perfectly fine with no H1 tags or with five H1 tags."

Despite these assertions from one of Google's most trusted authorities, many SEOs remained skeptical, wanting to "trust but verify" instead.

So of course, we decided to test it... with science!

Craig Bradford of Distilled noticed that the Moz Blog — this very one — used H2s for headlines instead of H1s (a quirk of our CMS).

H2 Header
h1 SEO Test Experiment

We devised a 50/50 split test of our titles using the newly branded SearchPilot (formerly DistilledODN). Half of our blog titles would be changed to H1s, and half kept as H2. We would then measure any difference in organic traffic between the two groups.

After eight weeks, the results were in:

To the uninitiated, these charts can be a little hard to decipher. Rida Abidi of Distilled broke down the data for us like this:

Change breakdown - inconclusive
  • Predicted uplift: 6.2% (est. 6,200 monthly organic sessions)
  • We are 95% confident that the monthly increase in organic sessions is between:
    • Top: 13,800
    • Bottom: -4,100
The results of this test were inconclusive in terms of organic traffic, therefore we recommend rolling it back.

Result: Changing our H2s to H1s made no statistically significant difference

Confirming their statements, Google's algorithms didn't seem to care if we used H1s or H2s for our titles. Presumably, we'd see the same result if we used H3s, H4s, or no heading tags at all.

It should be noted that our titles still:

  • Used a large font
  • Sat at the top of each article
  • Were unambiguous and likely easy for Google to figure out

Does this settle the debate? Should SEOs throw caution to the wind and throw away all those H1 recommendations?

No, not completely...

Why you should still use H1s

Despite the fact that Google seems to be able to figure out the vast majority of titles one way or another, there are several good reasons to keep using H1s as an SEO best practice.

Georgy Nguyen made some excellent points in an article over at Search Engine Land, which I'll try to summarize and add to here.

1. H1s help accessibility

Screen reading technology can use H1s to help users navigate your content, both in display and the ability to search.

2. Google may use H1s in place of title tags

In some rare instances — such as when Google can't find or process your title tag — they may choose to extract a title from some other element of your page. Oftentimes, this can be an H1.

3. Heading use is correlated with higher rankings

Nearly every SEO correlation study we've ever seen has shown a small but positive correlation between higher rankings and the use of headings on a page, such as this most recent one from SEMrush, which looked at H2s and H3s.

To be clear, there's no evidence that headings in and of themselves are a Google ranking factor. But headings, like Structured Data, can provide context and meaning to a page.

As John Mueller said on Twitter:

What's it all mean? While it's a good idea to keep adhering to H1 "best practices" for a number of reasons, Google will more than likely figure things out — as our experiment showed — if you fail to follow strict H1 guidelines.

Regardless, you should likely:

  1. Organize your content with hierarchical headings — ideally H1, H2s, H3s, etc.
  2. Use a large font headline at the top of your content. In other words, make it easy for Google, screen readers, and other machines or people reading your content to figure out the headline.
  3. If you have a CMS or technical limitations that prevent you from using strict H1s and SEO best practices, do your best and don't sweat the small stuff.

Real-world SEO — for better or worse — can be messy. Fortunately, it can also be flexible.


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!



from The Moz Blog https://ift.tt/2HVbjpH
via IFTTT

Passkeys: What the Heck and Why?

These things called  passkeys  sure are making the rounds these days. They were a main attraction at  W3C TPAC 2022 , gained support in  Saf...