Working with Custom HTML
Learn what you can do using the HTML block
Table of Contents
When our component options aren't enough to achieve your design, or when you want to add content from other platforms to your steps, use the Custom HTML option.

Add custom styling to a step or group step
There may be instances in which you'll want to add specific styling to only a step or a step group in a Flow, so that other steps aren't affected. For that, wrap any of the CSS snippets in a <style>
tag and place them in an HTML component of the step you'd like to modify.
<style> /* Insert CSS snippet */
</style>
For example, to change the width of a specific Modal, you can grab the CSS to make it narrower and then wrap it in <style> tags, as shown below.
<style>
appcues[data-pattern-type=modal] cue, appcues[data-pattern-type=modal] > div {
width: 580px;
min-width: 580px;
}
</style>
Then, in your Flow, use the HTML block to enter it. You can adjust the values as you're entering them and see in real-time how they apply.

Use this method with caution – when adding styling via a custom HTML it's easy to lose track of where it's coming from as opposed to using your Theme. Because of differences in how steps are displayed in build mode versus preview/live, it is also possible for the styling change to not appear in build mode while working in preview or live. We always recommend testing thoroughly to ensure the styling rules behave as you expect.
Add custom HTML
Get creative with custom HTML that you can add to your Flows. For example, you can create a Cycling Carousel for images using HTML.

HTML Cycling Carousel Images
<div id="slider">
<div class="images">
<div class="images-inner">
<div class="image-slide">
<div class="image image1"></div>
</div>
<div class="image-slide">
<div class="image image2"></div>
</div>
<div class="image-slide">
<div class="image image3"></div>
</div>
</div>
</div>
<div class="slide-selector">
<label for="slide1" class="slide-slct"></label>
<label for="slide2" class="slide-slct"></label>
<label for="slide3" class="slide-slct"></label>
</div>
</div>
<style>
.image1 {
background-image: url("https://media.4-paws.org/9/c/9/7/9c97c38666efa11b79d94619cc1db56e8c43d430/Molly_006-2829x1886-2726x1886-1920x1328.jpg");
}
.image2 {
background-image: url('https://static.scientificamerican.com/sciam/cache/file/1FD432BD-1DC9-4EE3-B2F3494EBAE7DCAE_source.jpg?w=1200');
}
.image3 {
background-image: url('https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ9UckXzkvboOjQZBmstwQd6pa8OXzcsw1BTQ&s')
}
.image {
width: 100%;
height: 400px;
background-size: cover;
}
.images {
overflow: hidden;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 100%;
}
.images-inner {
width: 500%;
transition: all 800ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
transition-timing-function: cubic-bezier(0.770, 0.000, 0.175, 1.000);
}
.image-slide {
width: 20%;
float: left;
}
.image-slide,
.slide-slct {
transition: all 0.5s ease-out;
}
.slide-selector {
text-align-last: center;
}
/* Color of bullets */
.slide-slct {
width: 9px;
height: 9px;
border-radius: 5px;
background: grey;
display: inline-block !important;
margin: 0 1px;
}
/* Calculate AUTOPLAY for BULLETS */
@keyframes bullet {
0%, 33.32333333333334% {
background: lightgray;
}
33.333333333333336%, 100% {
background: grey;
}
}
div .slide-slct:nth-child(1) {
animation: bullet 12300ms infinite -1000ms;
}
div .slide-slct:nth-child(2) {
animation: bullet 12300ms infinite 3100ms;
}
div .slide-slct:nth-child(3) {
animation: bullet 12300ms infinite 7200ms;
}
/* Calculate AUTOPLAY for SLIDES */
@keyframes slide {
0%, 25.203252032520325% { margin-left: 0; }
33.333333333333336%, 58.53658536585366% { margin-left: -100%; }
66.66666666666667%, 91.869918699187% { margin-left: -200%; }
}
#slider .images .images-inner {
animation: slide 12300ms infinite;
}
</style>
Embed external content
Use an HTML block to embed external content, for example, a booking page or an external survey. As a rule of thumb, iFrame your content. An example of an iFrame can be found below.
<iframe width="100%" height="400px" src="YOUR_URL"></iframe>
Then, add it using the HTML block. For a practical example on how to embed a Typeform survey in an Appcues Flow, read our article.

Please note: For security reasons, we do not support JavaScript in Custom HTML blocks (outside some whitelisted partners). Most embedded content will require using an iframe embed. Anything that has a <script> tag most likely won’t work in our html blocks.
The HTML editor will sanitize all input to prevent malicious content. This has an effect if you need to use JSON in HTML attribute values. You will need to use special formatting for these values so that they are rendered properly. All JSON values must have double quotes that are part of the JSON string replaced with". For example, myJsonAttribute="{"key":"value"}" must be entered into the HTML editor as myJsonAttribute="{"key":"value"}"
Create custom buttons
<div class="custom-button-wrapper">
<a data-step="next">
<img src="https://hips.hearstapps.com/hmg-prod/images/sacred-birma-cat-in-interior-royalty-free-image-1718202855.jpg" style="height:100px"/>
</a>
<div>
<style>
.custom-button-wrapper {
align-items: center;
justify-content: center;
display: flex;
}
</style></div></div>

The easiest way to figure out which attributes to add is to create a native button with the appropriate actions, and then inspect the button while previewing the flow. A button with a next step action that is tracking an event and updating a user property, like so:

Will look like the following when inspected in preview mode:

Right-clicking and choosing Edit as HTML will allow you to directly copy the necessary attributes—data-attrs-profile-update and data-attrs-event—and paste them into your custom button HTML:

