Comment insérer des éléments pliables dans la mise en page Flexbox
P粉366946380
P粉366946380 2024-03-19 23:20:59
0
2
346

J'ai une mise en page flexbox avec une image enroulée autour et je souhaite afficher des informations lorsque l'on clique sur l'image. Les informations doivent apparaître entre la ligne contenant l'image et la ligne directement en dessous, sans déplacer la « colonne ». C'est le type d'effet que je souhaite : http://olmenta.altervista.org (quand vous cliquez sur un livre).

C'est ce que j'ai fait : https://jsfiddle.net/fabhpnw9/3/

var coll = document.getElementsByClassName("rectangle");
var i;

for (i = 0; i < coll.length; i++) {
  coll[i].addEventListener("click", function() {
    this.classList.toggle("active");
    var content = this.nextElementSibling;
    if (content.style.display === "block") {
      content.style.display = "none";
    } else {
      content.style.display = "block";
    }
  });
}
.flex-container {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: center;
}

.rectangle {
  width: 200px;
  height: 50px;
  background-color: red;
  cursor: pointer;
}

.text {
  display: none;
  position: absolute;
}
<div class="flex-container">
  <div class="flex-item">
    <div class="rectangle"></div>
    <div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit</div>
  </div>
  <div class="flex-item">
    <div class="rectangle"></div>
    <div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit</div>
  </div>
  <div class="flex-item">
    <div class="rectangle"></div>
    <div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit</div>
  </div>
  <div class="flex-item">
    <div class="rectangle"></div>
    <div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit</div>
  </div>
  <div class="flex-item">
    <div class="rectangle"></div>
    <div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit</div>
  </div>
  <div class="flex-item">
    <div class="rectangle"></div>
    <div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit</div>
  </div>
  <div class="flex-item">
    <div class="rectangle"></div>
    <div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit</div>
  </div>
  <div class="flex-item">
    <div class="rectangle"></div>
    <div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit</div>
  </div>
</div>

La "colonne" bouge en raison du changement de taille des éléments flexibles. Je peux résoudre ce problème en ajoutant « position:absolute » au texte, mais le texte entre alors en conflit avec la ligne suivante. Savez-vous comment faire pour que les colonnes ne bougent pas et que le texte n'entre pas en conflit avec la ligne suivante ?

P粉366946380
P粉366946380

répondre à tous(2)
P粉739942405

L'élément de divulgation

Détails dispose déjà d'un mécanisme d'activation/désactivation intégré au navigateur. Alors pourquoi ne pas l'utiliser et modifier son comportement en fonction de nos besoins.

Le principe de base est

some clickable content
Any content you want to disclose when the gets clicked
  • Avec CSS, nous pouvons contrôler comment et où le contenu est affiché. Que nous utilisions le style de bloc par défaut ou la disposition Flexbox/Grid, le contenu est placé en dehors du flux de documents habituel. Ce sont des éléments réguliers, donc tout peut arriver.

  • Par défaut, il reste ouvert lorsque l'utilisateur clique ailleurs

    , nous avons besoin de Javascript pour detail/summary fermer automatiquement le contenu actuellement "public".

  • Les utilisateurs ont tendance à être confus lorsqu'ils ne voient pas de "bouton de fermeture", alors j'en ai mis un ici. Cependant, cliquez n'importe où dans la zone d'informations pour la fermer.

Je suis allé un peu trop loin avec cela et j'ai créé une démo réactive qui ignorait complètement votre code (désolé !) tout en essayant d'être aussi proche que possible du site d'exemple. J'ai commenté le cas échéant. Si ce n'est pas clair, dites-le-moi dans les commentaires.

Clip

// Contains a reference to the current 'open' 
element var currentDetail; // Walk the list of all grid cells =>
document.querySelectorAll('.grid .cell').forEach(el => { // Walk the list of grid cell children and attach eventlisteners for (const child of el.children) { // When it's a preview, toggle its information box // or open another when the information box is already visible. if (child.classList.contains('preview')) { // this event triggers before
'toggle' event child.addEventListener("click", event => { toggleDetails(event.currentTarget.closest('.cell')) }); // Finds closest parent .cell } // When it is an information box, just close it. if (child.classList.contains('information')) { child.addEventListener("click", event => { closeDetails() }); } }; }); function toggleDetails(el) { if (el.open) { /* Browser is about to trigger details 'toggle' */ currentDetail = null; // all details closed } else { // not null and different detail if ((currentDetail) && (currentDetail != el)) { currentDetail.removeAttribute('open'); // close current open detail }; currentDetail = el; // save new opened detail }; }; function closeDetails() { if (currentDetail) { // Details open? currentDetail.removeAttribute('open'); // close current open detail currentDetail = null; // all details closed }; };
/* * { outline: 1px dashed } /* for debugging */

/********************************/
/* some convenient global rules */
/********************************/
*, ::before, ::after { box-sizing: border-box }
/* makes padding and border part of any element total size, margin never */

html, body  { width: 100%; max-width: 100% }
html        { scroll-behavior: smooth }

body {
    margin: unset; /* Kill default margin */

    min-height: 100vh;
    line-height: 1.5;
    padding: 1rem;

    overscroll-behavior: contain; /* Check MDN for this */
}

details, /* Remove CSS defaults */
summary { padding: 0; list-style: none }

img {
    display: block;        /* removes little whitespace below image */
    width: 100%;           /* stretch to full width */
    aspect-ratio: 1 / 1.5; /* or height: auto, your choice */
    object-fit: cover;     /* fill parent, but clip when it doesn't fit */
}

/* Responsive font sizing */
/* Using linear equation y=mx+b => y=0.00625x + 12 (320,14)(1280,20) */
html { font-size: calc(0.625vmin + 0.75rem) }
body { font-size: 1rem }

/************************************/
/* DEMO, base layout - mobile first */
/************************************/
.grid {
    display: flex; flex-flow: row wrap;
    justify-content: center;
    gap: 1rem;
}

.cell {
    /* fiddle with these properties */
    flex-grow: 1;                /* [OPTIONAL] */
    min-width: min(12rem, 100%); /* set to desired width */

    cursor: pointer;
}

.cell .preview { border: 1px solid Black }

.cell .information {
    overflow: auto; overscroll-behavior: contain;

    position: fixed;    /* within viewport */
    z-index: 99999;     /* over any body content */
    inset: 0%;          /* full screen */

    gap: 1rem;
    padding: 4rem 1rem 1rem;

    background-color: hsl(0,0%,14%); color: hsl(0,0%,90%);

    cursor: default;
}

/****************************/
/* Some responsive behavior */
/****************************/
@media all and (min-width: 361px) {
    .cell .information {
        display: flex; flex-flow: row wrap; justify-content: center;

        inset: 30% 0% 0%;   /* stay % from sides */
        padding: 4rem;
        opacity: 0.985;
    }

    .cell .information img {
        width: auto; max-width: min(360px, 100%);
    }
}
/* Dito */
@media all and (min-width: 721px) {
    .cell {
        flex-grow: 0; /* [OPTIONAL] */
    }
}
/* Allow content to grow, only relevant on +360px devices */
/* as  * { flex: 1 }

/**********************************************/
/* The .information 'x' close button behavior */
/**********************************************/
.cell .information .close {
    position: absolute; top: 0.75rem; right: 1.25rem;
    font-size: 2em; font-style: normal;

    cursor: pointer;
}
.cell .information .close::after       { content: "15" }
.cell .information .close:hover::after { content: "16" }

Nice Description

Lorem ipsum dolor sit amet, id pri eirmod dolores ponderum. Per ea case posse libris, eros magna ius no. Rebum dicat legere sit ut. Mentitum consequat eam et. Omnis quaeque blandit mei in. Ius debet vulputate ut.

Nice Description

Lorem ipsum dolor sit amet, id pri eirmod dolores ponderum. Per ea case posse libris, eros magna ius no. Rebum dicat legere sit ut. Mentitum consequat eam et. Omnis quaeque blandit mei in. Ius debet vulputate ut.

Nice Description

Lorem ipsum dolor sit amet, id pri eirmod dolores ponderum. Per ea case posse libris, eros magna ius no. Rebum dicat legere sit ut. Mentitum consequat eam et. Omnis quaeque blandit mei in. Ius debet vulputate ut.

Nice Description

Lorem ipsum dolor sit amet, id pri eirmod dolores ponderum. Per ea case posse libris, eros magna ius no. Rebum dicat legere sit ut. Mentitum consequat eam et. Omnis quaeque blandit mei in. Ius debet vulputate ut.

Nice Description

Lorem ipsum dolor sit amet, id pri eirmod dolores ponderum. Per ea case posse libris, eros magna ius no. Rebum dicat legere sit ut. Mentitum consequat eam et. Omnis quaeque blandit mei in. Ius debet vulputate ut.

Nice Description

Lorem ipsum dolor sit amet, id pri eirmod dolores ponderum. Per ea case posse libris, eros magna ius no. Rebum dicat legere sit ut. Mentitum consequat eam et. Omnis quaeque blandit mei in. Ius debet vulputate ut.

Nice Description

Lorem ipsum dolor sit amet, id pri eirmod dolores ponderum. Per ea case posse libris, eros magna ius no. Rebum dicat legere sit ut. Mentitum consequat eam et. Omnis quaeque blandit mei in. Ius debet vulputate ut.

Nice Description

Lorem ipsum dolor sit amet, id pri eirmod dolores ponderum. Per ea case posse libris, eros magna ius no. Rebum dicat legere sit ut. Mentitum consequat eam et. Omnis quaeque blandit mei in. Ius debet vulputate ut.

Nice Description

Lorem ipsum dolor sit amet, id pri eirmod dolores ponderum. Per ea case posse libris, eros magna ius no. Rebum dicat legere sit ut. Mentitum consequat eam et. Omnis quaeque blandit mei in. Ius debet vulputate ut.
P粉041881924

Si nous passons à laisser de l'espace dans .flex-item 上切换 active 类,我们可以为活动 .flex-item 添加高度,以便为 .text.

Remarque : Pour positionner correctement le côté gauche de .text 元素,重要的是不要定位 .flex-items(或 position: static)。否则 .textleft: 0 将位于父级 .flex-item.

Voici un extrait d'un exemple fonctionnel :

var coll = document.getElementsByClassName("rectangle");
var i;

for (i = 0; i  x.classList.remove('active'))
    this.parentElement.classList.add("active");
  });
}
.flex-container {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: center;
}

.flex-item {
  width: 200px;
}

.rectangle {
  width: 200px;
  height: 50px;
  background-color: red;
  cursor: pointer;
  position: relative;
}

.flex-item.active {
  height: 155px;
}

.flex-item:not(.active) .text {
  display: none;
}

.text {
  position: absolute;
  left: 0px;
  width: 100%;
  padding: 10px;
  text-align: center;
  margin-top: 5px;
  height: 100px;
  background: grey;
  color: #fff;
  box-sizing: border-box;
}

/*tooltip styles*/
.flex-item.active .rectangle::after {
  content: '';
  border: solid 10px transparent;
  border-bottom: solid 10px grey;
  position: absolute;
  bottom: -5px;
  left: calc(50% - 5px);
}
Lorem ipsum dolor sit amet, consectetur adipiscing elit
Lorem ipsum dolor sit amet, consectetur adipiscing elit
Lorem ipsum dolor sit amet, consectetur adipiscing elit
Lorem ipsum dolor sit amet, consectetur adipiscing elit
Lorem ipsum dolor sit amet, consectetur adipiscing elit
Lorem ipsum dolor sit amet, consectetur adipiscing elit
Lorem ipsum dolor sit amet, consectetur adipiscing elit
Lorem ipsum dolor sit amet, consectetur adipiscing elit
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal