1

I have a two column grid.

main {
  max-width: 300px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-column-gap: 6.4rem;
}

h3::before {
  content: '';
  display: block;
  background-color: black;
  height: 1px;
  grid-column: 1 / span 2;
}
<main>
<h3>Heading blah</h3>
<p>Velluptiae dolupiet, im ea dolut que expercia sandionsed mo minvelibus modi occati sit autat quis ut fugitias maio. Moluptat.</p>
<h3>Heading blah</h3>
<p>Velluptiae dolupiet, im ea dolut que expercia sandionsed mo minvelibus modi occati sit autat quis ut fugitias maio. Moluptat.</p>
<h3>Heading blah</h3>
<p>Velluptiae dolupiet, im ea dolut que expercia sandionsed mo minvelibus modi occati sit autat quis ut fugitias maio. Moluptat.</p>
</main>
main {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-column-gap: 6.4rem;
}

With headings in the left column and body text in the right column.

Is it possible to have a border-top on my H3 headings (that display in the left column), that span both columns? Possibly using the before:: pseudo-element? So a horizontal line appears above the headings and goes across both columns. Like trying to insert a <hr> element before every H3 that spans both columns.

I've got the following:

h3::before {
  content: "";
  position: absolute;
  border-top: 1px solid;
  width: 100%;
  grid-column: 1 / -1;
}

But the border-top stretches outside the width of the containing element (main) and touches the right hand side of the browser window. Position: relative doesn't seem to work.

UPDATE

I've tried this, but the black line only stretches across one column.

h3::before {
    content: '';
    display: block;
    background-color: black;
    height: 1px;
    width: 100%;
    grid-column: 1 / -1;
}

UPDATE 2

I guess I need the CSS grid to treat the before:: pseudo-element as an actual element, in order for it to span more than one column? Is that possible? According to this 5 year old post pseudo-elements are treated as an element in grid. pseudo-element acting like a grid item in CSS grid But that isn't the case for me.

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
user2991837
  • 626
  • 1
  • 8
  • 17
  • Please update with some sample HTML so we may best assist you here – Mark Schultheiss Oct 27 '22 at 11:39
  • I made a wild probably incorrect guess and made a snippet, please update with the proper HTML here – Mark Schultheiss Oct 27 '22 at 11:43
  • The reason why it doesn't work is because your pseudo-element is a child of `

    `, therefore it is constrained to the dimensions of its parent, which only spans a single column.

    – Terry Oct 27 '22 at 12:03
  • But in this post the pseudo-element is treated as an element in the grid https://stackoverflow.com/questions/45599317/pseudo-element-acting-like-a-grid-item-in-css-grid – user2991837 Oct 27 '22 at 12:05
  • Can you change the layout to wrap the columns? Are there ever two paragraphs (or other markup) at that same level? Why not just give them both top borders? A few uncertainties here – Mark Schultheiss Oct 27 '22 at 12:06
  • I need the horizontal line to go across the gutter. There is a lot of content, but it always just

    and

    – user2991837 Oct 27 '22 at 12:08
  • I suppose a work around is to have no grid-column-gap. But add padding right to

    and padding left to

    to create a 'gap' and then add border top to both

    and

    – user2991837 Oct 27 '22 at 12:12
  • Is there something inherently problematic about just using a `
    `? ([Demo](https://jsfiddle.net/davidThomas/d4mn152r/))
    – David Thomas Oct 27 '22 at 12:13
  • I've got a lot of content and was hoping not to have to add elements such as
    to the html. But to come up with a CSS work around
    – user2991837 Oct 27 '22 at 12:20

3 Answers3

1

One approach is as follows, with explanatory comments in the CSS:

/* using custom properties to style aspects of the elements in order
   to position them appropriately and consistently: */
:root {
  --grid-padding-block-start: 0.5em;
  --grid-separator-height: 0.2rem;
}

main {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-column-gap: 6.4rem;
  /* added spacing between adjacent rows, using the custom property
     that also defines the height/block-size of the separator: */
  grid-row-gap: var(--grid-separator-height);
  /* I chose to use position relative on the <main> element, rather
     than the <h3>, in order to have the sizing and position relative
     to the grid-container, rather than the grid-item: */
  position: relative;
}

main > * {
  /* a padding isn't necessary; but if a padding is used (and only
     padding-block-start needs to have this property-value) then
     using the custom property allows the "separator" pseudo-
     element to be appropriately placed in the grid-row-gap spacing: */
  padding-block: var(--grid-padding-block-start);
}

h3::before {
  content: '';
  /* the element size on the inline-axis (left-to-right in latin languages),
     100% is relative to the <main> element, not the <h3>, as that's the first
     element ancestor with a non-static position: */
  inline-size: 100%;
  /* sizing the element along the block-axis, and this is why the
     grid-column-gap was also given this size: */
  block-size: var(--grid-separator-height);
  /* adjust to taste: */
  background-color: #000;
  /* to allow the pseudo-element to be sized in relation to the <main>, in terms
     of percentage: */
  position: absolute;
  /* moving the element zero along the x-axis, and 100% of its own block-axis size
     plus the size of the custom property (so that it occupies the grid-row-gap space,
     and multiplying that by -1 to ensure that it moves vertically 'up' into that space
     rather than further 'into' the <h3> element space: */
  translate: 0 calc(-1 * (100% + var(--grid-padding-block-start)));
}
<main>
  <h3>Heading One</h3>
  <p>Velluptiae dolupiet, im ea dolut que expercia sandionsed mo minvelibus modi occati sit autat quis ut fugitias maio. Moluptat.</p>
  <h3>Heading Two</h3>
  <p>Velluptiae dolupiet, im ea dolut que expercia sandionsed mo minvelibus modi occati sit autat quis ut fugitias maio. Moluptat.</p>
  <h3>Heading Three</h3>
  <p>Velluptiae dolupiet, im ea dolut que expercia sandionsed mo minvelibus modi occati sit autat quis ut fugitias maio. Moluptat.</p>
</main>

JS Fiddle demo.

References:

David Thomas
  • 249,100
  • 51
  • 377
  • 410
1

This can be done with some likely fragile CSS but I would suggest wrapping the blocks and setting a border there (set blocks (div?) all to display: grid

main {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-column-gap: 6.4rem;
}

main>p {
  margin-top: 2em;
}

h3::before {
  content: " ";
  height: 3px;
  width: 225%;
  grid-column: 1 / 2;
  display: inline-block;
  border-color: #ff0000;
  border-style: solid;
  border-width: 0;
  border-top-width: 0.2em;
}
<main>
  <h3>Heading blah</h3>
  <p>Velluptiae dolupiet, im ea dolut que expercia sandionsed mo minvelibus modi occati sit autat quis ut fugitias maio. Moluptat.</p>
  <h3>Heading blah</h3>
  <p>Velluptiae dolupiet, im ea dolut que expercia sandionsed mo minvelibus modi occati sit autat quis ut fugitias maio. Moluptat.</p>
  <h3>Heading blah</h3>
  <p>Velluptiae dolupiet, im ea dolut que expercia sandionsed mo minvelibus modi occati sit autat quis ut fugitias maio. Moluptat.</p>
</main>
Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100
1

One line of code can do it using border-image

main {
  max-width: 300px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-column-gap: 6.4rem;
  overflow: hidden;
}

h3 {
  /* 5px = thickness 
     15px = distance from the top
  */
  border-image: linear-gradient(180deg,#000 5px,#0000 0) fill 0//15px 100vw;
}
<main>
<h3>Heading blah</h3>
<p>Velluptiae dolupiet, im ea dolut que expercia sandionsed mo minvelibus modi occati sit autat quis ut fugitias maio. Moluptat.</p>
<h3>Heading blah</h3>
<p>Velluptiae dolupiet, im ea dolut que expercia sandionsed mo minvelibus modi occati sit autat quis ut fugitias maio. Moluptat.</p>
<h3>Heading blah</h3>
<p>Velluptiae dolupiet, im ea dolut que expercia sandionsed mo minvelibus modi occati sit autat quis ut fugitias maio. Moluptat.</p>
</main>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • I will shortly have an article about this kind of trick and will link it when it's live – Temani Afif Oct 27 '22 at 14:41
  • Sorry I think this is relevant: the
    has a max-width and is centred on the screen – so the 100vw doesn't work. I don't want the line to extend out past the
    element. I've updated my code. Any work around?
    – user2991837 Oct 27 '22 at 15:48
  • @user2991837 add overflow:hidden to main – Temani Afif Oct 27 '22 at 16:13
  • That's cool! Two lines of code! – user2991837 Oct 28 '22 at 16:09
  • I'm trying to understand this solution, by breaking it down into smaller parts (using the border-image long hand) but can't get it to work. Can you help me? I've updated my opening post – user2991837 Nov 08 '22 at 15:29
  • @user2991837 please don't keep adding more questions inside your question. Use the devtools to get the longhand version, In any browser you can, with a click, extend any shorthand property – Temani Afif Nov 08 '22 at 15:44
  • Thank you. That works. Wasn't aware that I could do that. Thank you – user2991837 Nov 08 '22 at 15:51