The image carousel has become ubiquitous throughout the world of web design. Instinctively its appeal makes sense, an engaging header image, combined with a well thought out call to action is still good practice in many cases. The logic follows that if we can put more header images, and more CTAs in a changing carousel surely that’s even better. Well the evidence all seems to suggest that in a lot of cases it isn’t.
This article does a great job of detailing why that might be the case, but essentially it comes down to people massively favouring the first slide content and all but ignoring any subsequent slides, particularly on carousels that don’t autoscroll. That’s not to say there aren’t times when it serves a purpose, but it does suggest that we, as web designers, should give more consideration to what might actually be of use to site users.
As far as theming within NationBuilder is concerned it got me thinking about how we could change the state of the featured content slider to reflect this thinking.
Given that the main header image, with a clear call to action (CTA) is still good practice, then perhaps there is no need to throw out the first slide all together. I can still appear full width, but rather than being part of a carousel, it is now just a banner. We could then perhaps treat all subsequent slides as secondary CTAs displayed in a grid format. That way we’re not hiding any content off screen but we are building in a hierarchy which is ultimately a good thing for not overwhelming the user.
Coding the grid
Using flexbox the code for a grid like this on a mid to large screen might look something like this…
html:
<div class="page-width"> <div class="featured-content-wrapper"> <div class="featured-content-slide-wrapper"> <div class="featured-content-slide"></div> </div> <div class="featured-content-slide-wrapper"> <div class="featured-content-slide"></div> </div> <div class="featured-content-slide-wrapper"> <div class="featured-content-slide"></div> </div> <div class="featured-content-slide-wrapper"> <div class="featured-content-slide"></div> </div> </div> </div>
css:
.page-width { width: 100%; max-width: 960px; margin: 0 auto; } .featured-content-wrapper { display: flex; flex-wrap: wrap; justify-content: space-between; } .featured-content-slide-wrapper { flex-basis: calc(100% / 3 - 30px); margin-bottom: 40px; } .featured-content-slide-wrapper:first-child { flex-basis: 100%; } .featured-content-slide { border:3px solid #000; padding-bottom: 50%; }
Here we’ve:
- Set a width for our featured grid and center it in the browser with margins (.page-width)
- Set up our flexbox wrapper to control our grid display (.featured-content-wrapper). We’re adding ‘flex-wrap: wrap;’ so that our grid items flow onto more than one line if required and ‘justify-content: space-between;’ so that our grid items space evenly over the full width of the row.
- Added 4 ‘slides’ to our layout, signified here by the class ‘.featured-content-slide-wrapper’. We then set our slides display rules. We’re setting the width of each item to be one third of the width of the outer wrapper minus 30px to give us a gap between items (flex-basis: calc(100% / 3 – 30px);). We then adding a margin to the bottom so when stacked there is a gap vertically.
- Specified that the first grid-item (i.e. our first featured image slide) should have 100% width (flex-basis: 100%;) by using the ‘:first-child’ selector. This will be our banner slide so we want it to sit on top of our three other slides all set to third widths.
- Added a ‘featured-content-slide’ div inside our slide width definer. This is where we’d add the content of our featured slide, but for now, just so I can see it, I’ve given it a percentage height using bottom padding and a thick black border.
The grid looks like something like this…
Getting the number of featured content slides
The above example would work really well if there are four slides added to the featured content slider, one for the banner and three to sit neatly in a grid underneath it. The trouble is, we don’t know how many slides a user will add. What if they only add two? What if they add seven? We can make suggestions for best practice, but we really want a system that always looks good no matter what choices are made. This is where we need to be a bit clever in our theming.
The first step is to establish how many featured content slides we’re dealing with. We can do that by getting the size of the ‘page.features’ variable. We’ll then assign that value to a variable as follows…
{% assign featuresCount = page.features | size %}
We now have a variable, ‘featuresCount’ which contains our number of slides.
Based on that number we need a plan for how we’re going to display the output of our slides.
We know that the first slide is always going to be full width so, to a certain degree, we can discount that and focus on any subsequent slides.
To account for that lets deduct 1 from our featuresCount variable:
{% assign featuresCount = featuresCount | minus: 1 %}
We now have a number that reflects the remaining slides i.e. minus the first full width one.
Displaying the grid in different scenarios
We’ll go back to a two slide scenario in a minute because it’s a bit of an anomaly. Anything above two falls into one of 4 categories:
- Divisible by three (e.g. our featuresCount = 3, 6, 9 etc)
- Divisible by four (e.g. our featuresCount = 4, 8, 12 etc)
- The number divided by three gives a remainder of 1 (e.g. our featuresCount = 7, 10, 13, 22 etc)
- The number divided by three gives a remainder of 2 (e.g. our featuresCount = 2, 5, 11, 14 etc)
Now obviously, we’re not expecting 22 different slides to be added, but I wanted a grid that adapted to any eventuality.
Now we need to check which of our four categories our ‘featuresCount’ number fits into (which remember, is the number of slides that will constitute our grid i.e. MINUS the first one). We can then assign a category dependent class…
{% if featuresCount / 3 == 0 %} {% assign gridClass = ‘divisible-by-three’ %} {% elsif featuresCount / 4 == 0 %} {% assign gridClass = ‘divisible-by-four’ %} {% elsif featuresCount | modulo: 3 == 1 %} {% assign gridClass = remainder-one %} {% elsif featuresCount | modulo: 3 == 2 %} {% assign gridClass = remainder-two %} {% endif %} <div class="page-width"> <div class="featured-content-wrapper {{ gridClass }}"> <div class="featured-content-slide-wrapper"> <div class="featured-content-slide"></div> </div>
etc...
Note: The modulo filter in liquid gets the remainder of whatever our variable divided by the following number is.
Here we have created a new variable called ‘gridClass’ which we’re assigning a different value to depending on which of our four categories ‘featuresCount’ falls into. We can then use this class to style how our grid will appear.
‘divisible-by-three’ is our default grid which we’ve already styled for so we don’t need to have any extra css here.
For ‘divisible-by-four’ we want to change our grid from being 3up to 4up so we’ll add the following css…
.divisible-by-four .featured-content-slide-wrapper { flex-basis: calc(25% - 30px); }
For ‘remainder-one’ we’re going to use our default 3up grid but make the first 4 slides span 50% of the space. To do this we’ll use the :nth-child() css pseudo class to target the 2nd, 3rd, 4th and 5th slides (remember the 1st slide is 100% width)…
.modulo-one .featured-content-slide-wrapper:nth-child(2), .modulo-one .featured-content-slide-wrapper:nth-child(3), .modulo-one .featured-content-slide-wrapper:nth-child(4), .modulo-one .featured-content-slide-wrapper:nth-child(5) { flex-basis: calc(50% - 30px); }
Finally, for ‘remainder-two’ we’re going to use our default 3up grid but make the first two slides span 50% of the space.
.modulo-two .featured-content-slide-wrapper:nth-child(2), .modulo-two .featured-content-slide-wrapper:nth-child(3) { flex-basis: calc(50% - 30px); }
So now we have a grid that works regardless of the number of slides APART from if there are only two slides. Our best option here might be to make both the first and second slides 50% width. So we lose our 100% width first slide, but at least don’t have a left over slide. To do this let’s add a final entry to out if/else statement…
{% if featuresCount / 3 == 0 %} {% assign gridClass = ‘divisible-by-three’ %} {% elsif featuresCount / 4 == 0 %} {% assign gridClass = ‘divisible-by-four’ %} {% elsif featuresCount | modulo: 3 == 1 %} {% assign gridClass = remainder-one %} {% elsif featuresCount | modulo: 3 == 2 %} {% assign gridClass = remainder-two %} {% elsif featuresCount == 1 %} {% assign gridClass = two-up %} {% endif %}
…and use that ‘two-up’ class to style our first two slides…
.two-up .featured-content-slide-wrapper { flex-basis: calc(50% - 30px); }
We now have a grid that will display well no matter how many slides are added. We need to do some work on making this grid responsive but apart from that, all that’s left now is to decide how you display slide content within this grid.
Leave a Reply