Getting Bootstrap Tabs to Play Nice with Masonry

Originally published at: http://www.sitepoint.com/bootstrap-tabs-play-nice-with-masonry/

On the Masonry website, we read that Masonry is

… a JavaScript grid layout library. It works by placing elements in optimal position based on available vertical space, sort of like a mason fitting stones in a wall.

Bootstrap is one of the most widely adopted open source front-end frameworks. Include Bootstrap in your project, and you’ll be able to whip up responsive web pages in no time.

If you tried using Masonry together with the Tabs widget, one of the many JavaScript components Bootstrap has to offer, chances are you’ve stumbled on some kind of annoying behavior.

I did, and this article highlights what the issue is and what you can do to solve it.

Bootstrap Tabs Explained

Bootstrap’s Tabs component includes two key, related pieces: a tabbed navigation element and a number of content panels. On page load, the first panel has the class .active applied to it. This enables the panel to be visible by default. This class is used via JavaScript to toggle the panel’s visibility via the events triggered by the tabbed navigation links: if .active is present the panel is visible, otherwise the panel is hidden.

If you have some web content that’s best presented in individual chunks, rather than crammed all in one spot, this kind of tabs component might come in handy.

Why Masonry?

In some cases, the content inside each panel is suited to being displayed in a responsive grid layout. For instance, a range of products, services, and portfolio items are types of content that can be displayed in grid format.

However, if grid cells are not of the same height, something like what you see below can happen.

A wide gap separates the two rows of content and the layout appears broken.

That’s when Masonry saves the day. Add some Masonry magic to the mix and your grid dynamically adapts to the screen real estate, eliminating all ghastly gaps.

Continue reading this article on SitePoint

Couldn’t you just use MixItUp or Isotope to achieve the same functionality? Both have a Masonry effect and tab like navigation.

Hi Luke,
Thanks for your comment. I could have used different plugins, but that would have been a different topic for a different tutorial perhaps. I’ve used both the plugins you mentioned on occasion and they’re very good. However, they’re not free to use for commercial projects. Also the BS tabs have a bit of a different look and implementation from the MixItUp plugin that some people might like to try in their projects, and Masonry would allow to implement the tiled layout effortlessly and for free.

That is true. Just some additional options for someone looking to get this effect and might not have known of MixItUp or Isotope. Good to know of as many tools and libs as possible to better find the right ones for the right jobs.

1 Like

This is a somewhat mis-titled article. Any tabs plugin, or accordion, or anything that creates hidden content areas will produce the same effect. It would be the same with JQueryUI for example. And any javascript that relies on reading CSS from the DOM to style layout on the fly will encounter the same problem. The problem is that hidden content has no height or width so the proportional calculations can’t be made. In any similar system layout javascript needs calling when the size of the content area changes, which in effect is what happens when you show the tab, it’s size changes from 0:0 to whatever its shown state is.

Hi nigeljohnwade1,
Thank you for making a great point and an absolutely valid one as far as hidden content is concerned.

However, although the problem can be generalized in the way you explain, it doesn’t necessarily follow that examining one particular case and showing the solution to the problem as it’s exemplified in that particular case, is not worth doing.

As for the article being mis-titled, I can’t see how this is: the article does exactly what it says in the title: it takes the particular case of using two plugins, it highlights the problem that might arises by doing that, and applies a solution that relates to those two plugins.

Although the cause of the problem (hidden content), and also the remedy that eliminates the cause (reinitializing the plugin), can to a certain extent
be generalized to other cases, the How, that is the specific way in which it’s done in that situation, is not always clear to someone facing that particular problem.

Thaks Maria, it was a really helpful tutorial; I’m using Masonry in a proyect and was having this problem.

Since Bootstrap has changed a little bit I think you can update the tutorial with the new code availale on the Bootstrap documentation.

I used this code and brought me the same results:

$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
e.preventDefault()
  $container.imagesLoaded( function () {
		$container.masonry({
			itemSelector: '.item',
			columnWidth: 195,
		});
            });
})

Hi Cesar_Viana, thanks for your comment. I’m happy you found the tutorial helpful :slight_smile:

Thank you so much for this great tutorial. It helped me a lot.

Hi Taieb,
Thank you for your feedback, I’m so glad the article was helpful :slight_smile:

1 Like

it seems good article nice info…thanks

Thank you for your comment, Ravi

Thanks for this tutorial - I bought a theme on themeforest that uses this and wasn’t quite sure what it was, why it was being used, and how it could be integrated with Bootstrap, but this completely clarified that for me!

Awesome! Thank you Jgibba for stopping by and leaving your feedback :slight_smile:

HI Maria, it seems that if I click on a tab and then click on another tab before masonry finishes to layout, the layout does not finish and remains stuck in it’s incomplete position. Even with imagesLoaded, this problem happens.

UPDATE: I’m using Masonry 3.3.1 and Bootstrap 3.3.5. Maria’s article currently uses Masonry 3.2.2 and Bootstrap 3.3.1. I found a workaround to the problem for those who need a solution to it. It seems that during the transition/animation of masonry layout, if the user switches tabs before masonry completely finishes, the content is stuck at the incomplete position. The masonry that Maria uses seems to have a transitionDuration of .1 second which is so fast that it’s humanly impossible to encounter this issue. The version that I uses has a default transitionDuration of .4 second which is slow enough for me to switch tabs before masonry finishes its layout. My fix was to simply specify transitionDuration to 0 seconds (no transition) or 0.1 seconds (fast transition like Maria’s). This seems to work, but I suspect this is more of a workaround than an actual solution. This workaround is sufficient for me.

Hi Peter,
I’ve updated Bootstrap and Masonry on a local version of my demo, but the animation is still fast enough to make it difficult to replicate this problem. I should have to slow it down on purpose to see the issue (just as you had to speed it up to see the issue).

Just come back after rebuilding my demo on my CodePen account. I’ve purposefully slowed down the transition on the .item element (both transition-delay and transition-duration have been delayed). It looks to me that the items reposition themselves even if I don’t let the animation complete. Only, it takes a bit longer because of the increased timing, which makes it look like it’s stuck.

Thank you so much for your feedback.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.