How to insert collapsible elements into Flexbox layout
P粉366946380
P粉366946380 2024-03-19 23:20:59
0
2
353

I have a flexbox layout with an image wrapped around it and I want to display some information when the image is clicked. The information should appear between the row containing the image and the row directly below it, without moving the "column". This is the type of effect I want: http://olmenta.altervista.org (when you click on a book).

Here's what I did: 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>

The "column" is moving due to the size change of the flex item. I can solve this problem by adding "position:absolute" to the text, but then the text conflicts with the next line. Do you know how I can make the columns not move and the text not conflict with the next line?

P粉366946380
P粉366946380

reply all(2)
P粉739942405

Detailed Information Disclosure ElementsAlready have a built-in browser turn on/off mechanism. So why not use it and modify its behavior to suit our requirements.

The basic principle is

some clickable content
Any content you want to disclose when the gets clicked
  • Through CSS, we can control how and where content is displayed. Whether we use the default block style or the Flexbox/Grid layout, the content is placed outside the regular document flow. They are regular elements, so basically anything can happen.

  • By default detail/summary stays open when the user clicks elsewhere, we need some Javascript to automatically close the currently "public" content.

  • Users tend to get confused when they don't see a "Close Button", so I put one in there. However, click anywhere in the info box to close it.

I went a little overboard with this and created a responsive demo that completely ignored your code (sorry!) while trying to be as close to the example site as possible. I commented wherever applicable. If it's unclear, please tell me in the comments.

fragment

// 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: "\2715" }
.cell .information .close:hover::after { content: "\2716" }

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

The pain itself is very important, that is, especially the pains of the weights. By means of those books that the cheese can be, the eros is not a big right. He says that he should read it. He lied to her about it. Everything flatters me. It should be right to be a superhero.
#

Nice Description

The pain itself is very important, that is, especially the pains of the weights. By means of those books that the cheese can be, the eros is not a big right. He says that he should read it. He lied to her about it. Everything flatters me. It should be right to be a superhero.
#

Nice Description

The pain itself is very important, that is, especially the pains of the weights. By means of those books that the cheese can be, the eros is not a big right. He says that he should read it. He lied to her about it. Everything flatters me. It should be right to be a superhero.
#

Nice Description

The pain itself is very important, that is, especially the pains of the weights. By means of those books that the cheese can be, the eros is not a big right. He says that he should read it. He lied to her about it. Everything flatters me. It should be right to be a superhero.
#

Nice Description

The pain itself is very important, that is, especially the pains of the weights. By means of those books that the cheese can be, the eros is not a big right. He says that he should read it. He lied to her about it. Everything flatters me. It should be right to be a superhero.
#

Nice Description

The pain itself is very important, that is, especially the pains of the weights. By means of those books that the cheese can be, the eros is not a big right. He says that he should read it. He lied to her about it. Everything flatters me. It should be right to be a superhero.
#

Nice Description

The pain itself is very important, that is, especially the pains of the weights. By means of those books that the cheese can be, the eros is not a big right. He says that he should read it. He lied to her about it. Everything flatters me. It should be right to be a superhero.
P粉041881924

If we switch to switching the active class on .flex-item, we can add a height to the active .flex-item so that .text Leave space.

Note: In order to position .text elements correctly, it is important not to position .flex-items (or position: static). Otherwise the left: 0 of .text will be to the left of the parent .flex-item.

Here is a snippet of a working example:

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: gray;
  color: #fff;
  box-sizing: border-box;
}

/*tooltip styles*/
.flex-item.active .rectangle::after {
  content: '';
  border: solid 10px transparent;
  border-bottom: solid 10px gray;
  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
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template