Be prepared for Bootstrap v4

The upgrade from Twitter’s Bootstrap 2 to Bootstrap 3 was not painless. The current 3.2.0. release will give you some insights for the coming v4 release of Bootstrap. The 3.2.0. already adds some new things such as the responsive utility classes now have variants for diferents CSS display property values. The most important change till now, seems to be the adding of vendor prefixes to the CSS code automatically.

Responsive utility classes

In stead of the .visible-* classes (deprecated as of v3.2.0) you are now enable to use or .visible-*-block, .visible-*-inline or .visible-*-inline-block. The hidden-* classes don’t change because of they set the display to none always. The .visible-*-inline classes can be used to hide and display inline elements such as the <span> element. Consider the following example code to see the difference:

<p>This is a paragraph. <span class="visible-xs">(Small grid)</span>.</p>
<p>This is a paragraph. <span class="visible-xs-inline">(Small grid)</span>.</p>

As you can see in the image shown beneath, the layout of the paragraph has been broken in the first situation:

Wrong layout of the paragraph due to display:block

The .visible-xs class changed the display of the span element to block. Block level elements start on a new line and take all available space.

Better responsive display for embedded media

Bootstrap adds new classes for embedding media with <iframe>, <embed> and <object> elements. These classes keep the aspect ratio of your media intact when scaling down for different screen widths. With Bootstrap 3.2 you can use the following code:

<!-- 16:9 aspect ratio -->
<div class="embed-responsive embed-responsive-16by9">
<iframe class="embed-responsive-item" src="…"></iframe>
</div>

Try it a find your videos will look great again. Use the .embed-responsive-4by3 class for the 4:3 ratio.

Using autoprefixer as part of build system

The autoprefixer adds vendor prefixes to your CSS code automatically. Using the autoprefixer allows you to only use W3C property declarations in the Less code. More clean and consistent Less code will be the big win here. Note that as also described in my Less Web Development Essentials book:

Vendor-specific rules also provide us with early implementations of standard properties, and alternative syntax.

If you take a look into the <code>/less</code> directory you will find that the mixins are modularized into separate files inside the <code>/less/mixins</code> directory. Before v3.2.0 vendor prefixes where set by mixins. These mixins for vendor prefixes are moved to the less/mixins/vendor-prefixes.less for backward compatibility reasons now. These vendor prefixes are deprecated as of v3.2.0 and will be dropped in v4.

Who used Grunt to build the Bootstrap CSS already will full profit from these change. People who compile the Bootstrap Less code with an other Less compiler for their projects will find some troubles since version v3.2.0. Till v4 new and improved code will not any longer prefixed by Less. Impossibilities in your build process to auto prefix your code automatically will cause non-prefixed CSS in your code base.

To get insight in the consequences of these change you can compare the CSS code build with the Bootstrap build process and the CSS code when compiling with Less directly. Run the following commands in your Bootstrap directory:


>> grunt dist
>> lessc less/bootstrap.less nonprefixed.css
>> diff -b nonprefixed.css dist/css/bootstrap.css

After running the preceding command you will find for instance the following code:

1345c1359,1360
< box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);
---
> -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
> box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);

When inspecting the compiled CSS will show you that the box-shadow property for the kbd selector is not prefixed if not using the autoprefixer. The preceding will be due to the Less code for the kbd selector in the less/code.less file does not call the .box-shadow() mixin. Before v3.2.0 not calling the prefixed mixins could be considered as an bug, since v3.2.0 these issues are solved by the autoprefixer automatically. Cause the non mixin calling code will be the prefered code for version 3.2+ and the coming version 4 of Bootstrap this code should not changed any more. Consequently the browser support of the CSS code which has been compiled by Less directly and did not run through the autoprefixer will decrease compared to Bootstrap original CSS code.

The best solution for this issue is to change your build process to enable the autoprefixer as recommended by Bootstrap. Unfortunately some situations can’t be solved this way. Grunt and so the autoprefixer requires Node.js which is not available in some situations. You can read more about this issue in my next post about the JBST WordPress starters theme, which has a built-in Less compiler based on PHP.

Bootstrap 3.2.0 and Shrinkwrap

When running npm install with the latest 3.2.0. release of Bootstrap I found the following error:

Loading "Gruntfile.js" tasks...ERROR
>> AssertionError: args.type is required
Warning: Task "dist" not found. Use --force to continue.

This issue can be solved by running the grunt update-shrinkwrap task just after npm install.

With version 3.2.0. Booststrap switch to the npm version of shrinkwrap. Shrinkwrap locks down the versions of a package’s dependencies so that you can control exactly which versions of each dependency will be used when your package is installed.
The Shrinkwrap task should be run whenever Bootstrap’s dependencies change and so you will have to run it after npm install.

WordPress: How to reverse the comment order with paged comments

In the settings panel of the WordPress Dashboard you will find the Discussion Settings. These settings enable you to create paged comments. You can set the top level comments per page, if you want to show the first or last page by default and if the oldest or newest comments should be shown on the to of each page.

In the situation that you want to show the newest comments first, you can set that the last page should showed be default with the newest comments on the top of each page. These setting are also shown in the following figure:

discussion settings expected

When using these settings i found some unexpected behavior. If you set the number of comments per page to 10 and for instance the total number of comments on your page is 44, you will get the following situation: The default page contains the 4 newest comments, and the next 4 pages contain 10 older comments each. In this situation i expected the newest 10 comments on the first page and the oldest 4 comments on the fifth and last page.

This strange behaviour will be due to the setting which shows the latest page first. If you inspect the comment queries in wp-includes/comments-template.php you will find that all comments are loaded with the oldest first (ORDER BY comment_date_gmt). Pages are created with an instance of the Walker_Comment class. This walker_Comment class create each page the same way. Order per page can be set with the reverse_top_level Boolean option (if not set the option when calling wp_list_comments() in your template the oldest/newest setting from the Discussion Settings will be used). The reverse_top_level option will only set the order per page and not the order for all comments.

Solution: reverse the comments array

The order issue with paged comments can be solved by using a filters which reverse the comments array returned by the database query in wp-includes/comments-template.php. After querying the database to get the list of comments the code applies the comments_array filter. You use this filter to reverse the comments array by adding the following code to your function.php file:

add_filter('comments_array',function($comments){return array_reverse($comments);});

When using the filter described above the Discussion Settings can be set to show the first page by default and the oldest comments first as be shown in the following figure:

discussion settings improved

Notice that the setting to show the oldest comments first seems to be strange if you want to show the newest comments first. When this setting is set to “oldest” the reverse_top_level Boolean option will be set to false, which means that the results per page are not reversed. That’s right because of the order of the comments is already set from new to old after reversing the comments array by the filter.

After applying the comments_array function you should also have to change the text or images used by the previous_comments_link() and next_comments_link() functions. The next link should refer to older comments instead of newer comments and so the previous links should refer to the older comments.

Further improvements

It seems interesting to take a look at the HTML link elements rel="next" and rel="prev" to indicate the relation between the pages with the comments. Some SEO plugins set these links, it’s unclear how reversing the comments influence that for now.
Finally you will find that the content of the page will be repeated on every comment page now. Paging your comment with jQuery which doesn’t reload the page can be an intresting strategy to investigate too. The jPages pagination for WordPress plugin integrates pagination for comments.