Creating markup in CSS

Sometimes the markup provided by a WordPress plugin isn’t quite what you want. If editing the plugin itself isn’t an option, maybe you can fake it with CSS.

I really like Jetpack; I especially like the image grid display it provides for the Top Posts & Pages widget, and I built custom styles for it into Cover. But there was a limit to what it provided. It doesn’t, for example, display the title along with the image.

The title shows up if you hover over the link, sure. (That’s the title attribute in action.) But what about touchscreen devices? No, they’d just have to click on the link and hope for the best. I didn’t like that.

So this is some example markup output from Jetpack’s Top Posts & Pages widget (I trimmed it down to just a couple post links, as opposed to the six that appear in eichefam.net’s overlay, and I’ve also limited it to the important bits):

<div class="widgets-grid-layout no-grav">
  <div class="widget-grid-view-image">
    <a href="/2015/05/12/mourning-grandma/" title="Mourning Grandma">
      <img src="/assets/IMG_1250.jpg" alt="Mourning Grandma">
    </a>
  </div>
  <div class="widget-grid-view-image">
    <a href="/2012/04/12/scrollable-menus-in-bootstrap/" title="Scrollable menus in Bootstrap">
      <img src="/assets/awhCbhLqRceCdjcPQUnn_IMG_0249.jpg" alt="Scrollable menus in Bootstrap">
    </a>
  </div>
</div>

As I mentioned, the title is there. It just isn’t being provided in a container we can display. Or is it? Both the image and the link have the text; we just need to know how to grab it. Pseudo-elements to the rescue!

When we define :before or :after for an element, we don’t have to make the content text static. We can grab the content of an attribute, and that’s just what we’ll do here by using title. We want to make sure we only target links inside Jetpack’s grid view container, the class widget-grid-view-image. While we’re at it, we’ll make sure we only target links that have a title. (There shouldn’t ever be an instance where this isn’t true, but it’s good practice to consider edge cases.)

.widget-grid-view-image a[title]:after {
  content: attr(title);
}

If we’re just aiming for something simple, this is enough. The post title will show up beneath each image. But I wanted something a little more fancy. I settled on text that overlaid the image, with a slight darkened gradient to make the text a little more readable.

.widget-grid-view-image a[title]:after {
  content: attr(title);
  position: absolute;
  width: 100%;
  bottom: 0;
  padding: 10px;
  font-size: 14px;
  background-image: linear-gradient(rgba(0,0,0,0), rgba(0,0,0,0.5));
  color: #fff;
}

One thing left to consider. The text should be contained to inside each grid block, so I needed to specify relative positioning on the containing element — in this case, the link itself.

.widget-grid-view-image a[title] {
  position: relative;
}

So this is the result, without having to hack the plugin. (According to Can I Use, pseudo-element support is up to date on all modern browsers.)

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Related