Exporting InDesign to HTML: Images

Tl;dr: skip to Putting It All Together to read the conclusion without having to read the adventure it took to get there.


This is part 3 of a multi-part series where I do a deep dive into Adobe InDesign’s export to HTML functionality, with this post’s focus on images.

Part 1, Exporting InDesign to HTML: The Basics took a look at exporting basic document elements: title, headers, text (including bolded and italicized text), bulleted lists and numbered lists.

Part 2, Exporting InDesign to HTML: Tables took a look at the steps necessary to export semantically correct tables from InDesign to HTML.


I much prefer posting long-form documents to the web as HTML. It’s not that I dislike PDFs, but experiencing a PDF on a smartphone and, sometimes, on a tablet is irritating. But creating a PDF is much faster than marking up a long document in HTML.

Enter Adobe InDesign, a document production app most often associated with print documents (and PDFs). But in the past few years Adobe has worked to make it viable in the digital publishing space. And one aspect of that is the ability to export a document to HTML.

That functionality intrigues me because the potential efficiencies created by a fully-featured, well-executed export function are measurable. So I decided to do a deep dive into this with three questions framing my assessment:

  • How semantic and clean is the markup on export?
  • How does a complex document export to HTML?
  • How robust are the options when exporting to HTML?

The Approach

I want to continue being methodical about this, so that as I found pitfalls in the process I would be able to know where to fix things and adjust along the way.

My approach:

  1. In a change from my previous posts, I did not update the source Word document. In my experience, images (or other vector or raster graphics) are usually independent files placed in InDesign;
  2. Identify often-used elements, like a photo caption and a photo credit, to ensure that images needing those elements export correctly;
  3. Use the standard paragraph and character styles found in Word, if possible, to be consistent across apps and, if not possible, create the necessary new ones; and
  4. Iteratively add complexity once I met with success doing the simple markup export and successes with each level of complexity added.

Often-Used Elements with Images

In many instances, a placed graphic will need a caption or a credit of some kind. And in those instances in HTML, the following things need to happen:

  • The <img> tag should be wrapped in the <figure> tag;
    • Solution: Create paragraph style called Figure, assign <figure> tag to export tag
  • The <img> tag’s alt parameter needs to have content added;
    • Solution: select the image, right-click, then choose Object Export Options…
  • The image caption and/or credit needs to be wrapped in the <figcaption> tag;
    • Solution:
      • create an object style called Image Figcaption;
      • Assign <figcaption> to the Export Tagging and assign it to the text box containing both the caption and the credit (both of which have their own paragraph styles;

Export Attempts

It took me 28 export attempts spread across several hours over the course of several days before I finally had the HTML exporting correctly. Rather than detail each of those attempts, I’m just going to go directly to the solution.

Putting It All Together

This is a multi-step process involving creating paragraph styles, object styles, text and image frames and grouping them all together. Once one is created, though, it can be added to an Adobe CC Library so that it’s easily available whenever it’s needed.

Create New Paragraph Styles

  • Caption: create a new paragraph style named Caption and in the “Export Tagging” option assign:
    • Tag: p
    • Include Classes in HTML: checked
    • Class: caption
  • Credit: create a new paragraph style named Credit and in the “Export Tagging” option assign:
    • Tag: p
    • Include Classes in HTML: checked
    • Class: credit
  • Figure: you’ll never actually assign this style to anything, but one of the Object Styles you’ll create below does; it’s necessary for spacing. Create a new paragraph style named Figure and in the “Export Tagging” option assign:
    • Tag: figure

Create the Object Styles

Ended up creating three object styles: one called Figure, one called Image Normal and one called Image Figcaption. Combined together, these three object styles successfully create almost semantically correct HTML output.

  • Create the Figure object style :
    • Anchored Object Options:
      • Position: choose Inline or Above Line
      • Select Above Line
        • Alignment: left
          • Space before: 0
          • Space after: 0
    • Export tagging:
      • Tag: enter figure
  • Create Image Normal object style
    • Basic Attributes
      • Paragraph style: assign Figure
      • Text Wrap: off
      • Anchored Object Options:
        • Position: choose Inline or Above Line
        • Select Above Line
          • Alignment: left
          • Space before: 0
          • Space after: 15
      • Export Tagging: leave set to [automatic]
    • Export Options > Alt Text choose Custom from “Alt Text Source” menu
  • Create the Image Figcaption object style
    • Basic Attributes
      • Anchored Object Options:
        • Position: choose Custom
        • Anchored Object Reference Point: choose the upper, left-hand square in the grid
        • Anchored Position Reference Point: choose the middle, left-hand square in the grid with:
          • X Relative To: choose Text Frame with X Offset at 0
          • Y Relative To: choose Baseline with Y Offset at 0
      • Export Tagging:
        • Tag: enter figcaption

Create a Group of Text and Image Frames and Assign Object Styles

These three object styles need to be combined together to create one object that will export to semantically correct HTML for images with captions and/or credits.

  1. Create a frame and assign it the Figure object style. Make sure the frame is wide enough to stretch from the left to right margin of your document and tall enough to take up about half a page.
  2. Create another frame and assign it the Image Normal object style. (It helps to place an image in the frame.)
  3. Create a third frame and assign it the Image Figcaption object style. In that frame insert the following text:
    1. Photo credit and assign it the Credit paragraph style
    2. Caption and assign it the Caption paragraph style
  4. Select the Image Normal frame and cut and paste it into the Figure frame.
  5. Select the Image Figcaption frame and cut and paste it into the Figure frame below the Image Normal frame

Add it to Your CC Library

Add this new group of frames to your “Presos, Proposals and Pubs” CC library so you can easily insert this into documents later.

  1. Select the Figure frame
  2. From the CC Library palette click the + button and choose Graphic.

Inserting a Figure

Insert the Figure text frame inline wherever you need an image placed.

Exporting to HTML

On my 28th—and first successful—export attempt, I used the following settings.

Export Screen

To export to HTML:

  1. Choose Export… from the File menu
  2. In the “Export” window:
    1. Enter a filename in the “Save As” field (it is pre-populated with the name of your InDesign file)
    2. Choose HTML from the “Format” dropdown menu
    3. Click Save
  3. In the “HTML Export Options” window:
    1. General: I left everything as-is
    2. Image: I left everything as-is
    3. Advanced: I chose Include classes in HTML with Generate CSS and Preserve Local Overrides not checked.
  4. Click OK

HTML Markup Review

A quick review of the markup shows a semantically correct marked up image.

What’s Next?

I’ve covered mapping the basic HTML tags in part 1 and exporting tables in part 2. Those two entries, combined with this post about images, should cover the majority of use cases. There are, however, often-used HTML tags that do need to be addressed and I’ll be taking a look at those in my next entry in this series.

Update: The Bland Brettrospective

It’s been a minute since I posted about creating a new custom theme for brettro.com, so I thought I’d post an update.

When I sat down and really started thinking about how I wanted to approach this, I realized how much had changed since I developed the last brettro.com WordPress theme. I decided I wanted to keep up with and learn about as many of those changes as possible throughout the entire design and development process, so I’m tackling each step with intention and a willingness to learn.

Step 1: Develop a Design System

Design systems seem to be the natural evolution of atomic design and provide an incredible amount of detail from the vision of a design to the exact pixel dimension of a rounded corner on a button and just about everything in between. I want to do a deep dive into this, create one for Brettrospective and document what I learn along the way.

Step 2: Use a New Tool to Design the User Interface

In 2017 Adobe released XD, an app specifically for creating user interfaces for websites and apps. From the little bit of it I’ve used, it seems to be an incredibly useful and functional app and one that I can see becoming the de facto standard for creating and prototyping interfaces. I’m excited to dive in and learn this tool.

Step 3: Assess my Development Toolbox

I want to take a look at the tools I use to do my actual development work. I’m both very comfortable with and a huge fan of all the tools I use. I know that Panic, the makers of Coda have Nova , a new code editor, on the horizon and I am very excited about that. And I recently decided to start using GitLab instead of Github. So those are a few changes on the horizon.

Step 4: Develop the Theme

Even though the Brettro WordPress theme won’t be available for anyone to use, I want to develop it to the standard that would get it approved for posting on the WordPress theme directory. Making sure it takes advantage of the newest features of WordPress is an important learning moment for me, as is understanding what elements must be and should be included in a theme. I plan to use the underscores theme as my foundation.

I also want to give some thought to what CSS framework I might use. My previous theme used Bourbon and Bourbon Neat. Recently the folks who created both frameworks discontinued development on Neat and are encouraging people to use modern, native CSS features like Grid and Flexbox. They’re smart to do so and I’m excited to dive into those two CSS features as well.

Documenting It All

Like I said in my original post about this, I plan on documenting the things I learn, the challenges I face and the victories I achieve while creating this new theme. So stay tuned…

Submitting to Subversion

This is the first in a four-part series about how Brettro integrated Subversion into its workflow. Part two will discuss the products Brettro uses to manage its SVN repositories, part three will discuss how Brettro uses SVN with ExpressionEngine and part four will talk about how Brettro uses SVN with WordPress.

About a year ago I tackled the task of integrating version control into my coding practices. I had spent a frustrating amount of time either recreating my code base as I started on new projects or backtracking and rewriting code when I would get a flash of inspiration to try something new. Also, I have both an iMac and a MacBook Pro and I use them interchangeably and wanted to be able to have the most up-to-date code on both of machine. Plus, it seemed all the pros were doing it—and since I consider myself one—I should join the gang.

Why Subversion?

Usually I do quite a bit of research, compare features and discover the value of one product over another. In choosing SVN, however, all I knew was that the WordPress Core Team used it. That, in and of itself, was a strong enough testimonial for me to dive right in.

Getting Started

When I know nothing about a topic, I buy a book, which is the first thing I did. I picked up Apress’s Practical Subversion, second edition, plopped down and started reading. I read chapters one, two and six completely as they provided an overview of version control in general, a “crash course” in Subversion and best practices in using Subversion. (By the way, Subversion is also known as SVN.)

Although clearly and plainly written, I was still confused as to the best way to get started and the best way to integrate SVN into my current workflow. I asked folks how they used it. I tweeted about my confusion consistently. I read blog entries and articles ad nauseum. I definitely hadn’t had my “ah ha!” moment yet.

Integrating SVN into My Workflow

As it turns out and after some starts, stops and stumbles, I realized that my current workflow wasn’t so much a “workflow” as much as it was a “jumble-of-tasks-that-stumbled-over-themselves” to get a project done. So I began to map out two workflows: one for managing Brettro web properties and one for creating and managing client web properties. This was really helpful as it:

  • Clarified the basic SVN concepts of trunks, tags and branches, and
  • Formalized how I create, produce and maintain website code.

Creating a Foundation: My HTML ‘Codebase’

With a better understanding of the basic SVN terminology and process, I decided to start with a fresh series of HTML, CSS and JavaScript files that would serve as the basis of all my website code from hereon out; and I’d call it my “codebase.” This seemed to be a great time to:

  • Make the switch from HTML 4/XHTML 1.1 to HTML5,
  • Adopt HTML5Boilerplate, a well-maintained framework established to ensure HTML5 code worked fairly well on legacy browsers (like any version of Internet Explorer before IE9),
  • Adopt 960.gs, another well-maintained framework established to ensure CSS consistency across browsers, and
  • Create the Brettro website design style manual.
With my basic HTML5 codebase complete, it was time to venture into the world of SVN. My goals at this point:
  • Be able to modify my HTML5 codebase as necessary for both my purposes and as both HTML5Boilerplate and 960.gs released improvements,
  • Create a branch of this codebase for my ExpressionEngine development,
  • Create a branch of this codebase for my WordPress development.

Repositories, Trunks, Branches, Tags and Working Copies

Let’s get some basic terminology out of the way:

  • Repository: the “repository” (or “repo”) is the container where your SVN-managed code is kept;
  • Trunk: the “trunk” is the main codebase of a project where most of your development will occur;
  • Branch: a “branch” is an offshoot of the trunk (do you see the tree metaphor?) whereby you might want to try out an idea or a feature that may not actually make it into production;
  • Tag: a “tag” is a copy of either the trunk or a branch frozen at a specific point in time, such as a release (the tree metaphor comes to a screeching halt here); a tag is never modified once it’s created;
  • Working Copy: the “working copy” is either the trunk or a branch copied to your computer from the repo to allow you to make changes.

After all this reading, contemplating, starting, stopping, deleting and creating, I settled on a basic structure that works for me. I’d like to think it’s a pretty common structure because it is based on my understanding of how WordPress organizes their SVN repository (and I like to use best practices because there’s no need to reinvent the wheel):


This is where I do my “next major version” development. For example, right after I finished my HTML5 codebase, HTML5Boilerplate released version 2 of their product. Rather than integrate those changes into version 1 of my codebase, I’ll integrate them into version 2 and do that development here.


When I imported my initial HTML5 codebase into my first SVN repo, I immediately created a branch and named it “1.0.” The “1.0” branch is my working copy of my HTML5 codebase code where I squash bugs and make minor fixes, then release them as dot releases. These releases are merged back down to the trunk so that they are included in the next major version codebase release.


After creating my “1.0” branch, I also created a “1.0” tag. This gives me a complete capture of version 1 of my HTML5 codebase so that I have a stable, working copy to use to create new projects.

Committing to SVN (See what I did there?)

By finally having an understanding of basic SVN techniques, by documenting my SVN structure and practices and by creating my first version controlled codebase, I was ready to take a deeper dive. Next I created branches of my codebase for both my WordPress codebase and my ExpressionEngine codebase. Stay tuned to the next three parts to learn what software I use and what workflow I use to manage sites built with either of these content management systems.

Brettro Re-Launches brettrospective.com

About nine months after starting this redesign in earnest, I am thrilled to announce the new brettrospective.com!

But nine months?!??

Yep. While it did not take an actual nine months to develop the design, write the code and move the content into WordPress, the Brettro website always took a back seat to both my client work and my full-time job.

The good news is, that in that time period, I really focused on developing better coding practices and on developing a solid codebase from which I can tweak and grow. I have integrated the 960 grid system and the HTML5 Boilerplate frameworks into a very solid HTML5 codebase. For customers, this means fast-loading, search-engine-optimized code. For me, it means quicker development times.

What’s Next?

While I have a solid code foundation and a great look-and-feel, this site is not yet complete. I still have a ton of content left to add. Brettro is not just a web design company, it also does identity, print and video work, plenty of which I have left to add to the Portfolio section. Stay tuned every week for updates.

Looking Back

Truly one of the most fun things about moving forward in any design is taking a look back at what was. So, of course, we’ll do that here. The images below are of the three previous Brettrospective website design. Laugh, smile and enjoy!

The third iteration of brettro.com
The homepage for the second iteration of brettro.com
The homepage for the original brettro.com