title: Using PHP substr() and strip_tags() while retaining formatting and without breaking HTML
body: <p>I have various HTML strings to cut to 100 characters (of the stripped content, not the original) without stripping tags and without breaking HTML.</p>
  
  <p><strong>Original HTML string</strong> (288 characters):</p>
  
  <pre><code>$content = "&lt;div&gt;With a &lt;span class='spanClass'&gt;span over here&lt;/span&gt; and a
  &lt;div class='divClass'&gt;nested div over &lt;div class='nestedDivClass'&gt;there&lt;/div&gt;
  &lt;/div&gt; and a lot of other nested &lt;strong&gt;&lt;em&gt;texts&lt;/em&gt; and tags in the air
  &lt;span&gt;everywhere&lt;/span&gt;, it's a HTML taggy kind of day.&lt;/strong&gt;&lt;/div&gt;";
  </code></pre>
  
  <p><em>Standard trim:</em> Trim to 100 characters and HTML breaks, stripped content comes to ~40 characters:</p>
  
  <pre><code>$content = substr($content, 0, 100)."..."; /* output:
  &lt;div&gt;With a &lt;span class='spanClass'&gt;span over here&lt;/span&gt; and a
  &lt;div class='divClass'&gt;nested div ove... */
  </code></pre>
  
  <p><em>Stripped HTML:</em> Outputs correct character count but obviously looses formatting:</p>
  
  <pre><code>$content = substr(strip_tags($content)), 0, 100)."..."; /* output:
  With a span over here and a nested div over there and a lot of other nested
  texts and tags in the ai... */
  </code></pre>
  
  <p><em>Partial solution:</em> using HTML Tidy or purifier to close off tags outputs clean HTML but 100 characters of HTML not displayed content.</p>
  
  <pre><code>$content = substr($content, 0, 100)."...";
  $tidy = new tidy; $tidy-&gt;parseString($content); $tidy-&gt;cleanRepair(); /* output:
  &lt;div&gt;With a &lt;span class='spanClass'&gt;span over here&lt;/span&gt; and a
  &lt;div class='divClass'&gt;nested div ove&lt;/div&gt;&lt;/div&gt;... */
  </code></pre>
  
  <p><em>Challenge:</em> To output clean HTML and <em>n</em> characters (excluding character count of HTML elements):</p>
  
  <pre><code>$content = cutHTML($content, 100); /* output:
  &lt;div&gt;With a &lt;span class='spanClass'&gt;span over here&lt;/span&gt; and a
  &lt;div class='divClass'&gt;nested div over &lt;div class='nestedDivClass'&gt;there&lt;/div&gt;
  &lt;/div&gt; and a lot of other nested &lt;strong&gt;&lt;em&gt;texts&lt;/em&gt; and tags in the
  ai&lt;/strong&gt;&lt;/div&gt;...";
  </code></pre>
  
  <p>Similar Questions</p>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/2105169/how-to-clip-html-fragments-without-breaking-up-tags">How to clip HTML fragments without breaking up tags</a></li>
  <li><a href="https://stackoverflow.com/questions/830283/cutting-html-strings-without-breaking-html-tags">Cutting HTML strings without breaking HTML tags</a></li>
  </ul>