August 31, 2020
The Contact Form 7 plugin does not inherently support the time attribute for an input field. As of version 5.2, you can use the native HTML5 date input field (and all of the UX that browsers provide that come along with it) but you cannot set up a time field with the same features. I prefer using the HTML5 date and time fields for these input configurations rather than a Javascript library. Though not fully supported, it still does have a considerable amount of browser compatibility and I believe that is the way things are headed. It’s very likely that the plugin will begin to support and include this field type in the future, but for now, let’s look at how to include this in our form.
This post assumes you have some knowledge about Contact Form 7, some coding skills, and knowledge of your WordPress theme.
Step 1: Add A Field to your Form
We are going to include the field we would like to make a time input field type in our form. You would perform this the same way you normally do for a text field, but in this case, you would like to give it an ID. In this case, it will be
time-field . I also gave the field a name of
my-time-field which I will reference later.

Step 2: Change The Property Type With Javascript
Now that we have our field, we are going to use jQuery to change the property type of the input field based on its ID. This is the same ID you provided in the prior step.
Take the code below and place it wherever you place your theme’s custom Javascript. This could be in your theme settings or in a file in your theme that is called.
|
$('#time-event').prop('type', 'time'); |
You would like this to occur on
$(document).ready() to once the form is called, you will immediately switch the input field from
text to
time and now the browser will respond accordingly.
This would be good enough for some, however, when Contact Form 7 sends the form submission via email, it will have that field value as a long string. Something like “YYYYDDHH” and that may not necessarily be legible for your client/user to receive.
That leads us to our next step.
Step 3: Modify the Time Value Before Sending
Here we would like to change the returned value of our new time input field to something legible that a user can understand and interpret. Since it is returning as a big long string, we can use a little PHP and tap into Contact Form 7’s hooks to modify the value before it is sent in an email.
Place the following snippet in the functions.php file of your theme:
|
add_filter( 'wpcf7_posted_data', 'change_update_time_form', 10, 1 ); function change_update_time_form($array){ if($array['my-time-field']) { $time = $array['event-time']; $updatedTIME = date('h:i a',strtotime($time)); $array['event-time'] = $updatedTIME; } return $array; } |
Let’s discuss what is happening here. The
wpcf7_posted_data filter will allow you to tap into the returned values of your form before it is sent. In our case, we are looking for a field in the array with the name
my-time-field . Once we have that value, let’s use the PHP functions
strtotime() to parse the value as a time value and then use the
date() function to manipulate it into a format we’d like. In my case, it will return as the 12-hour with AM/PM meridiem format.
In the email, the recipient will see the time as something like “8:23 AM”.
Conclusion
I hope this helps get you on the right track towards including a time field type in your forms going forward. Though I find it very likely there will be more support in the plugin going forward, I believe this method is sufficient in getting that accomplished. Please leave any questions or concerns in the the comments below.
Happy Coding!
May 27, 2020
This post is to show you how to display content for first time visitors only through Hubspot with the help of cookies. I recently became Hubspot Certified for their Developer CMS and had a request for showing certain content for new visitors on a page.
Hubspot already uses several cookies to track visitors on a site, and through those, I could easily determine whether or not a visitor was there for the first time or not.
Now, I have to say, this doesn’t necessarily mean they haven’t been there before — but it does mean they had either visited in a private browser without tracking, hadn’t visited in a very long time, or declined cookies on the site. Otherwise, they are a first time visitor.
Requirements
In order to utilize the cookies provided by Hubspot, a few things have to be done first:
- Set up your cookie tracking and privacy policy through the CMS. You need to ensure that you’re using cookies through the settings and that the domain is set up correctly. It is recommended you also choose to notify your users that you use cookies.
- Install Hubspot tracking. I actually don’t know if this imperative to the exercise we are doing today, but it’s probably a helpful tool to have anyway. This can give you more insight and detail about your visitors.
- Set up a custom module in the Design Manager. This is where you will be placing your code to determine first time visitors.
- Add the newly created custom module to a page or template you are using.
How to Get Cookies in HubL
Here is a list of the cookies Hubspot sets for a visitor. Since Hubspot does the heavy lifting for us by setting and keeping track of cookies, we need to figure out how to use those in our module to show or hide content based on those cookies.
Thanks to HubL’s HTTP Request Variables, you can call those cookies at any point in your custom module and use them however desired. The one we are working with specifically today is
{{ __hstc }} . This is the main cookie for tracking visitors and contains the domain, initial timestamp (first visit), last timestamp (last visit), current timestamp (this visit), and session number (increments for each subsequent session). Those are all very valuable things to know when determining what content to show to your visitor.
If this is a first time visitor, that cookie is not set.
Hide or Show Content For New Visitors
Now that we have a good idea as to how we determine a first time visitor… let’s get those cookies and set up a condition in our module to hide or show content based on that. Below is a very simple code snippet accomplish that:
|
{% set cookies = request.cookies %} {% if cookies.__hstc %} Our visitor has returned! {% else %} Our visitor is new! {% endif %} |
This is about as simple as it gets, but it provides all the control and power you would need to determine your first time visitor. At it’s core — if the cookie is set, then that has to mean the visitor has come before and accepted cookies.
Redirect First Time Visitors
Below is an example of how you would redirect a first time visitor using an unless condition in HubL:
|
{% set cookies = request.cookies %} {% unless cookies.__hstc %} <script>window.location.replace("http://rcneil.com");</script> {% endunless %} |
You would place this before any content you would like to show to returning users. For example, place this module on your home page if you would like to redirect them somewhere else if they are a first time visitor. Unless that cookie has been set, it will execute that Javascript and send the visitor elsewhere.
Loop Through All Cookies
Here is a simple HubL snippet to loop through all of the cookies set in Hubspot in your module:
|
{% set cookies = request.cookies %} {% for key, val in cookies.items() %} {{ loop.index }} - {{ key }}: {{ val }}<br /> {% endfor %} |
This detailed list will show you all of the Hubspot cookies set and their values. You can get much more defined about what you would like to show visitors based on the cookies’ values. From this list, you could decide to show a returning visitor something else as opposed to a new visitor. You could also decide to show a returning visitor who hasn’t been back in a while a specific message. The possibilities are endless!
Smart Content
It’s important to note that Hubspot gives you the ability to modify content based on certain factors — making it “Smart Content”. Those factors include what type of device they are using (desktop, tablet, phone), what referral source they are coming from (Google, Facebook, etc), what language they prefer, and a myriad of other factors. Unfortunately, this does not include first time visitors. Hopefully, this is something the Hubspot team is working on to include in the future so custom modules aren’t require for this type of thing.
Hope this helps! Happy Coding!
April 8, 2020
If you’ve done any custom WordPress development in the past 10 years, you’ve probably stumbled upon or worked on the Enfold theme which uses the Advanced Layout Builder. This is a proprietary page editor used by the popular theme developed by the theme’s creators. The theme alone has 200k sales, so it’s fairly common. It comes with a lot of built in modules and elements, but there may come a point where you’d like to extend this editor to allow for custom elements.
Below is an example code snippet that builds this custom element. I’m going to describe how to use it in more detail below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
|
<?php /** * EXAMPLE CUSTOM ADVANCED LAYOUT BUILDER ELEMENT * * */ if ( ! defined( 'ABSPATH' ) ) { exit; } if ( ! class_exists( 'avia_your_new_custom_element' ) ) { class avia_your_new_custom_element extends aviaShortcodeTemplate { /** * Create the config array for the shortcode button */ function shortcode_insert_button() { $this->config['version'] = '1.0'; $this->config['self_closing'] = 'yes'; $this->config['name'] = __( 'Title of Your Custom Element', 'avia_framework' ); $this->config['tab'] = __( 'Custom Elements Tab', 'avia_framework' ); $this->config['icon'] = AviaBuilder::$path['imagesURL'] . 'sc-accordion-slider.png'; $this->config['order'] = 100; $this->config['target'] = 'avia-target-insert'; $this->config['shortcode'] = 'av_your_new_custom_shortcode'; $this->config['tinyMCE'] = array('disable' => true); $this->config['tooltip'] = __( 'Tooltip for your new custom element!', 'avia_framework' ); $this->config['preview'] = 'large'; $this->config['id_name'] = 'id'; $this->config['id_show'] = 'yes'; } /** * Custom Fields * * Here are the fields you can use for the element that a content editor can fill out * * @return void */ function popup_elements() { $this->elements = array( array( 'type' => 'tab_container', 'nodescription' => true ), array( 'type' => 'tab', 'name' => __( 'Content', 'avia_framework' ), 'nodescription' => true ), array( 'name' => __( 'Field 1', 'avia_framework' ), 'desc' => __( 'Put your field value here', 'avia_framework' ), 'id' => 'field_1', 'fetch' => 'id', 'container_class' => 'avia-element-fullwidth', 'type' => 'input', 'std' => '' ), array( 'type' => 'tab_close', 'nodescription' => true ), array( 'type' => 'tab_container_close', 'nodescription' => true ), ); } /** * Editor Element - this function defines the visual appearance of an element on the AviaBuilder Canvas * Most common usage is to define some markup in the $params['innerHtml'] which is then inserted into the drag and drop container * Less often used: $params['data'] to add data attributes, $params['class'] to modify the className * * * @param array $params this array holds the default values for $content and $args. * @return $params the return array usually holds an innerHtml key that holds item specific markup. */ function editor_element( $params ) { $params['class'] = ''; $params['innerHtml'] = "<div class='avia_textblock avia_textblock_style' data-update_with='content' style='padding:12px 0;text-align:center'><h1>CUSTOM ELEMENT</h1></div>"; return $params; } /** * Frontend Shortcode Handler * * @param array $atts array of attributes * @param string $content text within enclosing form of shortcode element * @param string $shortcodename the shortcode found, when == callback name * @return string $output returns the modified html string */ function shortcode_handler( $atts, $content = '', $shortcodename = '', $meta = '' ) { $output = ''; $output .= '<div class="your-custom-element">'; $output .= '<h2>' . $atts['field_1'] . '</h2>'; $output .= '</div>'; return $output; } } } ?> |
There are 4 parts to this code snippet and they all play an important role in how your element appears and functions.
- Declaring the element and defining its name, description, icon, etc
- Determining what fields the user can edit while using this element
- Determining what the element looks like inside the editor when used
- Determining what is output on the front-end with your element
We are going to describe how and where to set this up in greater detail.
Setting up your files and calling them
The first step in extending this custom builder is determining where these files are going to live. In my case, I set them up in my WordPress theme and then referenced them in my
functions.php file. That is what I would recommend.
So, in your theme, set up a directory called “custom-elements”. You are probably going to make multiple custom elements and they all need a separate file. You would place them inside this directory. Here is the code snippet you would place in your
functions.php file to call that directory so Advanced Layout Builder knows where to find them:
|
add_filter('avia_load_shortcodes', 'avia_include_shortcode_template', 15, 1); function avia_include_shortcode_template($paths) { $template_url = get_stylesheet_directory(); array_unshift($paths, $template_url.'/custom-elements/'); return $paths; } |
That declares that going forward, check out “/custom-elements/” to see if there are files.
Next, let’s set up a demo custom element file within that directory. Any custom element files in that directory going forward will be recognized and included when the Advanced Layout Builder loads on the back-end.
Make a file in that directory called “custom-element.php”. Copy the entire code snippet that builds the custom element in there and save. You should now see a custom element when you refresh the page editor in the back end on it’s own tab.
Let’s break down those parts to see how you can re-purpose those for your needs.
Extending the Avia Shortcodes Class
This part of the code defines your custom element’s name and function:
|
if ( ! class_exists( 'avia_your_new_custom_element' ) ) { class avia_your_new_custom_element extends aviaShortcodeTemplate { |
You are going to need to make
avia_your_new_custom_element a unique function name for each of the custom elements you make. Make sure you update it on both lines.
Customize the element declaration
Let’s look at this piece of the code:
|
function shortcode_insert_button() { $this->config['version'] = '1.0'; $this->config['self_closing'] = 'yes'; $this->config['name'] = __( 'Title of Your Custom Element', 'avia_framework' ); $this->config['tab'] = __( 'Custom Elements Tab', 'avia_framework' ); $this->config['icon'] = AviaBuilder::$path['imagesURL'] . 'sc-accordion-slider.png'; $this->config['order'] = 100; $this->config['target'] = 'avia-target-insert'; $this->config['shortcode'] = 'av_your_new_custom_shortcode'; $this->config['tinyMCE'] = array('disable' => true); $this->config['tooltip'] = __( 'Tooltip for your new custom element!', 'avia_framework' ); $this->config['preview'] = 'large'; $this->config['id_name'] = 'id'; $this->config['id_show'] = 'yes'; } |
This section is defining a lot of important details about your new custom element. Most are self explanatory, but the key things are the name, icon, shortcode, and tooltip. These all need to be unique and help identify what they are and do to to your content editor.
I got the icon by literally “Right Click > Inspect Element > Image Name” of the icon I wanted to steal from another Advanced Layout Builder Module. They almost always start with “sc-” and you can find the best one that fits your element.
Another important piece is the “tab” section. If you notice in the editor, you can separate the custom modules by “Layouts Elements, Content Elements, etc”. Do you want this element to be in one of those? If so, label it the same. If you want it to be on a separate tab, give that definition a different name. Other custom elements you make can also reference that exact tab name to group them together. Feel free to experiment!
Customize the Editable Fields
We move on to the next chunk of code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
function popup_elements() { $this->elements = array( array( 'type' => 'tab_container', 'nodescription' => true ), array( 'type' => 'tab', 'name' => __( 'Content', 'avia_framework' ), 'nodescription' => true ), array( 'name' => __( 'Field 1', 'avia_framework' ), 'desc' => __( 'Put your field value here', 'avia_framework' ), 'id' => 'field_1', 'fetch' => 'id', 'container_class' => 'avia-element-fullwidth', 'type' => 'input', 'std' => '' ), array( 'type' => 'tab_close', 'nodescription' => true ), array( 'type' => 'tab_container_close', 'nodescription' => true ), ); } |
In this example, I’ve only made 1 field, called “Field 1”, where a user can add some custom content in the element. The “type = input” describes if this is a text field, a text area, a radio button, image, etc. There isn’t a ton of documentation on your options, but the best way to explore more is to dig into the Advanced Layout Builder. If you look at the code for other default elements, they will have a similar set up with waaaaaaay more fields and you can cut/paste parts of those to set up your editor how you wish.
One important note, the ID for each should be unique. You can also group them in tabs which is what the 2nd array in this code snippet does. You can start new tabs and place other editable fields on those. It’s just a nice way to group things and as your custom modules become more complex, you can make editing content easier.
Define what your element looks like in the editor
This piece of code does exactly that:
|
function editor_element( $params ) { $params['class'] = ''; $params['innerHtml'] = "<div class='avia_textblock avia_textblock_style' data-update_with='content' style='padding:12px 0;text-align:center'><h1>CUSTOM ELEMENT</h1></div>"; return $params; } |
I simplify this a lot of times. You can call the editable field’s content and spit it out, but for my case, I just liked having the element’s name displayed and only that. When a content editor wants to see how the page is structured and where certain content blocks are, they can easily identify the module’s name and that is sufficient for me.
Determine What Your New Element Outputs
The important stuff, right? What does the actual element output on the front-end when used. Let’s take a look at that function:
|
function shortcode_handler( $atts, $content = '', $shortcodename = '', $meta = '' ) { $output = ''; $output .= '<div class="your-custom-element">'; $output .= '<h2>' . $atts['field_1'] . '</h2>'; $output .= '</div>'; return $output; } |
This is a fairly simple example, but you can get a really good reference on how to modify it for what you need. Remember that earlier function where you defined the editable fields? Well we made one called “Field 1” and gave it an ID of “field_1”.
While we output the HTML we want, you can called that value with the syntax
$atts['field_1'] . As you begin to build more complex elements, you will need to give those unique identifiers and reference them in the same way.
Conclusion
Hopefully, this is a simplistic example to get you started on building custom Advanced Layout Builder elements. Here is a great reference that helped me immensly in starting out on this endeavor and I believe there may be more valueable information in that article, as well. I hope this helps. Leave your comments and questions in the section below. Happy Coding!
February 21, 2020
I’ve used Campaign Monitor for years as an email marketing tool. Recently, I had to work with PHP and the Campaign Monitor API to retrieve the subscribers from an email list for a specific client. Luckily, Campaign Monitor has made their API incredibly easy to work with while trying to accomplish some of these tasks and we are going to dive into how I accomplished it.
My objective was to retrieve a list of subscribers from an account, detect the total amount of subscribers on that list, and hide or show a sign up form based on whether the threshold of maximum subscribers was met.
Step 1: Using an API Wrapper Library
There are a multitude of languages and API Wrappers you can use to query and update the Campaign Monitor API, but since the site I was implementing this on was PHP, that is the language we will be using today.
You can explore their entire Campaign Monitor API PHP Library called createsend here. You will need to include this library in your project in order to execute a lot of the tasks needed to work with your Campaign Monitor account. I downloaded the library and included it in my WordPress theme template. There are many other ways to include it and you can explore their documentation on how to do so.
Step 2: Get an API Key
Like many APIs, you will need authentication to work with them. I found that most tasks for viewing and retrieving data only required the simpler API key so that’s the route we will be going today. In order to manipulate the accounts data (like adding a new email to a list), you will likely need OAuth credentials. For today’s example, we are looking to just retrieve the list of subscribers. Let’s get an API Key!
Log into your Campaign Monitor account. Go to Account Settings and then click on API Keys on the right hand side. That should bring you to a page like this:

This has the list of all of your clients, their API keys, and some options to edit them. It also has an Administrator API key, although, it is not recommended to use this when working on one specific client. You are going to want to find your client and get their API Key.
Note: This is also how you find the Client ID. In some cases, you will need this info as well, but not for this example.
Step 3: Get a List ID
The second part you will need is the List ID. When working with specific list of subscribers, you will need to find the specific List ID which identifies the group you want to work with.
In order to find your list ID, go to the Client you are working with, click on Lists & Subscribers, click on the list you would like to work with, and hit Change Name/Type.
Though you aren’t seeking to change the name, this will provide the API List ID that you are looking for. It appears at the bottom of the settings like below:

Copy and save that List ID value.
Step 4: Prepare your Library and Code
As I mentioned before, this example pertains to obtaining a list of subscribers, figuring out how many there are, and showing a form whether or not we have exceeded that threshold. It is in WordPress, so you would want to place the createsend library in your theme directory and call it like such:
|
<?php get_template_part('createsend/csrest_lists'); $auth = array('api_key' => '### YOUR API KEY GOES HERE ###'); ?> |
If you weren’t using WordPress, you would just use the standard PHP function:
|
<?php require_once('createsend/csrest_lists.php'); $auth = array('api_key' => '### YOUR API KEY GOES HERE ###'); ?> |
This, of course, is all relative to where you place your library, how you place your library, etc…. but the important thing is you are including it and establishing your API key by placing it where I have specified in the code.
Step 5: Use the Library to Call Active Subscribers from A List
Now the fun stuff. Below is a code snippet to request the active subscribers from a list you specify:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
<?php //SPECIFY THE LIST $wrap = new CS_REST_Lists('##### YOUR LIST ID GOES HERE #####', $auth); //REQUEST THE SUBSCRIBERS FROM THAT LIST $result = $wrap->get_active_subscribers('', 1, 500, '', '', true); //ARGUMENTS FOR get_active_subscribers ARE: // "added since", "page number", "page size", "order by", "order", "consent to track" if($result->was_successful()) { $response = $result->response; $k = $response->TotalNumberOfRecords; if($k < 500) { //WE HAVE NOT HIT 500 SUBSCRIBERS, SO SHOW THE FORM HERE } else { //WE HAVE HIT 500 SUBSCRIBERS, HIDE FORM } } else { echo 'Failed with code '.$result->http_status_code."\n<br /><pre>"; var_dump($result->response); echo '</pre>'; } ?> |
Ok, this is a big chunk, so let’s break down what’s happening here.
First, you are specifying the wrapper by identifying the list you want to query. You got the List ID as explained earlier.
|
$wrap = new CS_REST_Lists('##### YOUR LIST ID GOES HERE #####', $auth); |
Next, we are using the function
get_active_subscribers from your library to request them from your list how you see fit. It takes several arguments, so it’s very important to plan and determine how those subscribers should be queried. I placed the arguments in the comments below and the createsend documentation has a great amount of further explanation on this. As an example, I didn’t set a time limit, I wanted the first 1-500, ordered by email, and ascending. The Consent to Track is dependent on your list settings.
|
$result = $wrap->get_active_subscribers('', 1, 500, 'email', 'asc', true); //ARGUMENTS FOR get_active_subscribers ARE: // "added since", "page number", "page size", "order by", "order", "consent to track" |
After we query that list, we are asking: Was this successful? If so, let’s store the response as a variable, determine how many active subscribers we got, and if it’s above 500 (an arbitrary number for the sake of example), then hide the form! If not, show the form!
For some purposes, you will want to loop through the result to list names, emails, etc. Everything stored in the
$response variable will have what you need! You can iterate through the array like so:
Conclusion and Full Code Snippet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
<?php get_template_part('createsend/csrest_lists'); $auth = array('api_key' => '### YOUR API KEY GOES HERE ###'); $wrap = new CS_REST_Lists('##### YOUR LIST ID GOES HERE #####', $auth); $result = $wrap->get_active_subscribers('', 1, 500, '', '', true); if($result->was_successful()) { $response = $result->response; $k = $response->TotalNumberOfRecords; if($k < 500) { //WE HAVE NOT HIT 500 SUBSCRIBERS, SO SHOW THE FORM HERE } else { //WE HAVE HIT 500 SUBSCRIBERS, HIDE FORM } } else { echo 'Failed with code '.$result->http_status_code."\n<br /><pre>"; var_dump($result->response); echo '</pre>'; } ?> |
The Campaign Monitor API is very robust, regardless of what language or method you are using to work with it. Hopefully, this example served as a helpful tool in working with your Campaign Monitor clients and you can help build upon this example for your needs. Happy Coding!
February 11, 2020
CSS variables are quickly becoming my favorite thing in web development. The Custom Properties function in CSS3 is nothing new, but it’s finally becoming more widely accepted and supported. I also include a few examples on how to implement these in ways that I have found useful.
The best way to be efficient in web development is to avoid redundancy. Using CSS variables for common values that get repeated throughout a stylesheet is a very helpful way to accomplish this. I’ve also found them extremely helpful when working with margins, paddings, and the calculations thereafter in layouts and media queries.
How To Use CSS Variables
Let’s look into how to use a CSS variable. The first step is to set the variable name and value. We do this by declaring it at the beginning of a style sheet in the
:root psuedo element. This allows the variable to be accessible by all selectors in the stylesheet. In this example, we are going to set a variable to a common color we may use throughout the stylesheet.
|
:root { --light-blue:#336699; } |
We have now set the variable “light-blue” to a HEX value that I can use throughout the site, like the following example:
|
.container { background: var(--light-blue); } |
Just like that, the background color for that element will become
#336699 and if I ever want to change it, I only need to adjust the variable at the beginning of the stylesheet! I can use the variable in many selectors for various reasons and only need to refer to one place to ever change that value.
There is also an optional second value when using the variable in the event it isn’t provided:
|
.container p { color: var(--light-blue, #336699); } |
So, that’s cool and all, but let’s see some examples of how this can be really helpful.
Examples of CSS Variables
Let’s say I have a theme and having consistent spacing is incredibly important. Well, I can declare a CSS variable for that spacing and re-use it throughout the theme stylesheet:
|
:root { --spacing: 32px; } .container { padding: var(--spacing) 0; } p { margin: var(--spacing) auto; } |
Let’s take a look at what’s happening here. I want the spacing of the elements to always be 32 pixels, so I declare my “spacing” variable and then re-use it in a few places. You can use the variables as one part of the property value, much like I am in both declarations, to make them even more flexible. The paragraphs will have a property of
margin: 32px auto; and the container will have a property of
padding: 32px 0;.
To dive even deeper — there’s a good chance I am going to want to change this value on smaller devices/screens. Thanks to the flexibility of this function, I can change it through a media query and never have to declare new stylesheet rules!
|
@media all and (max-width:720px) { :root { --spacing: 16px; } } |
Now, on devices smaller than 720px, the paragraphs will have a property of
margin: 16px auto; and the container will have a property of
padding: 16px 0;. We’ve updated a property on multiple elements on the site with a single stylesheet rule. How cool is that??
And if you’re wondering, yes, you can have multiple variables with multiple media queries:
|
:root { --blue: #336699; --spacing: 1em; } @media all and (max-width:720px) { :root { --blue: #2163A5; --spacing: 0.9em; } } |
Even more helpful, you can include variables as part of another function like
calc() or another stylesheet value:
|
:root { --spacing: 48px; --blue: #336699; } .container { padding: calc(var(--spacing) / 2); border: 2px var(--blue) solid; } |
The padding for the container will now become 24px (because we divided it in half) and there will be a 2 pixel solid blue border with the color we specified around the element.
IE fallback
Unfortunately, not every browser supports CSS variables. Most notably, Internet Explorer. I still come across clients who want this browser compatibility so here is your fallback: Find + Replace! Haha, just kidding, but seriously — I often develop a site using CSS variables, spare myself valuable time avoiding redundancy, and then find and replace the variable with the value in a text editor or IDE. It’s stupid and it’s simple.
Conclusion
The possibilities are absolutely endless for CSS variables which is why they have become such a favorable tool for developers. They’ve become part of my workflow more and more. On almost every project I find another method of using them which saves me valuable time and typing!
Hope that helps! Happy coding!