bitty installation snippets examples documentation q&a

examples

page table of contents

  • The HTML for the "Lorem ipsum dignissim" content is contained directly on the page (which you can see in the "view html" details after the content).
  • The progressive enhancement loops through all the headers to add the table of contents sidebar.

Lorem ipsum dignissim

vel etiam lobortis. Pellentesque dictum proin dolor. Feugiat eget nec quis. Elit auctor felis tincidunt dapibus.

Erat etiam lorem faucibus in. Tristique convallis tortor. Magna tincidunt ac gravida luctus.

Elit magna

Enim platea sapien. Porttitor id ultrices. Etiam purus mattis ultricies lobortis gravida. Dolor laoreet consectetur malesuada ligula. Efficitur vitae elementum luctus.

Posuere sit tortor

Venenatis mollis fermentum magna massa. Semper curabitur metus dui. Risus maecenas fusce.

Blandit tempus convallis neque mauris. Mollis quis posuere laoreet. Aenean finibus est. Tincidunt morbi dolor eget. Tempus eget viverra.

Duis ac auctor

Habitasse scelerisque egestas. Vulputate venenatis laoreet ex. Congue lacinia venenatis. Efficitur orci tellus condimentum.

Ornare luctus

Eros quis venenatis metus. Risus convallis ligula phasellus accumsan. Pretium dolor leo faucibus.

Quam et mollis nec. Metus ultrices magna dapibus nibh auctor. Nisl dictumst commodo. Malesuada sollicitudin sodales tempor tincidunt dictumst.

Justo fusce

Ultrices dictumst et enim ornare habitasse. Phasellus porta hac. Praesent tortor venenatis. Tincidunt habitasse ac tincidunt imperdiet. Finibus lorem congue nisl hac porttitor.

Varius varius

Porta malesuada semper vulputate quam. Vivamus maximus nunc. Condimentum elit lectus ac urna. Dictum feugiat finibus porta.

Euismod vitae nisi scelerisque condimentum. Vehicula iaculis lacinia curabitur. Felis ex ex. Ac quam nullam mollis vehicula.

Quam venenatis

Dignissim iaculis hac at. Lectus velit gravida platea hac. Ut adipicing praesent vestibulum efficitur. Tincidunt nulla felis commodo tempus. Interdum dolor ullamcorper sapien diam elementum.

Dictum mollis duis. Nulla euismod mi quis vivamus. Malesuada iaculis metus velit.

Nullam odio

Porttitor sem lectus euismod venenatis leo. Augue non lectus nisl. Dignissim quisque id aliquam. Egestas duis metus.

Nunc convallis efficitur sapien. Commodo ut ut lectus. Tellus iaculis condimentum rutrum vivamus vehicula. Gravida varius in aliquet.

Condimentum urna non et. Nullam donec feugiat gravida commodo cras. Arcu libero faucibus commodo euismod. Volutpat tortor at faucibus blandit. Nulla imperdiet hac.

Venenatis diam donec bibendum. Egestas aenean faucibus sapien. Fringilla scelerisque ut vivamus.

Ultrices sit semper

Purus phasellus urna dictum nullam. Nunc euismod egestas tincidunt rhoncus. Tristique rutrum ex. At vestibulum congue. Diam nunc turpis.

Purus iaculis nisl eros vel aliquam. Ligula quis lorem vel. Donec sed phasellus amet sollicitudin.

Porttitor pretium dignissim

Lobortis magna elit quam. Convallis porttitor libero arcu. Cras feugiat eget commodo.

Risus metus laoreet dui nisl nibh. Semper dolor elit ex consectetur commodo. Molestie laoreet sagittis.

Maximus porttitor

Facilisis eu fringilla. Hac egestas ornare orci. Ipsum facilisis vulputate interdum maximus. Elementum maecenas sit sed id arcu. Ipsum purus dignissim.

Rhoncus semper

Quis dolor ullamcorper quam. Rutrum velit iaculis. Malesuada mattis eget praesent libero libero.

view html
<div class="wrapper">
  <div class="content default-flow">

  <h2>Lorem ipsum dignissim</h2>
  <p>vel etiam lobortis. Pellentesque dictum proin dolor. Feugiat eget nec quis. Elit auctor felis tincidunt dapibus.</p>
<p>
  Erat etiam lorem faucibus in. Tristique convallis tortor. Magna tincidunt ac gravida luctus.
</p>
<h3>
  Elit magna 
</h3>
<p>
  Enim platea sapien. Porttitor id ultrices. Etiam purus mattis ultricies lobortis gravida. Dolor laoreet consectetur malesuada ligula. Efficitur vitae elementum luctus.
</p>
<h4>
  Posuere sit tortor 
</h4>
<p>
  Venenatis mollis fermentum magna massa. Semper curabitur metus dui. Risus maecenas fusce.
</p>
<p>
  Blandit tempus convallis neque mauris. Mollis quis posuere laoreet. Aenean finibus est. Tincidunt morbi dolor eget. Tempus eget viverra.
</p>
<h4>
  Duis ac auctor
</h4>
<p>
  Habitasse scelerisque egestas. Vulputate venenatis laoreet ex. Congue lacinia venenatis. Efficitur orci tellus condimentum.
</p>
<h2>
  Ornare luctus 
</h2>
<p>
  Eros quis venenatis metus. Risus convallis ligula phasellus accumsan. Pretium dolor leo faucibus.
</p>
<p>
  Quam et mollis nec. Metus ultrices magna dapibus nibh auctor. Nisl dictumst commodo. Malesuada sollicitudin sodales tempor tincidunt dictumst.
</p>
<h2>
  Justo fusce
</h2>
<p>
  Ultrices dictumst et enim ornare habitasse. Phasellus porta hac. Praesent tortor venenatis. Tincidunt habitasse ac tincidunt imperdiet. Finibus lorem congue nisl hac porttitor.
</p>
<h3>
  Varius varius
</h3>
<p>
  Porta malesuada semper vulputate quam. Vivamus maximus nunc. Condimentum elit lectus ac urna. Dictum feugiat finibus porta.
</p>
<p>
  Euismod vitae nisi scelerisque condimentum. Vehicula iaculis lacinia curabitur. Felis ex ex. Ac quam nullam mollis vehicula.
</p>
<h3>
  Quam venenatis
</h3>
<p>
  Dignissim iaculis hac at. Lectus velit gravida platea hac. Ut adipicing praesent vestibulum efficitur. Tincidunt nulla felis commodo tempus. Interdum dolor ullamcorper sapien diam elementum.
</p>
<p>
  Dictum mollis duis. Nulla euismod mi quis vivamus. Malesuada iaculis metus velit.
</p>
<h4>
  Nullam odio 
</h4>
<p>
  Porttitor sem lectus euismod venenatis leo. Augue non lectus nisl. Dignissim quisque id aliquam. Egestas duis metus.
</p>
<p>
  Nunc convallis efficitur sapien. Commodo ut ut lectus. Tellus iaculis condimentum rutrum vivamus vehicula. Gravida varius in aliquet.
</p>
<p>
  Condimentum urna non et. Nullam donec feugiat gravida commodo cras. Arcu libero faucibus commodo euismod. Volutpat tortor at faucibus blandit. Nulla imperdiet hac.
</p>
<p>
  Venenatis diam donec bibendum. Egestas aenean faucibus sapien. Fringilla scelerisque ut vivamus.
</p>
<h2>
  Ultrices sit semper
</h2>
<p>
  Purus phasellus urna dictum nullam. Nunc euismod egestas tincidunt rhoncus. Tristique rutrum ex. At vestibulum congue. Diam nunc turpis.
</p>
<p>
  Purus iaculis nisl eros vel aliquam. Ligula quis lorem vel. Donec sed phasellus amet sollicitudin.
</p>
<h2>
  Porttitor pretium dignissim
</h2>
<p>
  Lobortis magna elit quam. Convallis porttitor libero arcu. Cras feugiat eget commodo.
</p>
<p>
  Risus metus laoreet dui nisl nibh. Semper dolor elit ex consectetur commodo. Molestie laoreet sagittis.
</p>
<h3>
  Maximus porttitor
</h3>
<p>
  Facilisis eu fringilla. Hac egestas ornare orci. Ipsum facilisis vulputate interdum maximus. Elementum maecenas sit sed id arcu. Ipsum purus dignissim.
</p>
<h3>
  Rhoncus semper
</h3>
<p>
  Quis dolor ullamcorper quam. Rutrum velit iaculis. Malesuada mattis eget praesent libero libero.
</p>

</div>
  <div data-r="toc"></div>
</div>

javascript

export const b = { init: "toc" };

function addLevel(heading, level, el) {
  if (level === 0) {
    const linkString = encodeURI(heading.innerText.trim().toLowerCase());
    const li = b.ce("li");
    li.innerHTML = `<a href="#${linkString}">${heading.innerText.trim()}</a>`;
    heading.id = linkString;
    el.appendChild(li);
  } else {
    let uls = b.qsa("li ul", el);
    if (uls.length === 0) {
      const ul = b.ce("ul");
      el.appendChild(ul);
      addLevel(heading, level - 1, ul);
    } else {
      addLevel(heading, level - 1, uls[uls.length - 1]);
    }
  }
}

export function toc(_, __, el) {
  const root = b.ce("ul");
  const contentEl = b.qs(".content");
  const headings = b.qsa("h2, h3, h4, h5, h6", contentEl);
  headings.forEach((heading) => {
    const level = parseInt(heading.tagName.replace("H", "")) - 2;
    addLevel(heading, level, root);
  });
  el.replaceChildren(root);
}

styles

.wrapper {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 0.9rem;
}

[data-r=toc] {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;

  ul {
    padding-left: 0.9rem;
  }
}