MAT MARTIN | Code – Alternating Layout with ACF Repeater Fields and CSS

7 June, 2017, 12:10 | Blog · Creating Content · Resources

Alternating Layout with ACF Repeater Fields
Alternating Layout with ACF Repeater Fields

When working to offer a CMS-based list style page template with an undefined number of entries it’s not unusual to need to create a layout which goes beyond simple repetition of a set of sub fields. Luckily there is a CSS-only solution which makes use of the nth-of-type() selector. This allows us to create an alternating layout without using JS to target specific rows by number and without knowing how many rows will be created by the site’s editor(s). Here we will break down the elements of such a layout.

Creating an Alternating Layout with ACF Repeater Fields

I recently needed to create a dynamic page template in a WordPress theme using the ACF Repeater Field function but in which I also wanted to alternate the layout from row to row, creating a design that felt less repetitive. As usual, I searched first for a CSS-based solution, and found that with a little creative use of nth-of-type(odd) and nth-of-type(even) I was able to do this without adding any JS at all.

Here are the conditions I needed to meet:

  1. Content was to be generated in WordPress CMS, via the ACF Repeater Field function.
  2. Each entry to contain a title, an image and some copy.
  3. Alternating entries to have different colour backgrounds.
  4. Alternating entries to swap the layout of title and copy / image from left to right.
  5. Page template to handle varying numbers of rows as above.

Creating the HTML

So as usual we start by calling the repeater field (sections) itself. Here it has three sub fields: title, image and copy. In the HTML we define a wrapping .content-area for everything, a .container to set the display width, and a .half div which we will float right and left, to create two columns of equal width. The .content-area div is given an id of #section (meaning we can use CSS target these specific divs without affecting other divs with same class elsewhere in the site), and the .half divs are given separate ids of #halfimg and #halftext, which we will use to swap their positions over, below.


<?php if( have_rows('sections') ): ?>
<?php while ( have_rows('sections') ) : the_row(); ?>
<div id="section" class="content-area">
	<div class="container">
		<div id="halfimg" class="half">
			<img src="<?php the_sub_field('image'); ?>">
		</div>
		<div id="halftext" class="half">
			<h2><?php the_sub_field('title'); ?></h2>
			<?php the_sub_field('copy'); ?>
		</div>
	</div>
</div>
<?php endwhile; ?>        
<?php else : endif; ?>

Applying the CSS

Alternating the background colour using the .content-area class is simple enough using nth-of-type():


.content-area {
	width: 100%;
	padding: 80px 0;
	min-height: 40px;
	overflow: hidden;
	background-color: #FAFAFA;
}
.content-area:nth-of-type(odd) {
	background-color: #EDEDED;
}
.container {
	width: 84%;
	margin: 0 auto;
	min-height: 40px;
	overflow: hidden;
}

Now we set up the initial conditions for the .half class, including its behaviour on odd-numbered iterations (1, 3, 5 etc.) using nth-of-type() to float them left and right respectively:


.half {
	width: 46%;
	min-height: 40px;
	overflow: hidden;
}
.half:nth-of-type(odd) {
	float: left;
}
.half:nth-of-type(even) {
	float: right;
}

Finally, we use nth-of-type() on the ids #section, #halfimg and #halftext, and add in the !important clause to override the initial conditions where appropriate* and switch out the floating:


#section:nth-of-type(odd) #halfimg {
	float: right !important;
}
#section:nth-of-type(odd) #halftext {
	float: left !important;
}

*Generally speaking (with a few exceptions) !important is bad practice. This code will work fine without it provided the CSS for the #section, #halfimg and #halftext ids follows that for the .half class. They’re cascading style sheets, after all.

Using An Alternating Layout with ACF Repeater Fields

We’re all done. A few lines of CSS and no JS, and we have a clean, simple layout which is much more sophisticated than a basic repeater. Of course, this is just the kernel of an approach to dealing with laying out dynamic content in repeater fields, and still ties us to a basic A/B layout. It could be elaborated using nth-child() formulas to target every third, fourth, fifth row, etc.

Despite my preference to do as much as I can in CSS, there is always JS to fall back on, too. When CSS gets too complicated or can’t handle the variables, there must be several JS options which would give us more complex and tuneable approaches to automatically vary the layout of specific rows in repeater fields.

tagged: · · · · · · · · · ·