skip to Main Content

can you please tell me what would be the best way to have a paragraph(s), that is decorated from sides with semi-transparent images?

This is how it looks like from the designer in Figma.
enter image description here

My current solution using :before and :after is flaky https://jsfiddle.net/tosinek/08bmo7uy/
It does overflow to the elements around (eg blocking the buttons). While I can probably keep on improving this, would you still recommend this approach?

// the positioning of the tilted rectangular element is a pain too
 .wide-container.with-image::before {
    content: '';
    position: absolute;
    top: -230px;
    left: 0px;
    width: 341px;
    height: 675px;
    background-image: url('https://res.cloudinary.com/holabiolabs/image/upload/f_auto/pages/jumbo-left.png');
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
    z-index: 100;
  }

Other solutions I can think of:

  1. ask the designer to give me better shapes of the decorations (so they won’t be rectangular but will nicely fit into the corners). So they won’t overflow.

  2. create a component (SvelteJS) that will consist of divs and images, providing the texts and main image as slots. That way, at least, I won’t be limited to two decorations (before and after). It seems to be more complicated than just adding a bunch of classes.

  3. create a complex SVG that would do the same thing, but that seems to be way too complicated and also will likely cause issues with texts inside.

Existing code:

* {
  color: white;
}

.above {
  background-color: blue;
}

.p-2 {
  padding: 2rem;
}

.container {
  max-width: 700px;
  margin: 0 auto;
  width: 100%;
  padding-left: 30px;
  padding-right: 30px;
}

.wide-container.with-image {
  margin-top: 2rem;
  background: linear-gradient(0deg, rgba(30, 27, 70, 0.9), rgba(30, 27, 70, 0.9)),
    url(https://res.cloudinary.com/holabiolabs/image/upload/f_auto,q_90,w_1997,h_600,c_fill/pages/12.jpg);
  background-size: cover;
  background-position: center;
  position: relative;
}

.wide-container.with-image::before {
  content: '';
  position: absolute;
  top: -230px;
  left: 0px;
  width: 341px;
  height: 675px;
  background-image: url('https://res.cloudinary.com/holabiolabs/image/upload/f_auto/pages/jumbo-left.png');
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  z-index: 100;
}

.wide-container.with-image::after {
  content: '';
  position: absolute;
  bottom: -200px;
  right: 0px;
  width: 409px;
  height: 721px;
  background-image: url('https://res.cloudinary.com/holabiolabs/image/upload/f_auto/pages/jumbo-right.png');
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  z-index: 100;
}
<div class="above p-2">
  Something above that gets covered up
</div>

<div class="wide-container with-image p-2">
  <div class="container">
    <h2>Heading </h2>
    <p>item 1</p>
    <p>item 2</p>
    <p>item 3</p>
  </div>
</div>

2

Answers


  1. How much I can understand your problem I have written a solution for you. Please go thru it. And still you face any problem Please ping me.

    <style>
    .container {
        position: relative;
        height: 400px;
        width: 100%;
        background-image: url('https://img.phonandroid.com/2021/11/comment-reduire-taille-poids-image.jpg');
        background-size: cover;
        background-position: center;
        background-repeat: no-repeat;
      }
      .overlay {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 400px;
        background-color: rgba(0, 0, 105, 0.7);
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        grid-gap: 10px;
        padding: 20px;
      }
      .overlay p {
        color: white;
    border:1px soild white;
      }
      
    </style>
        <div class="container">
          <div class="overlay">
            <p>Paragraph 1</p>
            <p>Paragraph 2</p>
            <p>Paragraph 3</p>
          </div>
        </div>
    
    Login or Signup to reply.
  2. Your question, as I understand it, is:

    How can I use pseudo-elements to position the graphics visibly in the parent element, while enabling text-interaction?

    If I’m correct in that interpretation, there are two (simple) ways of achieving the desired result.

    1. Using isolation: isolate, along with z-index, or
    2. pointer-events: none.

    To demonstrate the use of isolation: isolate, the code is below with explanatory comments in the code itself:

    * {
      color: white;
    }
    
    .above {
      background-color: blue;
    }
    
    .p-2 {
      padding: 2rem;
    }
    
    .container {
      max-width: 700px;
      margin: 0 auto;
      width: 100%;
      padding-left: 30px;
      padding-right: 30px;
    }
    
    /* all changes follow this point: */
    .wide-container.with-image {
      margin-top: 2rem;
      background:
        /* here, for personal preference, I switched to using
           CSS Color Module level 4 syntax, white-space separated
           numbers for r, g, b, and with a slash to separate the
           alpha; as part of this I also switched to rgb() rather
           than rgba() for easier color updates in future: */
        linear-gradient(
          0deg,
          rgb(30 27 70 / 0.9),
          rgb(30 27 70 / 0.9)
        ),
        url(https://res.cloudinary.com/holabiolabs/image/upload/f_auto,q_90,w_1997,h_600,c_fill/pages/12.jpg);
      background-size: cover;
      background-position: center;
      position: relative;
      /* added this line, which creates a stacking context that enables
         descendant elements to be positioned with negative z-index
         while still appearing "in front of,* or "above," the parent's
         background: /
      isolation: isolate;
      /* arbitrary z-index to position this element in the z-index stack,
         in order to have its descendants positioned relative that
         z-index position: */
      z-index: 10;
    }
    
    /* moving all repeated code for the pseudo-elements into this ruleset: */
    .wide-container.with-image::before,
    .wide-container.with-image::after {
      /* sizing the element in order that its width is 1.5 times the
         height (width could be used instead, aspect-ratio is simply
         my own preference): */
      aspect-ratio: 1.5;
      content: '';
      /* setting the background-image, and background-position, the
         the two properties that are specific to each element to use
         CSS custom properties, which are defined below: */
      background-image: var(--background-image);
      background-position: var(--background-position);
      background-repeat: no-repeat;
      /* I sized the background to match the size of the pseudo-element,
         though you may wish to adjust that: */
      background-size: 100% 100%;
      /* defining one dimension in order that the aspect-ratio can
         be calculated: */
      height: 100%;
      position: absolute;
      /* positioning both pseudo-elements on the same 'plane' in the
         z-index "stack" (adjust to preference if this doesn't work
         for your use-case/requirements): */
      z-index: -1;
    }
    
    .wide-container.with-image::before {
      /* defining the CSS custom properties for each element: */
      --background-image: url('https://res.cloudinary.com/holabiolabs/image/upload/f_auto/pages/jumbo-left.png');
      --background-position: 0 0;
      /* positioning the pseudo-element itself using inset, this
         positions the pseudo-element:
         0 distance from the top,
         auto distance (as if the value was never set)
         from the right,
         auto distance for the bottom (to allow for
         non-100% sizing), and
         0 distance from the left: */
      inset: 0 auto auto 0;
    }
    
    .wide-container.with-image::after {
      --background-image: url('https://res.cloudinary.com/holabiolabs/image/upload/f_auto/pages/jumbo-right.png');
      --background-position: 100% 100%;
      inset: auto 0 0 auto;
    }
    <div class="above p-2">
      Something above that gets covered up
    </div>
    
    <div class="wide-container with-image p-2">
      <div class="container">
        <h2>Heading </h2>
        <p>item 1</p>
        <p>item 2</p>
        <p>item 3</p>
      </div>
    </div>

    JS Fiddle demo.

    Of course, pointer-events: none prevents an element from receiving any mouse-events (so no :hover, :focus, :active…) which prevents the pseudo-elements from interfering with actions taken on the text of other elements that may otherwise be positioned "behind" those elements:

    * {
      color: white;
    }
    
    .above {
      background-color: blue;
    }
    
    .p-2 {
      padding: 2rem;
    }
    
    .container {
      max-width: 700px;
      margin: 0 auto;
      width: 100%;
      padding-left: 30px;
      padding-right: 30px;
    }
    
    .wide-container.with-image {
      margin-top: 2rem;
      background: linear-gradient(0deg, rgba(30, 27, 70, 0.9), rgba(30, 27, 70, 0.9)), url(https://res.cloudinary.com/holabiolabs/image/upload/f_auto,q_90,w_1997,h_600,c_fill/pages/12.jpg);
      background-size: cover;
      background-position: center;
      position: relative;
    }
    
    /* the only change I've made: */
    .wide-container.with-image::before,
    .wide-container.with-image::after {
      /* prevents the matched elements from taking part in
         any/all mouse-events: */
      pointer-events: none;
    }
    
    .wide-container.with-image::before {
      content: '';
      position: absolute;
      top: -230px;
      left: 0px;
      width: 341px;
      height: 675px;
      background-image: url('https://res.cloudinary.com/holabiolabs/image/upload/f_auto/pages/jumbo-left.png');
      background-size: contain;
      background-repeat: no-repeat;
      background-position: center;
      z-index: 100;
    }
    
    .wide-container.with-image::after {
      content: '';
      position: absolute;
      bottom: -200px;
      right: 0px;
      width: 409px;
      height: 721px;
      background-image: url('https://res.cloudinary.com/holabiolabs/image/upload/f_auto/pages/jumbo-right.png');
      background-size: contain;
      background-repeat: no-repeat;
      background-position: center;
      z-index: 100;
    }
    <div class="above p-2">
      Something above that gets covered up
    </div>
    
    <div class="wide-container with-image p-2">
      <div class="container">
        <h2>Heading </h2>
        <p>item 1</p>
        <p>item 2</p>
        <p>item 3</p>
      </div>
    </div>

    JS Fiddle demo.

    References:

    Bibliography:

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search