WordCamp Dev Talk: Breaking the Mould
October 28, 2012 -This is the post to compliment my Toronto Developer’s WordCamp 2012 talk! At the bottom you’ll find links to my demo, test theme and theme XML! #WCTO. You can watch the presentation on WordPress.tv here.
Remember the good old days of web before Content Management Systems were rampant?! You could make any part of the site look pretty much however you wanted (why you could even have rounded corners in a table with as few as 8 images). You could do this because you had to manually build and style every single lousy thing on the page. Come to think of it, maybe the old days weren’t so good after all…
One of the reasons we as a species invented CMS was so we could stop repeating work, and let robots figure it all out. That’s the great thing about a tool like WordPress; you just plug in the content and WordPress will format it all the same! Every post as far as the eye can see as cookie cuttered as the last… that’s actually supposed to sound like a good thing.
The best thing about a CMS is also the worst thing about a CMS: Uniformity.
What do you do if you actually want a post to stand out and look unique?! There can be several really good reasons to do this!
We’ll examine a couple routes to take to achieve this lofty goal, and impress those jerks from high school who said you’d never amount to anything.
I should warn in advance (this is also a general hat tip to the blood thirsty trolls who are only reading this so they can call me names), that some of the following can be used for pure evil! You could easily make a site look just terrible! I’m also going to share a technique that is controversial – but we’re all adults here, and I trust you to do the right thing.
You will need some CSS to make all of this work, but you don’t actually need to know CSS for the following concepts to make sense. We’re going to focus on the approaches to give yourself the ability to style uniquely in the future.
SEVERAL APPROACHES
We’re going to look at the pros and cons to doing this in a couple ways. These are all at the theme level to varying degrees. We’re going to focus on Posts for this demo, but a similar approach can be taken for Custom Post Types, widgets or Pages as well. I’ll talk about the Posts styles in two ways. Firstly, the list view – this is when WordPress shows a feed of posts, sometimes just the excerpts. By default this is the front page with ten posts. Secondly, we’ll talk about the single view. This is the page you come to when you view a post all by itself.
For these approaches I may be referring to my demo which you can check out here: http://rle.me/9r (http://test.mapleunderground.com/wcto-unique-styles/). There are download links at the bottom of this post for the XML and themes.
BE LAZY.
I aspire to be the best developer possible, therefore I should try to be as lazy as possible! We don’t need to make this any more complicated than this needs to be! To do this the best way possible you really need to understand well what you’re trying to achieve, and only solve that problem or you stand the risk of creating new ones.
1. Reusable Theme Elements
The easiest and lowest impact approach would be to add some CSS to your theme’s global style.css file for a reusable selector (not a unique element like post ID). If you have the Jetpack plugin installed you can add the CSS in the Appearance tab. A couple ideas come to mind here!
1a. Sticky Posts: Since WordPress 2.7 we’ve been able to make a post “sticky” in the post listings section of the backend – just click Quick Edit. Once Sticky, it will stay at the top of your posts feed – subsequently published posts will go below it. If you’re just trying to get the attention of a reader to a special post this is a fantastic tool. You can also just style the class .sticky in your stylesheet! In our demo I’ve added a blue background to this sticky post.
This is a great approach for calling attention to posts only temporarily, with the intention that they’ll look generic in the archives. A post is only sticky in the list view; in the single view it’s just a normal post without the .sticky class.
As an example, you might make a post sticky and stick out if it was a call for submissions on a site – once the call was passed, you could remove its stickiness and let it blend in again for the archives.
1b. Category: Categories are a very useful bit of meta data that can easily be styled. This is reusable and sortable (meaning you can style multiple posts similarly, and you can click go into a Category view to see all posts of that category)! Bulletins or posts of a particular kind can all be styled in a similar way – this is also just good user experience! Styling these is a matter of styling a class like .category-breakfast which gets a green background in our demo. The category name becomes a class by way of a function that’s called in the theme called post_class.
An example of this could be for the 2013 WordCamp Toronto site. They do the occasional post in the category of .category-featured-speaker which could by styled with different colours to stand out from general updates (not a commentary!).
Categories have contentual meaning – a word I made up to convey that the actual name should related to the content (think for instance of a newspaper’s categories: news, sports, editorial, etc). In my demo I’ve used less content-aware names like “uncategorized” and “styled” to show off the functionality. Rather than ever have a category called “styled” a much better compound category name might be “important”, or “exclusive”. The content should be supported by the category name!
1c. Post Formats: Post formats still seem new to me! WordPress allows you to enable some new formats to a theme. They include Gallery, Quote, Video, Aside, etc. and our old friend Standard. Just like the Category these can be reused for multiple posts; but aren’t sortable in the way that Categories can be (which may also be advantageous. For example, why would anyone want to see every day where weather cancelled an event?). Formatting all Asides to look a similar way is as simple as adding your attributes to .format-aside. In our demo my asides get green text.
Note that these Post Formats weren’t created just to be alternately styled posts. For that reason they aren’t always formatted in the same way as the standard post. Even in my demo I had to overwrite a few styles. Twenty Eleven is a wonderfully built theme if you would like to understand better how these are marked up by default, and how to manipulate them.
These three options are reusable, and the meta data of sticky, category, and post format will all export from one blog to another (even if that post format isn’t enabled on the receiving WP site).
2. Style by Post ID
If you truly are styling a post as a one-off that won’t ever be used on another post the most tempting and obvious approach would by styling by the post ID. You can find the unique ID of a post in a few ways; in the URL bar of the post editing screen, in the <article> or <div> tag on the front end (using Firefox or a Web Inspector), or in the status bar when you hover over a link in the post listings.
Most themes will add the post’s unique ID and apply it as a class and/or ID to the content container (as mentioned above, this is the post_class() function at work). Take this Twentyeleven post container for instance:
<article id="post-35" class="post-35 post type-post status-publish format-standard hentry category-uncategorized">
Now before you go and chuck some new post-specific rules into your theme’s style.css, gently handcuff yourself to a rusty radiator. That’s a terrible idea that ultimately ends ten years from now with you going insane as you sift through a 15MB stylesheet with rules for posts no user has read since before Palin administration.
The demo theme I’ve created uses a better option. A simple bit of code in the function.php file will make your posts work differently: when you surf to the post the function will figure out that the post’s ID is 123, and check if your theme has a style-123.css. If you do, it will load those styles. The advantage is that this CSS won’t load unless it’s needed – so other users aren’t needlessly downloading these styles! The alternative is a bloated global stylesheet that is full of styles that the average user will never make use of! Nightmarish.
In the first instance of the unique-by-ID demo our CSS is only loaded on the single page. This is a pretty safe and cool way to make all of your posts unique for reading. Who cares if the excerpts all look the same?!
…OK, maybe you do… In the content.php file I’ve also created some logic that can apply a post’s unique CSS sheet to the list view. Be careful with that! This requires your CSS to be written specifically for that post’s parent tag by ID, or you’re going to make changes to that entire list page! In my demo this second example uses a different style sheet for the list view and single view. You could easily just use one style sheet for both though.
Doing a post-specific style sheet can result in a lot of CSS management, but all your styles will be together! If you have multiple authors it’s important to remember that everyone will need FTP access for this to work, or you might want to get a protocol droid.
One MASSIVE catch is naturally the whole idea of styling by a Post’s ID. If you export your data and import it into another WordPress installation all of those IDs will be different. Think about how much fun that would be to deal with :S. Even in developing this theme locally I ran into this when exporting to a public server. I had 3 style sheets to rename, then change the style names within as well. It was a hassle.
3. SCOPED CSS
On the bleeding edge lives an amazing little attribute that is new to HTML5 that will be either loved or hated by developers – and no emotion in between: <style scoped>.
This allows you to put a style block full of rules in your markup. Every element inside the parent container can by styled by this style block, but not the rest of the page! With Scoped CSS, a style block inside of a WordPress post will only style that post. Cool huh?! We’ll look at how to do this with Custom Fields.
Check out this simple HTML demo: http://arleym.com/scopedcss/static/index2.html
The Nasty Bit
I first read about Scoped CSS in 2011 (in a book (noun): a collection of wood-pulp based fiber “sheets” with text on it. Like a static version of a screen (not related to Facebook)). and instantly saw it as a solution to this common CMS woe. Months later I still couldn’t find much info about this online, so I wrote an introductory post about it for CSS-Tricks. Soon after the story was picked up by WIRED Magazine’s Web Monkey (when you see your name misspelled on a site of that magnitude you know you’ve made it!).
The reaction was mixed. Some people think it’s terrible, and some really really think it’s terrible.
I do want to take time to defend this approach. Yes, as a rule inline CSS should be avoided. Where possible it’s great to keep your markup, data, styles and functionality all separated. This doesn’t always happen. Some people draw a line in the sand and will hold their breath until they pass out if you try to ever suggest such an audacious thought. These same people though may unknowingly be using jQuery’s .css method for passing simple JavaScript functionality to objects.
Bad news trolls! .hide() is calling an inline style!
They do have a point. You can take this too far – Scoped CSS is for creating exceptions to the standard rules outlined in your global style sheets. Don’t let me catch you reusing these blocks! With great power comes great clichés. Use this wisely.
Another gripe these wet blankets may voice is the browser support…
OK, maybe they have a point. Thankfully we have @thingsinjars (more about his story at the bottom of this post)! Simon Madine created a jQuery plugin that makes this work!
Get Started with Scoped!
First create a test post! I added the Custom Field of “scopedcss” and added rules like p {color:red}. Note: If you don’t see Custom Fields below your post area, check out your screen options at the top right of the WordPress admin.
Next you’ll need to have jQuery in your theme, then call the Scoped CSS library , and initialize it. I’ve done this in my footer.php (included in the theme).
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <script src="<?php bloginfo( 'stylesheet_directory' ); ?>/jquery.scoped.js"></script><script> $(document).ready(function() { $.scoped(); // this can go in your global JS file }); </script>
Finally I added the logic that looks for the scopedcss Custom Field, and injects it into the loop. I have done this in content.php and content-single.php within the parent <article> tag as I’m working with Twenty Eleven. You may only have to do this in loop.php depending what theme you’re using.
<?php $scopedcss = get_post_meta($post->ID, 'scopedcss', false); foreach($scopedcss as $css) { echo '<style scoped>'.$css.'</style>'; } ?>
Now you’ve scoped some CSS! It doesn’t strictly keep all of your CSS together like styling by ID, but I actually prefer the modularity of having the styles relative to the post they belong to. Another advantage to this is other authors can take advantage of unique styling without needing FTP access to your theme.
Do I love how many inline styles the JS adds? Not really, but in the end the functionality is decent – and the workflow is great. From a web site owner’s perspective this is a dream – even more so when it’s a browser standard supported element.
4 CUSTOM FIELDS
This is like the marriage of all three other options. Using PHP logic in the way we did for the Scoped CSS, we can pass Custom Field values from the post to the template easily right? You could just inject new classes to the parent <article> tag in this way. Then you can choose how reusable your styles are either with Posts by ID, or in your global style sheet, or with Scoped CSS.
This doesn’t technically add anything that we haven’t achieved with the above methods however, so I’ve not done it in the demo. Adding CSS to global styles isn’t any easier. Unique styles should still be in their own style sheet. It can give you a unique selector for Scoped CSS, but then so could a post ID.
There are really just three places where this would make the above methods better or safer:
- You want to do something along the lines of a Post Format, but you’re using all of the Post Formats for their legitimate intended purpose, and you don’t want something with semantic, sortable value like a category getting involved. Then you should add a class via Custom Field. Super reusable.
- You want to style by Post ID, but will need to export your posts from one installation to another. Your Custom Fields will export as well, and can be a great unique selector that will export along with CSS. You can modify the Post ID logic we used in that example to get the value of the custom field and look for a stylesheet of that name.
- If you wanted to use Scoped CSS but are concerned for users without JS enabled, then you can create selectors that will prevent the CSS from applying to other page elements by being post specific (and you don’t want to use Post ID). Heck, you wouldn’t have to scope, it could be a raw style block. Dangerous, but doable.
WHICH APPROACH IS FOR YOU?
It’s so important to understand what problem you’re solving before making a decision. I don’t think this is necessarily something to add just for a cool factor. I would start with studying analytics and see what your users are doing, and just try to tweak to increase conversions to your site’s goals.
There are likely ways to solve this with plugins. If that works for you check it out (I’d love your feedback in the comments if you have a good solution with a plugin). As a rule, I like to use as few plugins as possible, particularly if this is about styling the theme!
Before you choose ask yourself some questions:
- Do you want styles that you’ll want to reuse, or is this truly a one-off styling that you’re after?
- Who is going to create and maintain all of this CSS?
- Is it a good thing or bad thing if authors can only add styles with FTP?
- Are your authors cool with Custom Fields?
- Do you have a staging environment set up to test styles before the public sees them?
- Are you going to be exporting your posts in such a way as to change their IDs?
PROS AND CONS!
All require theme modification and comfort with CSS.
1. Style by Post Format / Category / Sticky:
PROS:
- Reusable, can live in main stylesheet. Set it and forget it!
- Can be compounded to create different style combinations
- These types of content can be exported and keep their special properties!
CONS:
- Requires Theme access and testing (or something like the Jetpack CSS editor). Tinkering with global styles on a live site isn’t a best practice
- Not truly unique
- Compound styling can be unpredictable, especially with multiple authors
- More difficult to add on the fly
2. Style by Post ID
PROS
- You can prevent users without FTP access from doing this / messing up the site
- It’s simple to implement – copy, paste code in a one-time setup
- It keeps all of your CSS in one place
- It’s so logical to uniquely style an element by its unique ID
CONS
- Authors can only do this if they have FTP access
- Once enough posts are done in this way this folder may get confusing “What is style-9876.css again?ˆ”
- If you export your posts from this site into another the IDs will change.
- For me, extra steps required for authoring will breed procrastination and disuse. I need the fewest steps possible to publish content regularly.
3. Styling with Scoped CSS:
PROS:
- It’s modular: content and style together. Content with styles, makes more sense to me for management / workflow.
- Can be used without theme access (great for multi author sites)
- Post can be exported and styles will go with – ID independently styling
- Custom Fields can be made to be more convenient
- Easy to implement
- For me this has the lowest barrier to creating a post and styling it on a whim
CONS:
- Styles aren’t all together, they’re technically in the data.
- Requires JS for now, browser support seems slow
- This can be abused badly or used as a crutch
CLOSING THOUGHTS!
There’s a lot to consider before you even touch code. Once it’s setup your new workflow should be pretty straightforward!
Need more of a challenge? How about making this usable for n00bs? If CSS would be a bit too hard for your clients to write you can get really fancy with some Advanced Custom Fields and predefining some select lists for your clients to choose from. You can then create tasteful pallets of colours and fonts with which to customize posts.
Remember, this is the kind of raw power that will lead to a Comic Sans saturated internet. If we have to burn this Internet to the ground and make a new one as a result, please don’t tell anyone you got any ideas from me.
SLIDESHOW RESOURCES
There are links throughout the slides, but some key ones are:
- Link to demo: http://rle.me/9r
- Link to verbose post version of my talk: http://arleym.com/wordcamp-dev-talk-breaking-the-mould-with-scoped-css/
- My electronic mail myfriendarley at arleym dot see, eh?
- Twitter: @ArleyM
- CSS-Tricks – Saving the Day with Scoped CSS: http://css-tricks.com/saving-the-day-with-scoped-css/
- An appropriate and tweetable animated gif to express your happiness at all of this http://rle.me/x/joy.gif
- Download demo theme: http://arleym.com/scopedcss/download/twentytwelve_uniquestyles.zip
- Download demo XML http://arleym.com/scopedcss/download/breakingthemould.wordpress.2012-10-30.xml
- Link to slideshow: http://rle.me/9w (10MB, I suggest downloading from home, or see me for USB stick at #WCTO)
ABOUT @THINGSINJARS:
I used to do a lot of agency work either building adverts to embed in other peoples sites or embedding other people’s ad units in client sites. One day when reading through the CSS spec (as every self-respecting dev does, of course) I saw the scoped attribute and immediately thought that would make things a lot easier. I could write my little advert units as contained HTML elements with no external dependencies and not care whether they were pulled in via iframe or embedded directly in the page. Similarly, if other people wrote their widgets nice and self-contained, they could be pulled in and we’d never have to worry about style collisions.
Once you start thinking along those lines, a lot of other possibilities start to appear – individual blog posts that need one particular style, widgets (such as jQuery UI stuff), etc – these can be completely self-contained and included/embedded anywhere without worrying about the effects.
There’s not a huge amount I could add beyond what’s in the blog post about it:
http://thingsinjars.com/post/359/css-scoped/
Categorized in: Elsewhere
This post was written by ArleyM