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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...