You're using an outdated browser

For a better experience, keep your browser up to date. Check here for the latest version.


Numbered pages and sections

Steffen Burzlaff

Steffen Burzlaff Last update: Jul 27, 2018

There are a couple of use-cases to have numbered pages and sections in all parts of your documentation.

The most common use case is about table of contents. When you display a table of contents using a numbered list of all chapters of your documentation, you want the user be able to refer to these chapters as numbers. The recipe below explains how to implement this. 


The examples below use the existing page tree of the default Webhelp theme, delivered with Scroll Viewport.

If you need to implement this in a theme made from scratch, you may need to omit or change some of the classes used in the CSS. For example .ht-content and #ht-sidebar are specific to the Webhelp theme.

When implementing this recipe, you will be able to automatically number all sections in the page tree and content, starting from the second tier - of course, you can configure that in the code - see line 17.

Add the following code to your page.vm

#macro( ancestorTree $items )
  	#set ($headerIds = [])
  	<style> body { counter-increment:
	#foreach ($item in $items)
          #set ($it = $velocityCount)
          #foreach($sibling in $item.parent.children)
          	#if ($sibling.title == $item.title)
      			header$it $velocityCount
      			#set($invisible = $headerIds.add("header$it"))
    ; } </style>

#set ($ancestors = $page.ancestors)
#if($ancestors.size() > 0)
	#set ($invisible = $ancestors.remove(0)) ## removes top-most space as section
	#set ($invisible = $ancestors.remove(0)) ## removes 2nd level of sections - repeat or remove this line until you have the desired numbering
	#set ($invisible = $ancestors.add($page))
    	*##foreach($headerId in $headerIds) counter($headerId) "." #end#*
 	.ht-content h1::before {
      content: $counterHtml;
    body {counter-reset: h2}
    .ht-content h2 {counter-reset: h3}
    .ht-content h3 {counter-reset: h4}
    .ht-content h4 {counter-reset: h5}
    .ht-content h5 {counter-reset: h6}

    .ht-content h2::before {counter-increment: h2; content: $counterHtml counter(h2) ". "}
    .ht-content h3::before {counter-increment: h3; content: $counterHtml counter(h2) "." counter(h3) ". "}
    .ht-content h4::before {counter-increment: h4; content: $counterHtml counter(h2) "." counter(h3) "." counter(h4) ". "}
    .ht-content h5::before {counter-increment: h5; content: $counterHtml counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) ". "}
    .ht-content h6::before {counter-increment: h6; content: $counterHtml counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) "." counter(h6) ". "}

Add the following to your stylesheet:

#ht-sidebar ul ul {
  counter-reset: section;
  list-style-type: none;

#ht-sidebar  ul ul li::before {
  counter-increment: section;
  content: counters(section,".") ". ";
  padding: 5px;
  float: left;

#ht-sidebar li {
  white-space: nowrap;

#ht-sidebar .ht-pages-nav ul a {
  display: inline-block;


If you are using the webhelp theme, remove the class .ht-content or replace it with the class your content container has.

Same for the stylesheet additions: We are using the ID from the webhelp theme - #ht-sidebar. If you are using your own sidebar, please use the correct class instead.

Now you should be able to see the numbers going through all pages and numbered sections, so you can easily refer to them.

We use cookies to create a secure and effective browsing experience for our website visitors and to understand how you use our site (i.e. Google Analytics). For more information: click here.