CSS 也能實現 if 判斷?實現動態高度下的不同樣式展現

来源:https://www.cnblogs.com/coco1s/archive/2023/11/14/17831064.html
-Advertisement-
Play Games

最近在群里,有個小伙伴問了這麼一道很有趣的問題: CSS 能否實現,容器再某個高度下是某種表現,一旦超出某個高度,則額外展示另外一些內容 為了簡化實際效果,我們看這麼一張示意效果圖: 可以看到,當容器高度沒有超過某一個值時,沒有箭頭圖標。反之,箭頭圖標出現。 這個效果在很多場景都會出現,可以算是一個 ...


最近在群里,有個小伙伴問了這麼一道很有趣的問題:

  1. CSS 能否實現,容器再某個高度下是某種表現,一旦超出某個高度,則額外展示另外一些內容

為了簡化實際效果,我們看這麼一張示意效果圖:

可以看到,當容器高度沒有超過某一個值時,沒有箭頭圖標。反之,箭頭圖標出現。

這個效果在很多場景都會出現,可以算是一個高頻場景,那麼在今天,我們能否不使用 JavaScript,僅僅憑藉 CSS 實現類似於這樣的功能呢?

答案當然是可以,XBoxYan 大佬在 CSS 實現超過固定高度後出現展開摺疊按鈕 介紹了一種非常巧妙的藉助浮動的解法,十分有意思,感興趣的同學可以先行一步瞭解。

當然,浮動 float 在現如今的 CSS 世界,運用的已經非常少了。那麼除了浮動,還有沒有其它有意思的解法?本文我們將一起來探究探究。

方法一:藉助最新的容器查詢

第一種方法,非常簡單,但是對相容性有所要求。那就是使用容器查詢 -- @container 語法。

容器查詢在 新時代佈局新特性 -- 容器查詢 也詳細介紹過。

簡單而言,容器查詢它給予了 CSS,在不改變瀏覽器視口寬度的前提下,只是根據容器的寬度或者高度變化,對佈局做調整的能力。

基於這個場景,我們假設我們有如下的 HTML/CSS 結構:

<div class="g-container">
    <div class="g-content">
        Lorem ipsum dolor s...
    </div>
</div>
.g-container {
    position: relative;
    width: 300px;
    height: 300px;
    resize: vertical;
    overflow: hidden;

    .g-content {
        height: 100%;
    }

    .g-content::before {
        content: "↑";
        position: absolute;
        bottom: 0px;
        left: 50%;
        transform: translate(-50%, 0);
    }
}

它是這麼一個樣式效果:

其中,我們給元素 .g-content 添加了 resize: vertical,讓它變成了一個可以在豎直方向上通過拖動改變高度的容器,以模擬容器在不同內容的場景下,高度不一致的問題:

我們通過元素的偽元素實現了箭頭 ICON,並且它是一直顯示在容器內的。

下麵,我們通過簡單的幾句容器查詢代碼,就可以實現讓箭頭 ICON,只在容器高度超過特定高度的時候才出現:

.g-container {
    container-type: size;
    container-name: container;
}

@container container (height <= 260px) {
    .g-content::before {
        opacity: 0;
    }
}

簡單解釋一下:

  1. .g-container 它被用作容器查詢的目標容器
    • container-type 屬性指定了容器的類型為 size,表示我們將使用容器的尺寸來應用樣式。
    • container-name 屬性指定了容器的名稱為 container,以便在後面的容器查詢規則中引用。
  2. @container container (height <= 260px) {} 表示這是一個容器查詢規則,在括弧中的條件 (height <= 260px) 表示當容器的高度小於等於 260px 時,應用該規則下的樣式
  3. 具體規則為,如果容器的高度小於等於 260px 時,.g-content 元素的偽元素將變得透明

這樣,我們就非常簡單的實現了容器在不同高度下,ICON 元素的顯示隱藏切換:

完整的代碼,你可以戳這裡:CodePen Demo -- flexible content

當然,這個方案的唯一缺點在於,截止至今天(2023-11-11),相容性不是那麼好:

那,有沒有相容性更好的方案?當然,來我們一起來看看 clamp + calc 的方案。

方法二:clamp + calc 大顯神威

上面效果的核心在於:

  1. 如果容器的高度大於某個值,顯示樣式 A
  2. 如果容器的高度小於等於某個值,顯示樣式 B

那麼想想看,如果拿容器的高度減去一個固定的高度值,會發生什麼?假設一下,ICON 元素的 CSS 代碼如下:

.g-content::before {
    content: "↑";
    position: absolute;
    left: 50%;
    transform: translate(-50%, 0);
    bottom: calc(100% - 200px);
}

仔細觀察 bottom: calc(100% - 200px),在元素的 bottom 屬性中,100% 表示的是容器當前的高度,因此 calc(100% - 200px) 的含義就代表,容器當前高度減去一個固定高度 200px。因此:

  1. 當容器高度大於 200pxcalc(100% - 200px) 表示的是一個正值
  2. 當容器高度小於 200pxcalc(100% - 200px) 表示的是一個負值
  3. 當容器高度等於 200pxcalc(100% - 200px) 表示 0

我們看看這種情況下,整個 ICON 的表現是如何的:

可以看到,當容器高度大於 200px 的時候,箭頭 ICON 確實出現了,但是,它無法一直定位在整個容器的最下方

有什麼辦法讓它在出現後,一直定位在容器的最下方嗎?

別忘了,CSS 中,還有幾個非常有意思的數學函數:min()max()clamp(),它們可以有效限定動態值在某個範圍之內!

不太瞭解的,可以看看這篇 現代 CSS 解決方案:CSS 數學函數

利用 clamp(),我們可以限定計算值的最大最小範圍,在這個場景下,我們可以限制 bottom 的最大值為 10px

.g-content::before {
    // ...
    bottom: clamp(-99999px, calc(100% - 200px), 10px);
}

上面的代碼 clamp(-99999px, calc(100% - 200px), 10px),核心在於,如果 calc(100% - 200px) 的計算值大於 10px,它只會取值為 10px,利用這個技巧,我們可以在容器高度超長時,把箭頭 ICON 牢牢釘在容器的下方,無論容器的高度是多少:

到此,結束了嗎?顯然沒有。

雖然上面的代碼,解決當 calc(100% - 200px) 的計算值大於 10px 的場景,但是沒有解決,當 calc(100% - 200px) 的計算值處於 -10px ~ 10px 這個範圍內的問題。

我們可以清楚的看到,當我們往下拖動容器變高的時候,箭頭元素是逐漸慢慢向上出現,而不是突然在某一個高度下,直接出現,所以在實際使用中,會出現這種 ICON 只出現了一半的尷尬場景:

但是,莫慌!這個問題也好解決,我們只需要給 calc(100% - 200px) 的計算值,乘上一個超級大的倍數即可。原因在於:

  1. calc(100% - 200px) 的計算值是負數時,我們其實不希望 ICON 出現,此時,乘上一個超級大的倍數,依然是負數,不影響效果
  2. calc(100% - 200px) 的計算值是正數時,為了避免 ICON 處在只漏出部分的尷尬場景,通過乘上一個超級大的倍數,讓整個計算值變得非常大,但是由於又有 clamp() 最大值的限制,無論計算值多大,都只會取 10px

看看代碼,此時,整個 bottom 的取值就改造成了:

.g-content::before {
    // ...
    bottom: clamp(-9999px, calc(calc(100% - 200px) * 100000), 10px);
}

通過,將 calc(100% - 200px) 的值,乘上一個超大的倍數 100000,無論是正值還是負值,我們把計算值放大了 100000 倍。這樣,整個效果就達成了我們想要的效果:

仔細看上圖,ICON 元素從漸現,變成了瞬間出現!與上面的 @container 效果幾乎一致,最終達成了我們想要的效果。

其核心就在於 clamp(-9999px, calc(calc(100% - 200px) * 100000), 10px),一定需要好好理解這一段代碼背後的邏輯。

基於此,我們就巧妙的利用 clamp() + calc() 方法,近似的實現了類似於 if/else 的邏輯,實在是妙不可言!

CodePen Demo -- flexible content

最後

好了,本文到此結束,希望本文對你有所幫助

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 火山引擎DataTester上線的「集成工作台」功能,能夠將DataTester的能力與企業自身的系統進行打通,減少系統之間的多次跳轉。幫助企業打造專屬AB平臺,滿足企業的個性化訴求,大幅降低企業服務的應用成本並提升用戶使用體驗。該功能可以通過完善的引導,進行一站式的定製、發佈、嵌出,幫助企業打造專... ...
  • 原文地址: Android app的暗黑模式適配實現 - Stars-One的雜貨小窩 很久之前放在草稿箱的一篇簡單筆記,是之前藍奏雲批量下載工具Android版本實現暗黑主題的適配記錄 本文所說的這裡的暗黑主題,應該只支持Android10系統,不過我手頭的Flyme系統(Android9)上測試 ...
  • 在日常的 JavaScript 編碼中,我們經常使用解構語法來提取對象中的屬性。假設我們有一個名為 fetchResult 的對象,代表從介面返回的數據,其中包含一個欄位名為 data。 const fetchResult = { data: null }; 在提取 data 欄位時,為了避免介面未 ...
  • vue 最有代表性質的就是.VUE 的文件,每一個vue文件都是一個組件,那麼vue 組件的編譯過程是什麼樣的呢 Vue 單文件組件 (SFC)和指令 ast 語法樹 一個 Vue 單文件組件 (SFC),通常使用 *.vue 作為文件擴展名,它是一種使用了類似 HTML 語法的自定義文件格式,用於 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 前言 Vue2 將在 2023 年年底停止維護了,但是 Vue2 的代碼卻不會在 2023 年消失,還會越來越多;難以想象幾十萬行或者幾百萬行的 Vue2 代碼遷移到 Vue3,這是不可能辦到的; 老一點的前端程式員肯定經歷過把大型項目從 ...
  • 從一個假死頁面引發的思考: 作為前端開發,除了要攻剋頁面難點,也要有更深的自我目標,性能優化是自我提升中很重要的一環; 在前端開發中,會偶遇到頁面假死的現象, 是因為當js有大量計算時,會造成 UI 阻塞,出現界面卡頓、掉幀等情況,嚴重時會出現頁面卡死的情況; ...
  • 本文介紹使用canvas的drawImage進行視頻截圖,並用toDataURL和toBlob轉化為圖片地址的方法,且重點介紹了將bold信息轉化為圖片地址的方法。 ...
  • 事件迴圈不是瀏覽器獨有的,從字面上看,“迴圈”可以簡單地認為就是重覆,比如for迴圈,就是重覆地執行for迴圈體中的語句,所以事件迴圈,可以理解為重覆地處理事件,那麼下一個問題是,處理的是什麼事件,事件的相關信息從哪裡獲取。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...