Adding Styles Properly to WordPress

Posted by Ronald Huereca / November 24, 2019 /

The following is an excerpt from the upcoming WordPress and Ajax 3rd Edition book. Please visit wpandajax.com to subscribe to updates for the new book.
Ronald Huereca
Ronald Huereca

Let’s give WordPress some style with some awesome CSS (Cascading Style Sheets, but you probably knew that already).

Just as wp_enqueue_script can prevent duplicate scripts from loading, wp_enqueue_style can do the same.  But the biggest advantage of using wp_enqueue_style over other techniques is the use of dependencies.

Unfortunately, the use of wp_enqueue_style isn’t as widely adopted as wp_enqueue_script, but in my non-humble opinion, it’s just as important to use.

The biggest reasons to use wp_enqueue_style?

  1. Allows for dependencies and media targeting (screen, print, etc.)
  2. Allows for others to overwrite your styles (an uber-awesome reason if you ask me)

So what are the arguments, and what hooks should we use?

How Does wp_enqueue_style Work?

The wp_enqueue_style function takes in five arguments, with the last four being optional.

<?php wp_enqueue_style( 'handle', 'src', 'deps', 'ver', 'media' ); ?>

Handle, Src, Deps, and Ver

Since I already covered loading scripts properly,  and wp_enqueue_script and wp_enqueue_style are so similar, I’m going to breeze over the first four arguments (they act the same, really).

So rather than being repetitive, let’s get to the new argument, which is media.

media

The media argument is asking for the type of media the stylesheet is defined for. A quick example is below:

wp_enqueue_style( 'my_css', plugins_url( 'my_plugin/my_css.css' ), array( 'another_css_file' ), '1.0.0', 'screen' );

In this particular example, we’re just setting the media type to screen, which is for most browsers.

Some other common media types you may use are:

  • all
  • print
  • screen
  • handheld.

The wp_enqueue_style Hooks

We’ll be using the same hooks as wp_enqueue_script: wp_enqueue_scripts for the front-end, and admin_enqueue_scripts for the backend. Why enqueue styles from a scripts hook? No idea why. It’s just the best place to do it and there are no wp_enqueue_styles or admin_enqeueue_styles hooks.

In order to use wp_enqueue_style properly, you need to call it using the appropriate hooks (wp_enqueue_scripts in this example.)

The admin_enqueue_scripts hook allows you to add styles in the admin area, while the wp_enqueue_scripts hook allows you to add styles on both the front-end and admin area.

To add your styles, use the add_action function and call the appropriate hook and provide a callback function.

<?php 
add_action( 'wp_enqueue_scripts', 'my_styles_callback' );
function my_styles_callback() {
	wp_enqueue_style( 'my_css', plugins_url('my_plugin/my_css.css' ), array( 'another_css_file' ), '1.0.0', 'screen' );
}
?>

The above code will place a stylesheet on each front-end area provided that the “another_css_file” dependency has been previously registered (using wp_register_style).  If you want to place the stylesheet in the admin area only, you should use admin_enqueue_scripts instead (more on that later).

Let’s Add Styles to Our Example

Let’s begin by creating a new file that will output a shortcode. We’ll then load our stylesheet and apply some styles. And even I told you we’ll be taking a break from JavaScript, let’s output some form data to the console.

Here’s our new file structure:

Chapter 6 File Structure

We’ll be creating a new CSS file called form-shortcode.css. We’ll also add in a new file to our frontend folder called class-shortcode.php.

Here’s what’s in class-shortcode.php:

<?php
/**
 * Create and output a shortcode.
 *
 * @package   Sample_WPAjax_Plugin
 */

namespace Sample_WPAjax_Plugin\Frontend;

/**
 * Load Frontend Shortcode
 */
class Shortcode {

	/**
	 * Register hooks needed for this class.
	 */
	public function register_hooks() {
	}
}

We aren’t doing anything quite yet. And let’s initialize this shortcode class from class-plugin.php.

// Load frontend assets.
$this->frontend = new Frontend\Frontend();
$this->frontend->register_hooks();

// Load shortcode assets.
$this->frontend_shortcode = new Frontend\Shortcode();
$this->frontend_shortcode->register_hooks();

Now we’re ready to output a shortcode and make it pretty. Let’s just output a simple form and style the output. Let’s go back to class-shortcode.php and set that up.

We’ll be using an add_shortcode initializer, which will call a callback function, where we can output the form data.

<?php
/**
 * Create and output a shortcode.
 *
 * @package   Sample_WPAjax_Plugin
 */

namespace Sample_WPAjax_Plugin\Frontend;

/**
 * Load Frontend Shortcode
 */
class Shortcode {

	/**
	 * Register hooks needed for this class.
	 */
	public function register_hooks() {
		add_shortcode( 'swpajax_form', array( $this, 'output_shortcode' ) );
	}


	/**
	 * Output a simple form shortcode.
	 *
	 * @param array  $atts Passed shortcode parameters.
	 * @param string $content Passed content item.
	 *
	 * @return string Shortcode html.
	 */
	public function output_shortcode( $atts = array(), $content = '' ) {
		$defaults = shortcode_atts(
			array(),
			$atts,
			'swpajax_form'
		);
		ob_start();
		?>
		<form action="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>" id="swpajax-form">
			<label for="swpajax-name">
				<?php esc_html_e( 'Enter your name', 'sample-wpajax-plugin' ); ?>:
			</label>
			<br />
			<input id="swpajax-name" name="swpajax-name" value="" placeholder="<?php echo esc_attr( __( 'Enter your name', 'sample-wpajax-plugin' ) ); ?>" />
			<br />
			<button id="swpajax-submit">
				<?php esc_html_e( 'Submit', 'sample-wpajax-plugin' ); ?>
			</button>
		</form>
		<?php
		return ob_get_clean();
	}
}

In the above example we’re adding a shortcode named swpajax_form. We then call a callback method named output_shortcode. We use several built-in and PHP WordPress functions:

  1. ob_start – Start an output buffer. In this case we’ll start an output buffer so we can write HTML to the screen.
  2. ob_get_clean – Return the output buffer (in this case HTML) as a string.
  3. esc_url – Escape any URL right before usage or retrieval.
  4. __ – Used for internationalization.
  5. esc_html_e – Used for internationalization and echoing escaped strings straight to the screen.
  6. esc_attr – Used for escaping anything that will go in an HTML attribute.

If all goes well, we should be able to output our shortcode to the screen as seen in these screenshots.

Gutenberg Shortcode Input
Gutenberg Form Output

So what I have done is created a post, added a shortcode block, added in the shortcode, and have previewed the work on the front-end. Now let’s work on getting a script loaded for the shortcode

Loading Scripts for Your Shortcode

Let’s conditionally load our JavaScript file so that it only shows up for our shortcode. Let’s gut class-frontend.php and add the script loading to our shortcode function only. I’ll go over how to conditionally load your scripts and files in a later chapter, but this technique shows how to do it for a shortcode.

Our class-frontend.php is now gutted and doesn’t do anything. Here’s what it looks like:

<?php
/**
 * Primary plugin file.
 *
 * @package   Sample_WPAjax_Plugin
 */

namespace Sample_WPAjax_Plugin\Frontend;

/**
 * Load Frontend Scripts/Styles
 */
class Frontend {

	/**
	 * Register hooks needed for this class.
	 */
	public function register_hooks() {
		add_action( 'wp_enqueue_scripts', array( $this, 'load_scripts' ) );
	}

	/**
	 * Load our Front-end scripts.
	 */
	public function load_scripts() {
		// Load any other scripts/styles here.
	}
}

Next, we’ll add the script loading to the top of the shortcode output:

/**
 * Output a simple form shortcode.
 *
 * @param array  $atts Passed shortcode parameters.
 * @param string $content Passed content item.
 *
 * @return string Shortcode html.
 */
public function output_shortcode( $atts = array(), $content = '' ) {

	// Conditionally load script for shortcode only.
	wp_enqueue_script(
		'sample_wpajax_plugin',
		SAMPLE_WPAJAX_URL . '/js/init.js',
		array( 'jquery' ),
		SAMPLE_WPAJAX_VERSION,
		true
	);
	wp_localize_script(
		'sample_wpajax_plugin',
		'swpajaxp',
		array(
			'phpversion' => PHP_VERSION,
			'ajaxurl'    => admin_url( 'admin-ajax.php' ),
		)
	);

        // .. code ...
}

Let’s leave wp_enqueue_script alone. The only argument we need to make sure of is that the script loads in the footer of the site, which it is already set up for.

Let’s modify the jQuery code so that it captures the form input button and outputs the name entered to the console. Since we gave the form HTML element an ID of swpajax-form, we can use the submit event in jQuery to capture the input.

Here’s what our JavaScript looks like. It just simply captures a submit handler and outputs the name entered to the console. We’re just not doing anything fancy with the data just yet (gotta walk before you crawl).

jQuery(function($) {
	$('#swpajax-form').on('submit', function(e) {
		e.preventDefault();

		var inputName = $(this).find('#swpajax-name').val();
		console.log('Name submitted');
		console.log(inputName);
	});
});

If I load this up and view the shortcode, I’ll get the following in my developer console should I choose to submit the form.

Console Output

By loading this file only when the shortcut is output, we’re making sure the script is only loaded when needed. Let’s do the same for styles.

Loading Styles Into Your Shortcode

We’re going to do something that is not a best practice, but it’s really the lesser of all evils when it comes to loading styles in with your shortcode. We’re going to simply register the style and print it out if it hasn’t already been done so. We’ll cover more on conditionally loading your scripts and styles in the next chapter.

We’ll place the following code into the shortcode output:

// Conditionially load style for shortcode only.
if ( ! wp_style_is( 'sample_wpajax_plugin_styles', 'done' ) ) {
	wp_register_style(
		'sample_wpajax_plugin_styles',
		SAMPLE_WPAJAX_URL . '/css/form-shortcode.css',
		array(),
		SAMPLE_WPAJAX_VERSION,
		'all'
	);
	wp_print_styles(
		array(
			'sample_wpajax_plugin_styles',
		)
	);
}

It’s not pretty, but the above will run only once in case we happen to have two shortcodes on one page. Let’s not do that for this example, however. We’ve designed our shortcode to really only be embedded once.

Let’s add some CSS to our form-shortcode.css to make it prettier (let’s make the input box look better and our submit button prettier):

/* Form Label */
#swpajax-form label {
	font-size: 20px;
	font-weight: 700;
	display: block;
}
#swpajax-form input {
	min-height: 48px;
	display: flex;
	align-items: center;
	min-width: 260px;
	font-size: 18px;
}
#swpajax-form button {
	margin: 10px 0;
	min-width: 260px;
}
#swpajax-form br {
	display: none;
}

I’m no CSS expert, nor do I pretend to be, but the above CSS made my form just a little bit prettier:

Styled Form Input

Conclusion

In this chapter, I showed you how to use wp_enqueue_style. We created a shortcode and outputted our script and style conditionally as needed. The next chapter will cover more techniques for conditionally loading our styles and scripts just where they are needed.

As always, you can download my completed code for Chapter 6 at https://github.com/wpajax and going to Chapter 6.

Ronald Huereca
Developer at MediaRon
Ronald Huereca is the CEO of MediaRon LLC and enjoys WordPress plugin and theme development.

Connect with the Author

Posted in

Leave a Comment

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

Scroll to Top