1

Given a standard well working Drop Caps styler in pure CSS.

    /* Automatic CSS Drop Caps on First Letter on the First Paragraph */

    article:first-of-type p:first-of-type:first-letter{
      font-size: 3em;
      margin: 0 0 0 0;
      padding: 0 0 0 0;
      line-height: 1em;
      float: left;
    }

Althouth most pages have a big chunky first paragraph, some pages start with just one line of text as their first paragraph. The automatic drop cap makes an odd looking first line with a huge first letter followed by just a couple of words behind it.

enter image description here

Is there a way to narrow down the automatic drop caps to only paragraphs with more than one line or say a minimum of 20 words?

Sam
  • 15,254
  • 25
  • 90
  • 145
  • Not with CSS, no. – Paulie_D Jun 27 '22 at 09:44
  • @Paulie_D even with JS this would be super difficult – Simp4Code Jun 27 '22 at 09:46
  • Since the 'more than one line' alters with container/viewport dimensions I think you'll need a few lines of Javascript. Is having some JS useful to you or is it not allowed? – A Haworth Jun 27 '22 at 12:53
  • @AHaworth thanks for your suggestion/help. If impossible with CSS in 2022~2030 (am afraid so by Pauli_D's three word short negation) then yess a JS solution is most welcome as an answer to solve this. In effect the whole CSS rule woulld not be applied to single line rendered first paragraphs that come first in article element. Or even better: those exceptionally short one line paragraphs would have their own css styling applied of say `.oneLineDropCapAlternative`. – Sam Jun 27 '22 at 13:40

1 Answers1

1

We need to find out whether the paragraph is more than one line. This snippet uses a slightly hacky method of writing a single line (one character) into the innerHTML and measuring its height.

If the actual paragraph is higher than that then a class of DropCap is set. Otherwise a class of oneLineDropCapAlternative is set.

article:first-of-type p.DropCap:first-of-type:first-letter {
  font-size: 3em;
  margin: 0 0 0 0;
  padding: 0 0 0 0;
  line-height: 1em;
  float: left;
}
<div>
  <h2>An article with a long first paragraph</h2>
  <article>
    <p>Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello
      Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello </p>
  </article>
</div>
<div>
  <h2>An article with a short first paragraph</h2>
  <article>
    <p>Hello</p>
  </article>
</div>
<div>
  <h2>An article with a first paragraph that is long on narrower viewports</h2>
  <article>
    <p>Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello</p>
  </article>
</div>
<script>
  function init() {
    const ps = document.querySelectorAll('article:first-of-type p:first-of-type');
    ps.forEach(p => {
      const h = window.getComputedStyle(p).height;
      const savedInnerHTML = p.innerHTML;
      p.innerHTML = 'g';
      const tempH = window.getComputedStyle(p).height;
      if (h.replace('px', '') >= (1.1 * tempH.replace('px', ''))) {
        p.classList.remove('oneLineDropCapAlternative');
        p.classList.add('DropCap');

      } else {
        p.classList.remove('DropCap');
        p.classList.add('oneLineDropCapAlternative');
      }
      p.innerHTML = savedInnerHTML
    });
  }
  window.onload = init;
  window.onresize = init;
</script>
A Haworth
  • 30,908
  • 4
  • 11
  • 14
  • Excellent elaboration! It works beautifully. I updated your answer and added the extra CSS, very nice that we now have even a graceful fallover to style non-common paragraphs if we want to: https://jsfiddle.net/oyte3c17/ – Sam Jun 27 '22 at 15:13