JSFiddle - React, Tailwind, and code Playground

by Laurent Dufour

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<section class="container-fluid py-5">
  <div class="container-fluid">
    <div class="row">
      <div class="col-12">
        <h2 class="divider-h2 color1 pt-3 pb-5 fs-3">Lorem ipsum</h2>
        <div class="row row-cols-1 row-cols-lg-4 g-4">

          <div class="col">
            <div class="card shadow h-100" data-annee="A2007">
              <div class="position-absolute top-0 start-0 ms-4 mb-1">
                <p class="fs-10 text-white opacity-75"><b> 2007 </b></p>
              </div>
              <img src="tccimg/annee-2007.jpg" class="card-img-top" alt="">
              <div class="card-body">
                <h2 class="fs-5 py-2 text-center">Lorem ipsum dolor sit amet consectetur.</h2>
                <p class="text-center py-2"><button onclick="readMore('A2007')" class="btn btn-outline-n btn-sm myBtn">+ Afficher plus</button></p>
                <article class="vide arti">
                  <p>Lorem, ipsum, dolor sit amet consectetur adipisicing elit. Blanditiis sit in odio optio repellendus, aliquam veritatis distinctio ipsa fugiat, maxime reiciendis nam, aspernatur atque temporibus iure dolor cupiditate, perferendis. Quae.</p>
                  <div class="dots"></div>
                  <div class="more" style="display: none;">
                    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Non officia minus nesciunt quisquam sed voluptates laborum, illum nihil dolore, consequuntur illo quod. Saepe eveniet quaerat voluptatum, distinctio tempore porro asperiores.</p>
                  </div>
                </article>
              </div>
            </div>
          </div>

          <div class="col">
            <div class="card shadow h-100"...

CSS

.arti {
  position: relative;
}

.arti:after {
  position: absolute;
  bottom: 0;
  height: 100%;
  width: 100%;
  content: "";
  background: linear-gradient(to top,
     
rgba(255,255,255, 1) 20%,
     
rgba(255,255,255, 0) 80%
  );
  pointer-events: none; /* so the text is still selectable */
}

JavaScript

function readMore(annee) {
    let dots = document.querySelector(`.card[data-annee="${annee}"] .dots`);
    let moreText = document.querySelector(`.card[data-annee="${annee}"] .more`);
    let btnText = document.querySelector(`.card[data-annee="${annee}"] .myBtn`);
    let article = document.querySelector(`.card[data-annee="${annee}"] .vide`);

    if (dots.style.display === "none") {
        dots.style.display = "block";
        btnText.textContent = "+ Afficher plus";
        moreText.style.display = "none";
        $( "article" ).addClass( "arti" );
    } else {
        dots.style.display = "none";
        btnText.textContent = "- Afficher moins";
        moreText.style.display = "block";
        $( "article" ).removeClass( "arti" );
    }
}