Medium-like Posts for WordPress

Although the single-column full-width style has been around for a while, I think Medium popularised it by putting it out there in a distraction-free manner. There’s few features on the surface and no clutter hampering the content. Because of its simplicity, it isn’t very opinionated and works well for many people (such in the case of Medium, where everyone is “restricted” to the same design).

The key idea behind this sort of design is that it (hopefully) provides a superior reading experience, whereby there’s nothing else standing between the reader and the core content. The design continually leads you into the content, and freely uses the space it has been been granted.

Within WordPress however, we’ve come to recognise a particular style. We often see two columns (content + sidebar) as well as a footer area that has three or four columns for widgets. Even today, default themes are still being shipped with a template component called sidebar.php. This sort of wording sets the wrong expectations.

With our single column approach, instead of having something along the lines of:

.col-content {
    width: 800px; // or % width, flex, etc.
}

We now simply declare nothing at all. The parent container for content simply spans across the entire page. In turn, the child elements (text, images, media, etc.) that make up the content, now have to take on additional properties.

Handling Content

My posts are predominantly made up of text, but it likely isn’t wise to let text stretch like that on larger displays. There are countless articles on the topic, but you’ll generally find that they call for 50 to 75 characters per line. With our new found freedom, this means we’ll need to dial it in and control it. As there are a fair amount of textual elements (more than my other elements), we can tighten them up using something along the lines of:

.entry-content > * {
    max-width: 800px;
    margin-left: auto;
    margin-right: auto;
}

Using the direct descender with a universal selector enables us to set a foundation, but at the same time easily allows anything to change with a bit more specificity, for instance .entry-content > blockquote.

Handling Images

Using the above example, all images will also be limited in width. But what if we wanted to create a full-width image? We could use the full size image format to help target the images we want to show at full width:

.entry-content > img.size-full {
     max-width: 100%
}

There’s only one problem with that, WordPress by default encapsulates images with a Paragraph selector. In my opinion, it doesn’t make sense to have images inside of a paragraph unless they’re providing some form of inline value.
With that in mind, we can remove the P tags in a non-destructive manner using a filter (via CSS-Tricks):

function filter_ptags_on_images( $content ){
    return preg_replace( '/<p>\s*(<a .*>)?\s*(<img .* \/>)\s*(<\/a>)?\s*<\/p>/iU', '\1\2\3', $content );
}
add_filter( 'the_content' , 'filter_ptags_on_images' );

This means we get a nice result like this now:

Wapuu Pins

We’re not quite in the clear yet, as adding a link or caption (or both) adds additional elements around the image. Unfortunately, via WordPress you can’t specifically target those parent wrappers, nor can you go upstream with CSS (yet). So there’s no way to tell a link apart for example.
To assist us, we should add a class on the parent called wp-image-parent as well as bubble up any additional classes you desire. This allows us to make the same statement as before, but to also account for various image options.

.entry-content > .wp-image-parent.size-full {
    max-width: 100%
}

It’s not the best of solutions as it causes a reflow, but here’s the jQuery I’ve thrown in:

	$( 'a, .wp-caption', '.entry-content' ).each( function( i, e ) {

			if ( $( this ).find( 'img' ).length !== 0 ) {
				$imgClasses = $( 'img', this ).attr( 'class' );
				$( this ).addClass( 'wp-image-parent ' + $imgClasses );
			}

	});

This enables us now to target captions too, like the image below:

Contributor Day at WordCamp Tokyo
Contributor Day at WordCamp Tokyo, having a monitor on each table was a big win.

I’ve been doing all this as part of my own sites redesign, so I’m still working through everything. The code could be cleaner and better organised, but I hope you’re able to understand the idea I’m pursuing and how I’m getting there. Feedback and thoughts welcome.

  • Thanks for sharing. Recently setup my personal WP.com site and went for a theme called Coherent which has a similar design but misses out on the full-width images/captions. Nice touch. I was actually quite surprised that it was so hard to find the one-column, clean styling that Medium has used to great effect. I hope we see more of this.

  • Great article, Noel!

    Can you let me know if you added some other hacks to prevent conflicts with responsive images feature added in 4.4? I have a theme where I use full-width images, but it looks that the 4.4 update caused a smaller image size to be used, and I guess that this may be related to the content wrapper width or the_content_width value.
    http://demo.wpzoom.com/tempo/2015/07/20/maecenas-sed-diam-eget-risus-varius-blandit-sit-amet-non-magna/

    Not sure if the attached screenshot helps, but for now I’ve disabled this feature on the demo page using Disable Responsive Images plugin, so that may be handy for someone else having the same problem :)
    https://wordpress.org/plugins/disable-responsive-images/

    On another note, for a more Medium-like experience, I’d also recommend this plugin that loads the next posts on scroll:
    https://wordpress.org/plugins/auto-load-next-post/

    I’ve noticed that Medium don’t use this feature anymore, so probably it’s more in Quartz style now http://qz.com/

  • Thanks for the comment! Haven’t had a chance to dig into the responsive stuff as much as I’ve wanted too yet. With this particular layout it works quite well because the content area = window width, so you don’t have to anything crazy (like I used to with wordpress.org/extend/plugins/hammy/ ).

    I definitely have a few other hacks, but I need to clean up the code some more before I drop it on Github. Tempo is looking really good :+1:

  • Yeah, coherent is really nice (link for others reading https://theme.wordpress.com/themes/coherent/ ). I’m guessing the full width thing still has some room to grow (in terms of being a “trend”), feel like others will still continue to adopt it.

  • Loved this Noel. I’d just style a little different the caption text (maybe just making it italics would be good). And yes, as you said, the medium-like layout improves readability.

    Been questioning also the comment system: do you think medium-like comments would improve the engagement on WordPress-based websites? I’m not 100% sure about this, but I think it would.

  • Thank you for taking out the time to write a post and put across your thoughts for N00bs like me. Loved the structure and the tone of the post.

    Keep up the good work.