Custom Background Image Module/ Banner Image module with text

SOLVE
HubSpot Employee

 

A Custom Background Image Module

I have found that this post over a year later is still quite popular. Re-reading this post, after learning so much, feels like reading my middle-school diary. As such, I have updated it with the specific audience of ‘people who have not made a module in HubSpot’ in mind. This guide will still go over the same concept, making a custom background image module, but it will be better, like @cbarley’s description below.

Here’s the main concept we’re working with, and why we are doing it this way:
The module that we make here will look, more or less, the same wherever it is dropped. This means no matching up stylesheets, none of that, and you can customize it all you want.

With that in mind, let’s look first at the playing field, so we can understand the components, and then we’ll be able to better use them. To do that, we’ll need to first create the custom module. In Design Tools use the ‘Create a new file’ button or File > Create a new file in [folder] option on the left.
community1.gif
It does not matter what you name it, give it a name that means something to you. Here’s what things should look like now, I have labeled a few parts

module.png

  1. HTML and HubL
    This is the section where we’re going to do the majority of our work. In terms of the module, this is essentially what actually gets output on the page.

  2. CSS

This is the section that supports CSS. I believe that currently, HubL is not supported here, so we will only be using CSS that does not require HubL here. CSS that would require HubL would be any CSS call that you would want to customize from the page editor. We don’t need to do that, but it can be nice. 

 

  1. JS
    This section supports JS, we won’t be using any here, but if we wanted to, we could add it here. This is nice because you don’t need to add anything to your main JS file to support it on each implementation, it will be there wherever the module is present. This can also be a downside: if it conflicts with other JS on the page, so keep that in mind. 

 

  1. Fields
    This one is pretty important to understand. These are going to be the available fields that you can edit when you are on the page editor. Any text that you want to be able to edit, you need to add a text field for that here. 

Now, just adding the field here does not do anything directly, apart from allowing a user to select it and set a value, but that value would not be put anywhere. 1, the HTML and HubL section, is where things actually happen and so we need to put something there that says something akin to ‘when something is set here, that goes there’
We’re going to get deeper into fields as we start to build out the module.


Building out the module-
HTML First

Our module is going to be a full-width background image, that has a main header and a subheader. In building this, I am hoping to convey some general building concepts here as well, so that you the reader will know how to replace parts of it with whatever you want. Don’t want the subheader and instead want a CTA? You should be able to do that by the end of this. 

 

For me, when I am building out a module for the first time, I like to start with the HTML without adding any fields yet. This allows me to get everything in place, and then I can add in the fields after, and then insert their values where I need them. I am going to assume that the reader knows some basic HTML and CSS, or at least enough to Google the things you don’t know that I mention here.

The basic build will look something like this:

<div class='banner-image'>
<div class='banner-text-area'>
<h1> My header text </h1>
<h2> My subheader text </h2>
</div>
</div>



Here we have an outer-wrapper div we’re called banner-image, and this is what will display the banner image. Inside that, we have another div called banner-text-area, where we have an h1 and an h2.
We’re doing it this way so that the banner image can be full width, while the text will have some styling to put it in the center. We’re now ready to move onto our fields.

Adding the fields

 

At its most basic level, the three things here we will want to be able to change will be the banner image itself, and the header and subheader text. For each of these things we want to change, we need a field. We will use an Image field for the background-image, and two separate text fields for the header and subheader.
To add a field, on the right hit ‘Add field’ and then search/find the one you are looking for. Give them a name that will be meaningful to you when you are editing them on the page level. I have gone with Banner Image for my image and Header and Subheader for my text fields.
community2.gif
Give yourself a high-five because if you got this far and you’re still saying, “alright, I think I get this” then you are well on your way to doing whatever you want in these modules.
source


Let’s do a quick review of what we have here:
In the HTML and HubL area, we have the skeleton of what our module is going to look like
On the right, we have 3 Fields that are going to be used in the module. Let’s start with the two text fields because they are the easiest. We know where they are going, right between the h1 and h2.

Let's do it

Mouse over ‘Header’ first, hit
Actions > Copy Value Only

This part is important, we only want to output the value of this field, we don’t want to insert the full snippet, because that’s going to add extra code that we don’t need in this context. 

Now, take that value, and add it in between the h1 tags, removing the original text we had.
community3.gif
Do the same for Subheader, using Actions > Copy value only, and paste it into where the subheader text was. If you used the same naming conventions as me, your HTML and HubL will now look like this:

<div class='banner-image'>

<div class='banner-text-area'>
<h1> {{ module.header }} </h1>
<h2> {{ module.subheader }} </h2>
</div>
</div>

 


Note that if you named your fields something different, they will have a different name here, as long as you used ‘copy value only’ from the field, you’ll have the right code.

Now, we want to add in the image. If we use ‘copy value only’ the code will output like this:
{{ module.banner_image }}
The issue here is that it is going to output the full image HTML, and that won’t work for our purposes. Instead, we’re going to grab just one attribute from it, the src attribute, which stores the URL of the image. We are then going to use that as the value for some inline styling. This is probably one of the more complicated things we’re doing here, but it’s relatively easy. If you followed my naming convention, the code we want to use is:
{{ module.banner_image.src }}

That .src at the end says ‘just give me what is in the src attribute of the image’ and we can then use this in our wrapping div like so:

<div class='banner-image' style="background-image:url('{{ module.banner_image.src }}')">
<div class='banner-text-area'>
<h1> {{ module.header }} </h1>
<h2> {{ module.subheader }}</h2>
</div>
</div>

 


What we’re doing here is we’re saying for this div, have it have a background image that has the value of the image module we’ve added. This allows us to, on the page-level, select an image that we’d like.

 

Another high-five moment

giphy

 

You’ve made it this far, which means you’re pretty much almost done. The only thing left here is to do some styling tweaks. We have the core structure of everything we need here, we have a field that allows us to select an image, that image is then passed to the div banner-image as its background image. We have two other text fields that will ‘float’ over this.

Now, we just need some CSS to make things the right size. With all things CSS, there are many ways to approach this. I am not going to teach CSS here, and I think @cbarley has some fantastic (much better than my) CSS in there, so I am going to steal it and rework it for these purposes. If you copy and paste the following, provided you used my same naming convention, you should be able to publish, pat yourself on the back, and test it out:

.banner-image {
 background-size: cover;
 background-position: 50% 50%;
 background-repeat: no-repeat;
 height: 400px;
}


.banner-text-area {
 background: rgba(0,0,0,.6); /*adds background color to the text area*/
 width: 50%;
 margin: 0 auto;
 position: relative;
 top: 100px;
}


.banner-text-area h1 {

 text-transform: uppercase; /*makes it always uppercase */
 color: #fff;
 text-align: center;
 font-size: 60px;
 margin-top: 0;
}

.banner-text-area h2 {
 color: #fff;
 text-align: center;
 font-size: 30px;
}

@media(max-width: 767px) {
 .banner-image{
 height: 300px;
 }
 .banner-text-area h1 {
 font-size: 40px;
 }
 .banner-text-area h2 {
 font-size: 20px;
 }
}

 



Note: We never set any default values for the fields, so when you first preview the module, it will look empty. Select an image and some text, and it should be all set.

This is what the final module should look like in the editor:


And here’s an example of what it would look like in the preview after selecting an image an adding text:

 

Now, if you wanted to replace any of the text elements with something else, if you followed the steps here, you would just clone the module, and then add in a new field on the right, have that field output to where you want it to be, and mess around with the styling until you have it as you’d like.

 

giphy

 



1 Accepted solution

Accepted Solutions
Highlighted
HubSpot Moderator

Great writeup @mrcruz! We had this convo over Slack, but I'd also like to continue that here/point out another way to set this up for anybody interested.

 

I like to create background image sections using only a custom module so that it's set up for people that may not be as familiar with code and that the can use moving forward quite easily. The reason being two-fold: one - the background image section can be edited in only one place (the editor) if you do it this way, taking away any confusion for somebody that may not be as familiar with code. and two - so that your code can be modular. With the new CMv2, we can add CSS right in our CSS declarations section, and therefore those styles will carry onto any page it's placed on, regardless of the stylesheet that's attached.

 

Here's how I'd write it up. In the HTML we'd have:

 

<div class="background-image" style="background-image: url('{{ module.background_image.src }}')">
    <div class="page-center">
         <div class="header-text-section">
              <h1>{{ module.header_text }}</h1>
              <p>{{ module.subheader }}</p>
         </div>
     </div>
</div>

 

and in our CSS, we'd have something like:

 

.background-image {
background-size: cover;
background-position: 50% 50%;
background-repeat: no-repeat;
height: 400px;
}

.header-text-section {
background: rgba(0,0,0,.6);
width: 50%;
margin: 0 auto;
position: relative;
top: 100px;
}

.header-text-section h1 {
text-transform: uppercase;
color: #fff;
text-align: center;
font-size: 60px;
margin-top: 0;
}

.header-text-section p {
color: #fff;
text-align: center;
font-size: 30px;
}

@media(max-width: 767px) {
.background-image{
height: 300px;
}
.header-text-section h1 {
font-size: 40px;
}
.header-text-section p {
font-size: 20px;
}
}

 

I like this way because the person who's utilizing the module on the page level won't really have to do anything besides plug in any values they'd want!

 

Something else that I like to do is put in another single line text field with "no_wrapper=True" setup inline next to the background-image declaration. The declaration would simply be

 

 

background-position: "{% inline_text field="background_position" value="{{ module.background_postition }}" no_wrapper="True" %}";

This way, we can pass in any valid CSS here such as 10% 90%, or center top etc. I find the most common complaint is that background images sometimes cut off parts of the image (as they will if the background-size is set to cover), so at the very least, we can solve on the page level for this with this new field. Especially since not all background images are the same and we wouldn't have to rely on that background-position declaration in the CSS section (we can actually just get rid of that).

 

Here's what it looks like in the CMv2 editor:

 

Screenshot 2018-04-03 22.01.24.png

 

I do like your way of doing this as well, and I think both examples are equally valid, which is a really great thing about HubSpot and how we can edit code in the Design Manager!

24 Replies 24
Highlighted
HubSpot Moderator

Great writeup @mrcruz! We had this convo over Slack, but I'd also like to continue that here/point out another way to set this up for anybody interested.

 

I like to create background image sections using only a custom module so that it's set up for people that may not be as familiar with code and that the can use moving forward quite easily. The reason being two-fold: one - the background image section can be edited in only one place (the editor) if you do it this way, taking away any confusion for somebody that may not be as familiar with code. and two - so that your code can be modular. With the new CMv2, we can add CSS right in our CSS declarations section, and therefore those styles will carry onto any page it's placed on, regardless of the stylesheet that's attached.

 

Here's how I'd write it up. In the HTML we'd have:

 

<div class="background-image" style="background-image: url('{{ module.background_image.src }}')">
    <div class="page-center">
         <div class="header-text-section">
              <h1>{{ module.header_text }}</h1>
              <p>{{ module.subheader }}</p>
         </div>
     </div>
</div>

 

and in our CSS, we'd have something like:

 

.background-image {
background-size: cover;
background-position: 50% 50%;
background-repeat: no-repeat;
height: 400px;
}

.header-text-section {
background: rgba(0,0,0,.6);
width: 50%;
margin: 0 auto;
position: relative;
top: 100px;
}

.header-text-section h1 {
text-transform: uppercase;
color: #fff;
text-align: center;
font-size: 60px;
margin-top: 0;
}

.header-text-section p {
color: #fff;
text-align: center;
font-size: 30px;
}

@media(max-width: 767px) {
.background-image{
height: 300px;
}
.header-text-section h1 {
font-size: 40px;
}
.header-text-section p {
font-size: 20px;
}
}

 

I like this way because the person who's utilizing the module on the page level won't really have to do anything besides plug in any values they'd want!

 

Something else that I like to do is put in another single line text field with "no_wrapper=True" setup inline next to the background-image declaration. The declaration would simply be

 

 

background-position: "{% inline_text field="background_position" value="{{ module.background_postition }}" no_wrapper="True" %}";

This way, we can pass in any valid CSS here such as 10% 90%, or center top etc. I find the most common complaint is that background images sometimes cut off parts of the image (as they will if the background-size is set to cover), so at the very least, we can solve on the page level for this with this new field. Especially since not all background images are the same and we wouldn't have to rely on that background-position declaration in the CSS section (we can actually just get rid of that).

 

Here's what it looks like in the CMv2 editor:

 

Screenshot 2018-04-03 22.01.24.png

 

I do like your way of doing this as well, and I think both examples are equally valid, which is a really great thing about HubSpot and how we can edit code in the Design Manager!

Occasional Contributor

Can you please send a tutorial on how to do this for email templates?

 

I have been working on this for 2 days now and the image is not showing.

 

Thanks

Reply
0 Upvotes
HubSpot Employee

hey @paulamc thanks for reaching out. This would work in some email clients but not others. With email, it all comes down to what CSS they support. This page from Campaign Monitor will show you the breakdown per email client.  You can try using background-image instead of background which does offer slightly wider support, but still not supported by many major email clients (Outlook 2016 for instance)

Occasional Contributor

Thank you!

Reply
0 Upvotes
Regular Contributor

I found that a combination of the two was helpful.. the 50% 50% gave me the desired results... 

 

One thing that I thought would work, but didn't, was to put the height at 100% as well as the width... I want to be able to guarantee the full image is displayed regardless of the resolution of the screen (for a very specific request from a client)

Reply
0 Upvotes
New Contributor

Hi @cbarley ! 

 

I've used your method in a template for a new landing page (at this URL: http://info.coloradospacesolutions.com/free-quote-colorado-space-solutions-0), but as you can see, the image is not showing properly. It's just all white.

 

Any ideas?

Reply
0 Upvotes
HubSpot Moderator

Hi @co_space , you've named your background image field "image_field". You must reference the field in your code as such for it to render. 

 

Screenshot 2019-04-03 17.44.28.png

Reply
0 Upvotes
New Contributor

Ah.. okay. I've made them all match now: Screen Shot 2019-04-03 at 3.54.56 PM.png

 

But it's still blank Smiley Sad

Reply
0 Upvotes
New Contributor

Never mind! I figured it out - thank you!

Reply
0 Upvotes
HubSpot Moderator

Hi @co_space , you still need to be referencing the module. So for example, it should be {{ module.custom_background_image }}. If you still don't get it to work after that, feel free to DM me!

Reply
0 Upvotes
Community Manager

Thanks for sharing!

 

CC: @danaketh@Josh108@matttunney@Alexandra@nthethy@ccooney@mrspabs@priscillam@Hubmate@jausura

Occasional Contributor

Thanks Smiley Happy

Occasional Contributor

Would this work for email? I have tried with no luck.

 

The link to the original thread is broken, so I am a bit lost when you talk about:

Basically, everything stays the same, but we put the token for image heigh into the style tag like we did with the background property. You can add any number of text fields to be able to modify these variables from the module level. Again, John, I don’t know how I didn’t bother to do this before so thanks for the tip!

Reply
0 Upvotes
New Contributor

HI @mrcruz

Thank you for the solution. But i have one problem when i am trying to add custom-background-class to row  it display same image for multiple rows background. Supppose i want different background imges for different row. How is it aachived. Can you help me?

Reply
0 Upvotes
Occasional Contributor

Awesome tutorial. I managed to create the custom module same as the example and i drag n drop it on my Article Page. Everything works fine.

 

How can i render this custom module on my Blog Listing Page inside the for loop i create to get the articles??

Reply
0 Upvotes
New Contributor

Hi! I have little to no knowledge of html or css, but I managed to create the background module. The only trouble I'm having is that the text I'm putting on my landing page is longer than the image. How would I get the image to repeat itself for the length of the page? It's just texture, so visually it wouldn't be a problem to have it doubled, but I don't know how to do that with css/html. Thanks!

Reply
0 Upvotes
Community Manager

Hey @carson12,

 

Can you create a new post in the design forum and include as many links, screenshots and details as you can regarding where you are getting stuck? 


Did my post help answer your query? Help the Community by marking it as a solution
Reply
0 Upvotes
New Contributor

It looks great, but my text is getting lost that is over the image. How can I add a white box to hold a rich text module in?

Reply
0 Upvotes
HubSpot Employee

I would try adding a background to the rich text module, you can do that with the inline-style option in the template editor. Just open up your template, click the rich-text module and apply background-color: #fff to the inline styling section. You may need to play around with some sizing/padding to make it look just the way you like it.
Side note: white text with a black border can be read over any background color/image. 

New Contributor

Hi MrCruz, many thanks for your directions.  (I am not a developer!).  I have done my best to copy these instructions, but don't seem to end up with a background image and the existing modules for header and footer don't seem to render correctly.

 

This is the image I was intending to test as a background image

https://cdn2.hubspot.net/hubfs/5902561/iStock%20Photos/iStock-585160380.jpg

 

This was the page I ended up with

https://page.urim.app/test-landing-page-with-background

 

I'm sure it's some instruction I haven't understood, but your first line support team said I should approach the Developers Team :-).  Guidance appreciated.

 

Thanks Gill

Reply
0 Upvotes
HubSpot Employee

Hey @acmgturim I am going to reach out to you via a ticket and we'll get this fixed for you.

Reply
0 Upvotes
New Contributor

Thanks Matt, much appreciated.  Gill

Reply
0 Upvotes
New Contributor

Hi

Im trying to create a Welcome Statement, some text with 2 buttons in a padded block that floats over a background image on our HomePage (above the fold section), that's also responsive. 
With your code I could get the image displayed (yay), but my text is missing. Can someone help me please? Thanks

Reply
0 Upvotes
HubSpot Employee

Hey @dolessmore I'd be glad to try and lend a hand here. Full disclosure: with the recent activity here I have decided I am going to re-write this walkthrough because I want it to be more comprehensive. 
If I had to guess, my guess would be that the tokens that you are using to call for the text in the HTML/HubL do not match the internal values of the text fields you added. Let's say the text field you added is called Text Field, the internal value would be text_field (likely at least) and you'd call for it like {{module.text_field}}
Give that a shot and let me know if it solves things!

Reply
0 Upvotes