Creating a background image/background color widget

Regular Contributor

I've created a background image widget that has an image, rich text, and CTA component in HubL. Is it possible to add an if statement that would allow me to select either an image or background fill instead of the image? Or is there some other way to accomplish this? I'd like to be able to select either option after placing the module on any landing page. 

2 Replies 2
Esteemed Advisor

Hi @cpburke ,


Yes, that is something that can be easily accompished.


Let's say this is the html structure for your module:

<div style="">
  <!-- Your Richtext -->
  <!-- Your CTA -->


You want to be able to choose between a background image or a background color. to do this you need some kind of switch. You can use a choice module, but to keep things simple here, I'll use a boolean toggle:

download (1).png


Whether you choose to have the toggle checked by default or not is up to you.


We want to use this to create some logic. You can copy the "snippet" from the copy dropdown (blue "copy" link, above and right of the HubL variable name). that will look like this:

{% if module.bg_image_ %}
	<!-- HTML to show when checked -->
{% endif %}


you will want to modify it a bit by removing the html comment, and adding an "else" statement:

{% if module.bg_image_ %} {% else %} {% endif %}


We need two fields to give this module proper customization options: an image field to get an image url, and a color field to get a color code. I'll start with the image field:

download (2).png

I set a default image in the "Content Options" for this field, but I minimized it to fit the "Display Conditions" on my screenshot because I feel it is good practice to hide the image field if the "BG Image?" toggle is unchecked. I've the conditions to only show this image field if "bg_image_" is equal to "true", which means it's checked.


We can now place this image into our "BG Image?" conditional statement. Copy the snippet for the image field (the value is fine if you know how to modify it, but if not...) and paste it into the "HTML + HUBL" section of your module editor. it will look like this:

{% if module.background_image.src %}
	<img src="{{ module.background_image.src }}" alt="{{ module.background_image.alt }}" width="{{ module.background_image.width }}" height="{{ module.background_image.height }}">
{% endif %}


Your don't need all of this code, you only need the token for the image src:

{{ module.background_image.src }}

You can copy that, and delete the rest. Paste that token into your "BG Image?" Conditional statement:

{% if module.bg_image_ %}url({{ module.background_image.src }}) center center no-repeat{% else %} {% endif %}

Now, when the toggle is checked, it will print the image url.


Setting up the color field is a little trickier, or at least I am going to make it complicated so as to include all available options. First, create color field:

download (3).png


You have an option to choose the default color, and the default opacity. Also, I have set display conditions to only show this field if "BG Image?" is unchecked.


Copy the snippet for this field, and paste it into your work area. You will find two tokens, the color token and the opacity token:

{{ module.background_color.color }}
{{ module.background_color.opacity }}

The color token is going to print the hexidecimal color code for the chosen color. The opacity token is going to print the chosen opacity, as an integer value between 0 and 100. 


The color token will work just fine on it's own, for a solid color, however the opacity token's value doesn't really work because the css opacity property accepts a value between 0 and 1 (i.e. 0.1, 0.2, 0.3, etc.). To get the proper format, we want to modify the token by dividing it's value by 100:

{{ module.background_color.opacity / 100 }}

Now if opacity is set to 10%, for instance, it will print "0.1".


You can use this with the opacity css property:

<div style="opacity: {{ module.background_color.opacity / 100 }};">

but since we are using both the color and the opacity, we might as well as combine the color and opacity into RGBa format. We need to modify the color token though, converting it to RGB color format, using the HubL convert_rgb filter (the 'a' stands for alpha, we will take care of that with the opacity token), like this:

{{ module.background_color.color|convert_rgb }}


This will print the color in rgb format:

255, 255, 255


Now we can combine both tokens to make the background property RGBa value:

rgba({{ module.background_color.color|convert_rgb }},{{ module.background_color.opacity / 100 }})

Dont forget the comma after the color token.


Now we need to place that into the "else" part of our toggle condition. I'm going to use line breaks here, but this can all be one line of code as well:

{% if module.bg_image_ %}
url({{ module.background_image.src }}) center center no-repeat
{% else %}
rgba({{ module.background_color.color|convert_rgb }},{{ module.background_color.opacity / 100 }})
{% endif %}


The last step is to apply the above code as the value to the "background" attribute of your wrapper, inline (HubL can't be used in the css or javascript areas of the module editor):

<div style="background: {% if module.bg_image_ %}
url({{ module.background_image.src }}) center center no-repeat
{% else %}
rgba({{ module.background_color.color|convert_rgb }},{{ module.background_color.opacity / 100 }})
{% endif %}
;"> <!-- Your Richtext --> <!-- Your CTA --> </div>


I would clean this up a bit though:

<div style="background: {% if module.bg_image_ %}url({{ module.background_image.src }}) center center no-repeat;{% else %}rgba({{ module.background_color.color|convert_rgb }},{{ module.background_color.opacity / 100 }}){% endif %};"> 
<!-- Your Richtext -->
<!-- Your CTA -->

and that is basically it. If you want to get really creative, you can use two color fields, group them, and apply their tokens to a css color gradient. It's the same concept, just more work when you account for browser prefixes. Each 'color stop' on the gradient would get it's own color field set up. I have taken this even further by using a choice field for gradient orientation options, also. Grouping the fields is for user experience in the page editor.


Also, you could use the "if" condition wrapping the image in the image's default snippet instead of the boolean toggle. "If" an image is set use the background image tokens, "else" use the background color. I find this to be a bad user experience because if you set a default background image it might not be clear that the image has to be removed in order for the color to apply. Not setting a default image is better, but I still don't like it. I find it cleaner to use the boolean toggle.


Let me know if this helps.



Need help? Hire Us Here

- Jonathan Sumner
Regular Contributor

Thank you for taking the time to put together instructions. I will try this today and let you know how it turns out.