搜尋

首頁  >  問答  >  主體

如何將可折疊元素插入到 Flexbox 佈局中

我有一個圖像繞行的彈性盒佈局,我想在單擊圖像時顯示一些資訊。此資訊應顯示在包含影像的行與其正下方的行之間,而不移動「列」。 這就是我想要的效果類型:http://olmenta.altervista.org(當您點擊一本書時)。

這是我所做的: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>

由於彈性項目的大小發生變化,「列」正在移動。 我可以透過在文字中加入「position:absolute」來解決此問題,但隨後文字與下一行發生衝突。 你知道我如何才能讓列不移動並且文字不與下一行衝突嗎?

P粉366946380P粉366946380254 天前357

全部回覆(2)我來回復

  • P粉739942405

    P粉7399424052024-03-20 14:07:10

    詳細資訊揭露元素已經有一個瀏覽器內建的開啟/關閉機制。那麼為什麼不使用它並修改其行為來滿足我們的要求。

    基本原則是

    some clickable content
    Any content you want to disclose when the gets clicked
    • 透過 CSS,我們可以控制內容的顯示方式和位置。無論我們使用預設的區塊樣式還是 Flexbox/Grid 佈局,都將內容放置在常規文件流之外。它們是常規元素,所以基本上任何事情都會發生。

    • 預設情況下,當使用者點擊其他地方 detail/summary 保持開啟狀態,我們需要一些 Javascript 來自動關閉目前「公開」的內容。

    • 當用戶沒有看到「關閉按鈕」時,他們往往會感到困惑,所以我在那裡放了一個。但是,按一下資訊框中的任意位置將其關閉。

    我對此有點過分了,創建了一個響應式演示,完全忽略了您的程式碼(抱歉!),同時嘗試盡可能接近範例網站。我評論了所有適用的地方。如果不清楚,請在評論中告訴我。

    片段

    // 包含目前「開啟」
    元素的引用 var 目前詳細資料; // 遍歷所有網格單元的清單 =>
    document.querySelectorAll('.grid .cell').forEach(el => { // 遍歷網格單元子層級清單並附加事件監聽器 for (el.children 的 const 子級) { // 預覽時,切換其資訊框 // 或當資訊框已經可見時打開另一個。 if (child.classList.contains('預覽')) { // 該事件在
    'toggle' 事件之前觸發 child.addEventListener("click", event => {toggleDetails(event.currentTarget.closest('.cell')) }); // 找到最近的父.cell } // 當是資訊框時,關閉即可。 if (child.classList.contains('訊息')) { child.addEventListener("click", event => { closeDetails() }); } }; }); 函數切換詳細資訊(el){ if (el.open) { /* 瀏覽器即將觸發詳細資訊 'toggle' */ 當前詳細資料 = null; // 所有詳細資料已關閉 } else { // 不為空且細節不同 if ((currentDetail) && (currentDetail != el)) { currentDetail.removeAttribute('開啟'); // 關閉當前開啟的詳細信息 }; 當前詳細資料 = el; // 儲存新開啟的詳細信息 }; }; 函數 closeDetails() { if (currentDetail) { // 詳細資料已開啟? currentDetail.removeAttribute('開啟'); // 關閉當前開啟的詳細信息 當前詳細資料 = null; // 所有詳細資料已關閉 }; };
    /* * { Outline: 1px dashed } /* 用於調試 */
    
    /*********************************/
    /* 一些方便的全域規則 */
    /*********************************/
    *, ::之前, ::之後 { box-sizing: border-box }
    /* 使填充和邊框成為任何元素總大小的一部分,而邊距從不 */
    
    html, 內文 { 寬度: 100%;最大寬度:100% }
    html { 滾動行為:平滑 }
    
    身體 {
        邊距:未設定; /* 取消預設保證金 */
    
        最小高度:100vh;
        行高:1.5;
        填充:1rem;
    
        過度滾動行為:包含; /* 檢查 MDN 是否有此 */
    }
    
    詳細信息,/* 刪除 CSS 預設值 */
    摘要 { 填充:0;列表樣式:無 }
    
    圖像{
        顯示:塊; /* 刪除影像下方的小空白 */
        寬度:100%; /* 拉伸至全寬 */
        縱橫比:1 / 1.5; /* 或高度:自動,您的選擇 */
        物件適配:覆蓋; /* 填滿父級,但在不適合時進行剪輯 */
    }
    
    /* 響應式字體大小 */
    /* 使用線性方程式 y=mx b => y=0.00625x 12 (320,14)(1280,20) */
    html { 字體大小:calc(0.625vmin 0.75rem) }
    正文 { 字體大小:1rem }
    
    /******************************************/
    /* DEMO,基本佈局 - 行動優先 */
    /******************************************/
    。網格 {
        顯示:柔性; flex-flow:行換行;
        調整內容:居中;
        間隙:1rem;
    }
    
    。細胞 {
        /* 擺弄這些屬性 */
        彈性成長:1; /* [選修的] */
        最小寬度:min(12rem,100%); /* 設定為所需的寬度 */
    
        遊標:指針;
    }
    
    .cell .preview { 邊框:1px 實心黑色 }.cell.資訊{
        溢出:自動;過度滾動行為:包含;
    
        位置:固定; /* 在視窗內 */
        z 索引:99999; /* 覆蓋任何主體內容 */
        圖解:0%; /* 全螢幕 */
    
        間隙:1rem;
        填充:4rem 1rem 1rem;
    
        背景顏色:hsl(0,0%,14%);顏色:hsl(0,0%,90%);
    
        遊標:預設;
    }
    
    /*****************************/
    /* 一些回應行為 */
    /*****************************/
    @media all 和(最小寬度:361px){
        .cell.資訊{
            顯示:柔性; flex-flow:行換行;調整內容:居中;
    
            圖解:30% 0% 0%; /* 與側邊保持% */
            填充:4rem;
            不透明度:0.985;
        }
    
        .cell .訊息 img {
            寬度:自動;最大寬度:最小(360px,100%);
        }
    }
    /* 迪托 */
    @media all 和(最小寬度:721px){
        。細胞 {
            彈性成長:0; /* [選修的] */
        }
    }
    /* 允許內容成長,僅在 360px 裝置上相關 */
    /* 作為 <361px are has no flexbox parent */
    .cell .information > * { flex: 1 }
    
    /**********************************************************************/
    /* .information 'x' 關閉按鈕行為 */
    /**********************************************************************/
    .cell .訊息 .close {
        位置:絕對;頂部:0.75rem;右:1.25rem;
        字體大小:2em;字體樣式:正常;
    
        遊標:指針;
    }
    .cell .information .close::after { 內容: "\2715" }
    .cell .information .close:hover::after { 內容: "\2716" }
    #

    很好的描述

    Lorem ipsum dolor sat amet,id pri eirmod dolores ponderum。每個案例 posse libris, eros magna ius no.請坐下來。 Mentitum consequat eam 等。 Omnis quaeque blandit mei in. Ius debet vulputate ut。
    #

    很好的描述

    Lorem ipsum dolor sat amet,id pri eirmod dolores ponderum。每個案例 posse libris, eros magna ius no.請坐下來。 Mentitum consequat eam 等。 Omnis quaeque blandit mei in. Ius debet vulputate ut。
    #

    很好的描述

    疼痛本身非常重要,尤其是舉重時的疼痛。透過那些書,起司可以是,愛欲並不是一個大權利。他說他應該讀一讀。他在這件事上對她撒了謊。一切都讓我受寵若驚。成為超級英雄應該是對的。
    #

    很好的描述

    疼痛本身非常重要,尤其是舉重時的疼痛。透過那些書,起司可以是,愛欲並不是一個大權利。他說他應該讀一讀。他在這件事上對她撒了謊。一切都讓我受寵若驚。成為超級英雄應該是對的。
    #

    很好的描述

    疼痛本身非常重要,尤其是舉重時的疼痛。透過那些書,起司可以是,愛欲並不是一個大權利。他說他應該讀一讀。他在這件事上對她撒了謊。一切都讓我受寵若驚。成為超級英雄應該是對的。
    #

    很好的描述

    疼痛本身非常重要,尤其是舉重時的疼痛。透過那些書,起司可以是,愛欲並不是一個大權利。他說他應該讀一讀。他在這件事上對她撒了謊。一切都讓我受寵若驚。成為超級英雄應該是對的。
    #

    很好的描述

    疼痛本身非常重要,尤其是舉重時的疼痛。透過那些書,起司可以是,愛欲並不是一個大權利。他說他應該讀一讀。他在這件事上對她撒了謊。一切都讓我受寵若驚。成為超級英雄應該是對的。
    #

    很好的描述

    疼痛本身非常重要,尤其是舉重時的疼痛。透過那些書,起司可以是,愛欲並不是一個大權利。他說他應該讀一讀。他在這件事上對她撒了謊。一切都讓我受寵若驚。成為超級英雄應該是對的。
    #

    很好的描述

    疼痛本身非常重要,尤其是舉重時的疼痛。透過那些書,起司可以是,愛欲並不是一個大權利。他說他應該讀一讀。他在這件事上對她撒了謊。一切都讓我受寵若驚。成為超級英雄應該是對的。

    回覆
    0
  • P粉041881924

    P粉0418819242024-03-20 09:09:13

    如果我們切換到在.flex-item 上切換active 類,我們可以為活動.flex-item 添加高度,以便為.text 留出空間。

    注意:為了正確定位 .text 元素,重要的是不要定位 .flex-items(或 position: static)。否則 .textleft: 0 將位於父級 .flex-item 的左側。

    這是一個工作範例的片段:

    var coll = document.getElementsByClassName("rectangle");
    var i;
    
    for (i = 0; i < coll.length; i++) {
      coll[i].addEventListener("click", function() {
        document.querySelectorAll('.flex-item.active').forEach(x => 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

    回覆
    0
  • 取消回覆