A Simple “Max-Width” Container Block with ACF

Dev note as of 8/21/23:
I no longer use this method of controlling content width as the Group Block offers interior content width controls.

One of the hurdles I run into when building bespoke websites is dealing with content that has variable breakpoints. Sometimes headings look better when they have a thinner width. Sometimes content has specific words that should drop to the next line. Sometimes you simply want a form or image to be a specific width.

My solution? The “Max-Width Block”.

What does the Max-Width block do?

Simply put, it creates a container with a maximum width. Using the default text_align functionality you can then align the content within the block as needed.

Using this method allows text to flow naturally and avoids awkward break points that appear when using hard breaks.

Take a look at it in action:

Notice that we are using the native text_align to control the alignment of the interior content. Additionally, the interior content will inherit that text alignment, unless you manually choose a different alignment option on the interior blocks.

So, let’s get down to the code…

What we’ll cover:

Register the ACF Block

First, you need to register the block. I place this in a core functionality plugin, but this could also be added to your functions.php file. You can modify things like the category, icon, etc…as needed.

<?php
acf_register_block_type(array(
     'name'			=> 'acf-max-width-block',
     'title'			=> __( 'Max-Width Block' ),
     'description'		=> __( 'A block to wrap any content in a max-width container with alignment options.' ),
     'category'		=> 'wd-blocks',
     'icon'			=> [
          'background' => '#fff',
          'foreground' => '#b5267b',
          'src'        => 'editor-expand'
     ],
     'mode'              => 'preview',
     'keywords'		=> [ 'max-width', 'wd', 'acf' ],
     'post_type'         => [ 'post', 'page' ],
     'render_callback'	=> 'wd_acf_block_render_callback',
     'enqueue_style'     => get_stylesheet_directory_uri() . '/assets/scss/partials/blocks/css-output/blocks-max-width.css',
     'supports'          => [
          'align'      => false,
          'align_text' => true,
          'jsx'        => true
     ]
));

Notice we are disabling the default alignment settings since this won’t need to go ‘wide’ or ‘full’. Additionally, we’ve enabled the align_text option as well as jsx (which enables the use of innerBlocks.

Depending how you output your CSS you may need to change the path to the styles or disable that altogether.

Create the ACF Fields

Next, we need to create the range field that controls the width. Below is the PHP code you can use to register this block, or you can do it within ACF by creating a new field group and creating a range field.

You should modify the default values, min, max, and step properties as needed.

<?php
if( function_exists('acf_add_local_field_group') ):

acf_add_local_field_group(array(
	'key' => 'group_5fb53ed0a8987',
	'title' => 'Block - Max-Width',
	'fields' => array(
		array(
			'key' => 'field_5fb53edd8eb88',
			'label' => 'Maximum Width',
			'name' => 'wd_maximum_width',
			'type' => 'range',
			'instructions' => 'Set maximum width for this container.',
			'required' => 1,
			'conditional_logic' => 0,
			'wrapper' => array(
				'width' => '',
				'class' => '',
				'id' => '',
			),
			'default_value' => 1200,
			'min' => 150,
			'max' => 1440,
			'step' => 5,
			'prepend' => '',
			'append' => 'px',
		),
	),
	'location' => array(
		array(
			array(
				'param' => 'block',
				'operator' => '==',
				'value' => 'acf/acf-max-width-block',
			),
		),
	),
	'menu_order' => 0,
	'position' => 'normal',
	'style' => 'default',
	'label_placement' => 'top',
	'instruction_placement' => 'label',
	'hide_on_screen' => '',
	'active' => true,
	'description' => '',
));

endif;

Create the Block Template

Now we create the template that controls how the block renders. We pull in the align_text value and apply that with the other block classes. We apply the max-width property to the interior container. We use <InnerBlocks /> for the content of the block.

<?php
/**
 *  Max-Width Block
 *
 * @package      CLIENTNAME
 * @author       Matt Whiteley
 * @since        3.0.0
 * @license      GPL-2.0+
**/

// ACF custom fields
$wd_maximum_width = get_field( 'wd_maximum_width' );

// block ID
$block_id = 'max-width-' . $block['id'];

// block Classes
$block_classes = 'acf-block max-width-block';

if( ! empty( $block['align_text'] ) ) {
     $block_classes .= ' has-text-align-' . $block['align_text'];
}

if( ! empty( $block['className'] ) ) {
     $block_classes .= ' ' . $block['className'];
}

?>

<div id="<?php echo esc_attr( $block_id ); ?>" class="<?php echo esc_attr( $block_classes ); ?>">
     <div class="max-width-block__interior" style="max-width:<?php echo $wd_maximum_width; ?>px;">
          <InnerBlocks />
     </div>
</div>

Setup your CSS

Finally, we have a little CSS to wrap things up.

In my setup I use a SASS partial for each custom block that outputs to a static CSS file. That file is called when registering the block so it only loads when the block is present on the page. Additionally, using this method ensures we have the styles on the front end for end users and the back end for editors.

If you use plain CSS make sure you enqueue the styles in the block editor as well as the front end.

Here is the SASS for this block:

/**
 * /assets/scss/partials/blocks/blocks-max-width.scss
 *
 * Let's define our max-width block styles
 *
 *
 */
.max-width-block {
     display: flex;
     width: 100%;
     flex-wrap: wrap;
     justify-content: flex-start;

     &.has-text-align-center {
          justify-content: center;
     }

     &.has-text-align-right {
          justify-content: flex-end;
     }
}

And that’s all there is to it!

You now have a simple “max-width” block that allows you to dynamically control the width of content on any page or post on your site!

Comments

  1. themiya says:

    Hi Admin this block displaying but I can’t add anything inside to block

  2. Josiah Schaefer says:

    I’ve used a variety of custom blocks like this for the past couple years, but I’ve never thought of doing this. It’s been a timely game-changer on the project I’m currently working on. Thanks for this!

    1. Matt Whiteley says:

      Thanks Josiah! I don’t use this too much anymore as the group block has controls for the interior container width, but it is still a nice approach to handle content widths.

      Cheers!

Leave a Reply

Your email address will not be published. Required fields are marked *