skip to Main Content

I have a paragraph with some text, a possible span, and some :before and :after psueodo-content:

<p>Normal content without a span</p>
<p>Additional content with a <span>span</span></p>

I would like to pace the pseudo-content at the very beginning and end of the paragraph:

«   Normal content without a span               »
«   Additional content with a             »

I though a simple grid with grid-template-columns would do it, but everything I try gets confused with the additional span element.

How can I get this effect? Should I be using flex instead?

Here is a sample snippet:

p {
  display: grid;
  width: 40em;
  grid-template-columns: 2rem ? ? 2rem;
  span {
    border: thin solid #ccc;
    padding: 0 0.25rem;
  }
  &:before {
    content: "«";
  }
  &:after {
    content: "»";
  }
}
<p>Normal content without a span</p>
<p>Additional content with a <span>span</span></p>

3

Answers


  1. You don’t need grid for that, a position: absolute for the arrows to stick them to the sides of <p> will fix your issue.

    Additionally, grid-template-columns: 2rem ? ? 2rem; has an invalid value, ? is an invalid value.

    p {
      position: relative;
      width: 40em;
      padding-left: 30px;
      span {
        border: thin solid #ccc;
        padding: 0 0.25rem;
      }
      &:before {
        content: "«";
        position: absolute;
        left: 0;
      }
      &:after {
        content: "»";
        position: absolute;
        right: 0;
      }
    }
    <p>Normal content without a span</p>
    <p>Additional content with a <span>span</span></p>
    Login or Signup to reply.
  2. Idealy, if changing your HTML structure is an option, wrapping the whole content in another layer would be advised. This case your paragragh won’t run into issues with arbitrary <span>s since they are in the same grid cell.

    article {
      display: grid;
      grid-template-columns: 2rem auto 2rem;
      width: 40em;
      align-items: center;
      
      span {
        border: thin solid #ccc;
        padding: 0 0.25rem;
      }
      
      &:before {
        content: "«";
      }
      
      &:after {
        content: "»";
      }
    }
    <article><p>Normal content without a span</p></article>
    <article><p>Additional content with a <span>span</span></p></article>

    If changing the structure is not possible. I would use flexbox, however this may cause an issue when the paragragh is wrapped into another line.

    p {
      display: flex;
      width: 40em;
      
      span {
        border: thin solid #ccc;
        padding: 0 0.25rem;
      }
      
      &:before {
        content: "«";
      }
      
      &:after {
        content: "»";
        margin-inline-start: auto;
      }
    }
    <p>Normal content without a span</p>
    <p>Additional content with a <span>span</span></p>

    You may also use grid together with display: contents, so the inner <span> is treated as a plain text. But that means you lose some styling options like borders or paddings etc. Also be aware of its coverage.

    p {
      display: grid;
      width: 40em;
      grid-template-columns: 2rem auto 2rem;
      span {
        display: contents;
        color: red;
        border: thin solid #ccc;
        padding: 0 0.25rem;
      }
      &:before {
        content: "«";
      }
      &:after {
        content: "»";
      }
    }
    <p>Normal content without a span</p>
    <p>Additional content with a <span>span</span></p>
    Login or Signup to reply.
  3. CSS and HTML Code

    1. CSS Modifications: We’ll switch the display property to flex and adjust the alignment and spacing using Flexbox utilities.
    p {
      display: flex;
      width: 40em;
      justify-content: space-between; /* Ensures the content is spaced out */
      align-items: center;
    }
    
    p::before, p::after {
      content: ""; /* Initially no content, it's set in specific pseudo-selectors */
    }
    
    p::before {
      content: "«"; /* Opening quote */
    }
    
    p::after {
      content: "»"; /* Closing quote */
    }
    
    span {
      border: thin solid #ccc;
      padding: 0 0.25rem;
    }
    
    /* Optional: If you want to make sure the quotes are always at the edges */
    p::before, p::after {
      flex-shrink: 0; /* Prevents shrinking */
    }
    
    1. HTML: The HTML remains the same as you have provided.
    <p>Normal content without a span</p>
    <p>Additional content with a <span>span</span></p>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search