1

I am faced with the CSS implementation of a multi-column layout that aligns the first line of the second column, which may have various font sizes, to the second line of the first column. Like this:

Two examples of a two-column layout, with a visual guide to illustrate the desired baseline alignment.

(The colored background and highlighted baseline are for illustration purposes.)

The first column will always start with two lines of known typeface, line height, and weight.

The second column may consist of headings, paragraphs, images etc. It will start either with a paragraph or a h2.

Here is a minimal reproducible example:

div.column {
  width: 30%;
  float:left;
}

p.highlight {
  font-weight:bold;
}
<div class="column">
  <p class="highlight">
    Line 1 with colon:<br>
    Line 2 should be aligned to
  </p>
</div>
<div class="column">
  <p>
    This is a paragraph, whose fist line should align to the second line on the left.
  </p>
  <p>
    Followed by further paragraphs.
  </p>
</div>
<div class="column">
  <h2>Larger h2 should still align.</h2>
  <p>
    Followed by further paragraphs.
  </p>
</div>

The second column will be under CMS control and might be subject to change by editors at any time, i.e. start with a paragraph in the first iteration, but might be changed to a h2 later, and maybe back.

The editors should preferably only use plain h2 and p tags in the second column, without any requirement for inline CSS. Assigning a class like <p class="top_align"> or similar would probably be okay.

Constraints:

  • I have to solve it in pure CSS, I can not use any JavaScript nor CSS preprocessors.
  • The solution must be pixel-perfect across desktop devices, desktop operating systems and desktop browsers. Mobile layout is not an issue.
  • The solution still has to work when zooming in, up to a level of 300 %.

I have done quite some CSS work, but never this kind of cross-column baseline alignment. I know there are some baseline-related rules in CSS, but I have neither seen nor found any reference techniques to baselines outside the current container.

My line of thought is that the second column somehow would have to know the distance of the second baseline to the top of the first column, and then adjust the top padding of the first paragraph or the heading, given its line height, to match that distance.

Is that even possible, given my constraints?

How would I start to tackle this?

fbmd
  • 730
  • 6
  • 22
  • How are the columns created? Please give a runnable snippet that shows your html structure and relevant CSS. See https://stackoverflow.com/help/minimal-reproducible-example – A Haworth Aug 21 '23 at 11:41
  • @AHaworth I have added a runnable snippet as a minimal reproducible example. – fbmd Aug 21 '23 at 12:01
  • 1
    Pretty sure this is not possible. However this might help. https://stackoverflow.com/questions/56711501/align-child-elements-of-different-blocks – Paulie_D Aug 21 '23 at 12:34

3 Answers3

3

This can be done quite simply with inline-block and inline-table.

Inline-block aligns the last line of its contents, and inline-table (via table-cell) aligns its first line.

(There's a proposed CSS property called "baseline-source" that will control this, but the browser support right now is limited to Chromium.)

div.column {
  width: 30%;
}

.column {
  display: inline-block;
}
.column:nth-child(n + 2) {
  display: inline-table;
}

p.highlight {
  font-weight:bold;
}
<div class="column">
  <p class="highlight">
    Line 1 with colon:<br>
    Line 2 should be aligned to
  </p>
</div>
<div class="column">
  <p>
    This is a paragraph, whose fist line should align to the second line on the left.
  </p>
  <p>
    Followed by further paragraphs.
  </p>
</div>
<div class="column">
  <h2>Larger h2 should still align.</h2>
  <p>
    Followed by further paragraphs.
  </p>
</div>
Alohci
  • 78,296
  • 16
  • 112
  • 156
  • Beautiful and clever, but I suppose it would break should I ever be required to put something in column 1, below line 2, as it aligns to the very bottom line of this column? – fbmd Aug 21 '23 at 14:38
  • @fbmd - Indeed it would. But your requirement explicitly ruled that out. "The first column will always consist of two lines of known typeface, line height, and weight." – Alohci Aug 21 '23 at 14:54
  • I see. I corrected the wording in the question, thank you. Still, the `inline-block` vs. `inline-table` alignment rules, and the link to `baseline-source` are gold. – fbmd Aug 21 '23 at 18:59
1

You can do it but its a bit of a faff. You basically have to make sure you set line-heights and margins consistently. Using CSS Custom Properties makes this a little easier.

:root {
  --base-font-size: 1rem;
  --base-line-height: 1.5rem;
}

.demo {
  display:grid;
  grid-template-columns: 1fr 1fr 1fr;
  margin:0;
  gap:10px;
}


div.column {
  padding:var(--base-line-height);
  background:beige;
  font-size:var(--base-font-size);
  line-height:var(--base-line-height);
  background-image:repeating-linear-gradient(to bottom, transparent 0 calc(var(--base-line-height) - 1px), #ccc calc(var(--base-line-height) - 1px) var(--base-line-height))
}

p.highlight {
  font-weight:bold;
}

div.column p {
  margin:0;
  margin-top:var(--base-line-height);
}

div.column p.highlight {
  margin-top:0rem;
}

div.column h2 {
  margin:0;
  font-size:calc(var(--base-font-size) * 1.5);
  line-height:var(--base-line-height);
  margin-top:var(--base-line-height);
}
<div class="demo">
<div class="column">
  <p class="highlight">
    Line 1 with colon:<br>
    Line 2 should be aligned to
  </p>
</div>
<div class="column">
  <p>This is a paragraph, whose first line should align to the second line on the left.</p>
  <p>Followed by further paragraphs.</p>
</div>
<div class="column">
  <h2>Larger h2 should still align.</h2>
  <p>Followed by further paragraphs.</p>
</div>
</div>
Moob
  • 14,420
  • 1
  • 34
  • 47
  • Accepted as the apparently most flexible approach. – fbmd Aug 21 '23 at 14:46
  • 1
    This should become easier, and less of a “faff,” once the [`rlh`](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units) unit becomes [more widely available](https://caniuse.com/mdn-css_types_length_rlh). – David Thomas Aug 22 '23 at 19:19
0

You can make an element span 2 lines by using the line-height property. If you set it to 2em, it will be as height as 2 lines. Remember to reset default paddings and margins.

/* reset default margin */
p, h2 {
  margin: 0;
}


/* setting the line height of the first element on the right side */
.right :first-child {
  line-height: 2em;
}



/* just for visualizsation purpose */
.container {
  display: flex;
}

.inner-container {
  border: 2px dashed red;
  padding: 0.5em;
}
<div class="container">
  <div class="inner-container left">
    <p>First Line</p>
    <p>Second Line</p>
  </div>
  <div class="inner-container right">
    <h2>Headline</h2>
  </div>
</div>
tacoshy
  • 10,642
  • 5
  • 17
  • 34
  • But that would not work for a paragraph in the second column, would it? I would not want to mess with its line height, as in my understanding that would affect the whole paragraph. – fbmd Aug 21 '23 at 12:03