Tag: Display

Careful When Changing the Display of `summary`

I got a very helpful bug report the other day (thanks Kilian!) about the <details> element in a blog post of mine not showing the default ▶ icon, and thus looking rather like any ol’ random <p>.

It wasn’t terribly hard to diagnose. I just opened the page in Firefox, inspected the element in Firefox DevTools, and played with properties and values until I saw the ▶ come back. The problem? I was using a (very old) copy of Normalize.css, which must have followed me through several redesigns on this site, and set…

summary {   display: block; /* the problem */ }

If you do that, Firefox nukes the ▶:

Way back in 2016, this was fixed by Jon Neal in Normalize:

summary {   display: list-item; }

In Chrome, the User Agent style for <summary> is block, so no problem with setting it to block. But in Firefox, best I can tell, the User Agent style is list-item.

Hence Jon setting it to list-item in the current version of Normalize.

You can also see in the Firefox DevTools that the ▶ is applied with a ::marker pseudo element. As soon as <summary> isn’t a list-item anymore, the ::marker disappears. I guess that makes some sense, as the spec says:

The ::marker pseudo-element represents the automatically generated marker box of a list item.

So the fact that ::marker works on block-level items in Chrome might be the bug? I dunno, but I kinda like having ::marker work on other things. As Šime Vidas once pointed out, it’s rather nice.

In Safari, there is no problem, as apparently the ▶ comes from “Shadow Content”???

Anyway, the Normalize idea of just forcing them to be list-item seems fine (or just don’t touch them at all).

The post Careful When Changing the Display of `summary` appeared first on CSS-Tricks.

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


, , ,

A Primer on Display Advertising for Web Designers

A lot of websites (this one included) rely on advertising as an important revenue source. Those ad placements directly impact the interfaces we build and interact with every day. Building layouts with ads in them is a dance of handling them in fluid environments, and also balancing the need to showcase our content and highlight the ads to make sure they are effective.

In this post, I am going to share a few tips and ideas for integrating ad units into layouts. We’ll take a look at some placement options where we might consider or commonly expect to place advertisements in webpages, then move into styling strategies.

I might use some modern CSS properties along the way that are not fully supported in older browsers. Take a look at @supports if you wish to support old browsers in a progressive enhancement friendly way.

Common Digital Ad Placements

There are many, many different places we can drop ads onto a page and an infinite number of sizes and proportions we could use. That said, there are standard placements and sizes that are commonly used to help establish a baseline that can be used to set pricing and compare metrics across the industry. We’ll cover a few of them here, though you can see just how many options and variations are in the wild.

The Navigation Bar Placement

The space right above the main navigation of a site is often a great placement to put an advertisement. It’s great because — in many cases — navigation is at the top of the page, providing a prominent location that both lends itself to using a full-width layout and lots of user interaction. That’s often why we see other types of important content, like alerts and notifications, occupy this space.

The easiest way to do this is simply placing the ad element above the navigation and call it a day. But what if we want to “stick” the navigation to the top of the page once the ad scrolls out of view?

Here we’re using position: sticky to get that effect on the navigation. As documented by MDN, a sticky element is where:

The element is positioned according to the normal flow of the document, and then offset relative to its nearest scrolling ancestor (and containing block).

It might be tempting to use fixed positioning instead, but that removes the navigation from the normal document flow. As a result, it gets fixed to the top of the viewport and stays there as you scroll. That makes sticky a more viable method with a smoother user experience.

A fixed element literally stays put while it remains in view, while a sticky element is able to “stick” to the top when it reaches there, then “unstick” upon return.

Now, we could do the reverse where the ad is the sticky element instead of the navigation. That’s something you’ll need to weigh because hiding the navigation from view could be poor UX in certain designs, not to mention how persistent advertisements could interfere with the content itself. In other words, tread carefully.

The Header Placement

Displaying ads in the site header is another place we commonly bump into advertisements. There are two widely used patterns using the header placement. In advertising industry jargon, they’re referred to as:

  • Billboard: A rectangular ad that is presented as a main call-to-action These are typically 970⨉250. We could use the widest size there, 970px, to set the size of a site’s main content area.
  • Leaderboard: An ad that is wide, short, and often shares space with another element. These are typically 728⨉90.

The billboard spot, despite being large, is rarely used (estimated at only 2% of sites), but they do command higher rates The leaderboard is far and away the most widely used digital ad size, with a 2019 SEMrush study citing 36% of publishers using leaderboards and 57% of advertisers purchasing them.

The nice thing about a leaderboard is that, even if we use the same 970px container width that the billboard ad command, we still have enough room for another element, such as a logo. I tend to use flexbox to separate the site logo from the ad. I also give the container a fixed height that either equals or is greater than the 90px leaderboard height.

.header .container {   /* Avoid content jumping */   height: 90px;   /* Flexibility */   display: flex;   align-items: center;   justify-content: space-between; }

The Sidebar Placement

The mid page unit ad (also known as medium rectangle) weighs in at 300⨉250 and is the top-performing ad unit — literally #1!

Google study of 2018 clickthrough rates (clicks per thousand views) compared for different ad placements. Google no longer provides these stats. (Source:Smart Insights)

Mid page units have influenced the design of sidebars on sites for a long time. Again, you can see an example right here on CSS-Tricks. 

Crack that open in DevTools and you will see that it has a rendered width of exactly 300px.

We can achieve the same thing using CSS grid:

Let’s say this is the markup of our layout:

<div class="wrapper">   <main>Main content</main>   <aside>Sidebar</aside> </div>

We can set the wrapper as our grid container and define two columns, the second of which is the exact 300px width of our ad unit:

.wrapper {   display: grid;   grid-template-columns: minmax(0, 1fr) 300px; }

If we aren’t displaying too many ads in the sidebar and want to draw more attention to them, we can try using the same sticky technique we did with the navigation placement:

<div class="wrapper">   <main>Main content</main>   <aside>     <div class="is-sticky">Sidebar</div>   </aside> </div>
.is-sticky {   position: sticky;   top: 0; }

But you must keep in mind that it will affect reach if the sidebar is longer than the viewport or when using a dynamic sidebar:

(View demo)

There are two ways I tend to solve this issue. The first is to keep it simple and only make important ads sticky. It’s the same concept applied to the CSS-Tricks sidebar, the only difference is that JavaScript toggles the visibility:

The second is to use a JavaScript library that includes scrolling behavior that can be used to listen for when the user reaches the end of the sidebar before triggering the sticky positioning:

There are other considerations when working with ads in the sidebar. For example, let’s say the ad we get is smaller than expected or the script that serves the ads fails for some reason. This could result in dreaded whitespace and none of the approaches we’ve looked at so far would handle that.

Where’d the widget go? The disable button is a simulation for an ad blocker.

Here’s how I’ve tackled this issue in the past. First, our markup:

<header class="header">   <div class="container">      <div class="header-content"> ... </div>          <aside class="aside">       <div class="aside-ad"> ... </div>       <div class="aside-content"> ... </div>     </aside>    </div> </header>

Then, we set the right measurements for the grid columns:

.header .container {   display: grid;   grid-template-columns: minmax(0, 1fr) 300px;   grid-gap: 24px;   min-height: 600px; /* Max height of the half-page ad */ }

Now let’s make the sidebar itself a flexible container that’s the exact width and height that we exact the ad to be, but hides any content that overflows it.

.aside {   display: flex;   flex-direction: column;   overflow: hidden;   height: 600px;   width: 300px; }

Finally, we can style the .aside-content element so that it is capable of vertical scrolling in the event that we need to display the widget:

.aside-content {   overflow-y: auto; }

Now, we’ve accounted for situations where the size of the ad changes on us or when we need fallback content.

No more whitespace, no matter what happens with our ad!

Styling Digital Ads

Now that we’ve looked at placements, let’s turn our attention to styling digital ads. It’s always a good idea to style ads, particularly for two reasons:

  1. Styling ads can help them feel like a native part of a website.
  2. Styling ads can make them more compelling to users.

Here are a few tips we can leverage to get the most from ads:

  • Use a flexible layout so things look good with or without ads. Let’s say an image doesn’t load for some reason or suddenly needs to be removed from the site. Rather than having to refactor a bunch of markup, it’s ideal to use modern CSS layout techniques, like flexbox and grid, that can adapt to content changes and reflow content, as needed.
  • Use styling that is consistent with the site design. Ads that look like they belong on a site are not only easier on the eye, but they leverage the trust that’s been established between the site and its readers. An ad that feels out of place not only runs the risk of looking spammy, but could compromise user trust as well.
  • Use a clear call to action. Ads should provoke action and that action should be easy to identify. Muddying the waters with overbearing graphics or too much text may negatively impact an ad’s overall performance.
  • Use accurate language. While we’re on the topic of content, make sure the ad delivers on its promises and sets good expectations for users. There’s nothing more annoying than expecting to get one thing when clicking on something only to be sold something else.
  • Use high-res images. Many ads rely on images to draw attention and emphasize content. When we’re working with ads that contain images, particularly smaller ad placements, it’s a good idea to use high-resolution images so they are crystal clear. The common way to do that is to make an image twice the size of the space to double its pixel density when it renders.

When working with custom ads where you have control over how they are implemented, like the ones here on CSS-Tricks, it’s a lot easier to adapt them to a specific layout and design. However, in cases where they are injected dynamically, say with a script, it might not be possible to wrap them in a div that can be used for styling; tactics like using ::before and ::after pseudo-elements as well as [attribute^=value] selectors are your friend in these situations.

Many advertising platforms will generate a unique ID for each ad unit which is great. They often start with the same prefix that we can use to target our styles:

[id^="prefix-"] {   /* your style */ }

Handling Responsive Ads

Ad platforms that provide a script to inject ads will often handle responsive sizing by bundling their own styles and such. But, when that’s not the case, or when we have complete control over the ads, then accounting for how they display on different screen sizes is crucial. Proper responsive handling ensures that ads have a clear call-to-action at any screen size.

Flexbox, Grid and nth-child

One thing we can do is re-order where an ad displays. Again, flexbox and grid are great CSS techniques to lean on because they employ the order property, which can change the visual placement of the ad without affecting the order of the actual source code.

In this example, we will try to reorder our items so the ad is visible “above the fold,” which is a fancy way of saying somewhere at the top of the page before the user needs to start scrolling.

Here’s our markup: 

<div class="items">   <div class="ad">...</div>   <div class="item">...</div>   <div class="item">...</div>   <!-- and so on... --> </div>

We can use :nth-child to select one or more items based on their source order, according to a formula:

.items {   display: grid;   /* ... */ } 
 .item:nth-child(-n+2) {   order: -1; } 
 @media only screen and (min-width: 768px) {   .article:nth-child(-n+3) {     order: -1;   } }

This selector will target the first n elements and set their order to a negative value. This allows the ad to dive between the items depending on the size of the viewport:

Handling Static Ads

Not all ads can be perfectly flexible… or are even designed to be that way. We can still sprinkle in some responsive behavior to ensure they still work with a layout at any given screen size.

For example, we can place the ad in a flexible container and hide the parts of the ad that overflow it.

Obviously, there’s a good deal of design strategy needed for something like this. Notice how the important ad content is flush to the left and the right is simply cut off.

Here’s the markup for our flexible container:

<div class="ad">   <img src="https://i.imgur.com/udEua3H.png" alt="728x90" /> </div>

Depending on whether the ad’s important content is on the left or right of the ad layout, we can justify the container content either to flex-start, flex-end, or even center, while hiding the overflowing portion.

.ad {   display: flex;   justify-content: flex-end; /* depending on the side your important content live */   overflow: hidden; }

Handling Responsive Images

While ads aren’t always made from static images, many of them are. This gives us an opportunity to put the  <picture> tag to use, which gives us more flexibility to tell the browser to use specific images at specific viewport sizes in order to fill the space as nicely as possible.

<picture>   <!-- Use the ad_728x90.jpg file at 768px and above  -->   <source media="(min-width: 768px)" srcset="ad_728x90.jpg">   <!-- The default file -->   <img src="ad_300x250"> </picture>

We covered it a little earlier, but using high-resolution versions of an image creates a sharper image, especially on high-DPI screen. The <picture> element can help with that. It’s especially nice because it allows us to serve a more optimized image for low-resolution screens that are often associated with slower internet speeds.

Another thing you can do is using srcset to support multiple display resolutions which will allow the browser to choose the appropriate image resolution:

<img srcset="ad_300x250@2.jpg, ad_300x250@2.jpg 2x" src="ad_300x250_fallback.jpg" />

We can even combine the two:

<picture>   <!-- ... -->   <source media="(min-width: 768px)" srcset="ad_728x90.jpg, ad_728x90@2.jpg 2x" />   <!-- ... -->   <img srcset="ad_300x250@2.jpg, ad_300x250@2.jpg 2x" src="ad_300x250_fallback.jpg" /> </picture>

Let’s make sure we set the right width for the ad:

.selector {   width: 250px; }

And let’s use media queries for <picture> to handle the different assets/sizes:

.selector {   width: 300px;   height: 250px; } 
 @media (min-width: 768px) {   .responsive-ad {     width: 728px;     height: 90px;   } }

For more flexibility, we can make the image responsive in relation to its parent container:

.selector img {   display: block;   width: 250px;   height: auto; }

In the case of srcset, there’s no need to worry much about performance because the browser will only download the needed asset for a specific resolution.

Phew, there’s so much to consider when it comes to display advertising! Different types, different sizes, different variations, different layouts, different formats, different viewport sizes… and this is by no means a comprehensive guide to all-things-advertising.

But hopefully this helps you understand the elements that make for effective ads as a site publisher, especially if you are considering ads for your own site. What we’ve covered here should certainly get you started and help you make decisions to get the most from having ads on a site while maintaining a good user experience.

The post A Primer on Display Advertising for Web Designers appeared first on CSS-Tricks.


, , ,

CSS Foldable Display Polyfill

Foldable phones are starting to be a thing. Early days, for sure, but some are already shipping, and they definitely have web browsers on them. Stands to reason that, as web designers, we are going to want to know where that fold is so we can design screens that fit onto the top half and bottom half… or left half and right half¹.

Looks like that’s going to make its way to us in the form of env() constants, just like all that notch stuff.

The code block in the polyfill repo is:

@media (spanning: single-fold-vertical) {   body {     flex-direction: row;   }   .map {     flex: 1 1 env(fold-left)   }   .locations-list {     flex: 1;   } }

I would also think it could be…

@media (spanning: single-fold-vertical) {   .page-wrap {     display: grid;     grid-template-columns: env(fold-left) 1fr;   } }

Interesting how there is no fold-right, isn’t it? And aren’t we trying to stay away from directional terms like that and use logical properties? Why not fold-inline-start?

  1. It’ll be interesting to see how that sentence ages. Just watch the first really popular foldable phone will have three segments.

The post CSS Foldable Display Polyfill appeared first on CSS-Tricks.


, ,

Careful with Nested `display: grid; height: 100%;`

It’s not every day you can feel CSS be slow at something. Reddit user jgbbrd discovered nesting grid containers that all have 100% height can cause many-seconds of rendering delay. Probably not something you’ll ever have to worry about, but still, interesting. From the comments:

  • What a funny use of the NSFW tag!
  • This is not an issue when using 100vh instead.

Direct Link to ArticlePermalink

The post Careful with Nested `display: grid; height: 100%;` appeared first on CSS-Tricks.


, , , , ,

Two-Value Display Syntax (and Sometimes Three)

You know the single-value syntax: .thing { display: block; }. The value “block” being a single value. There are lots of single values for display. For example, inline-flex, which is like flex in that it becomse a flex container, but behaves like an inline-level element rather than a block-level element. Somewhat intuitive, but much better served by a two-value system that can apply that same concept more broadly and just as intuitively.

For a deep look, you should read Rachel Andrew’s blog post The two-value syntax of the CSS Display property. The spec is also a decent read, as is this video from Miriam:

This is how it maps in my brain

Choose block or inline, then choose flow, flow-root, flex, grid, or table. If it’s a list-item that’s a third thing.

You essentially pick one from each column to describe the layout you want. So the existing values we use all the time map out something like this:

Another way to think about those two columns I have there is “outside” and “inside” display values. Outside, as in, how it flows with other elements around it. Inside, as in, how layout happens inside those elements.

Can you actually use it?

Not really. Firefox 70 is first out of the gate with it, and there are no other signals for support from Chrome-land or Safari-land that I know about. It’s a great evolution of CSS, but as far as day-to-day usage, it’ll be years out. Something as vital as layout isn’t something you wanna let fail just for this somewhat minor descriptive benefit. Nor is it probably worth the trouble to progressively enhance with @supports and such.


  • You can’t block flow because that doesn’t really make sense. It’ll be reset to block flow-root.
  • There is implied shorthand. Like if you inline list-item, that’s really inline flow list-item whereas list-item is block flow list-item. Looks all fairly intuitive.
  • You still use stuff like table-row and table-header-group. Those are single-value deals, as is contents and none.
  • Column one technically includes run-in too, but as far as I know, no browser has ever supported run-in display.
  • Column two technically includes ruby, but I have never understood what that even is.

How we talk about CSS

I like how Rachel ties this change to a more rational mental and teaching model:

… They properly explain the interaction of boxes with other boxes, in terms of whether they are block or inline, plus the behavior of the children. For understanding what display is and does, I think they make for a very useful clarification. As a result, I’ve started to teach display using these two values to help explain what is going on when you change formatting contexts.

It is always exciting to see new features being implemented, I hope that other browsers will also implement these two-value versions soon. And then, in the not too distant future we’ll be able to write CSS in the same way as we now explain it, clearly demonstrating the relationship between boxes and the behavior of their children.

The post Two-Value Display Syntax (and Sometimes Three) appeared first on CSS-Tricks.


, , , ,