整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          CSS 如何讓auto height完美支持過渡動畫

          CSS 如何讓auto height完美支持過渡動畫?

          所周知,高度在設置成auto關鍵詞時是不會觸發transition過渡動畫的,下面是偽代碼

          div{
            height: 0;
            transition: 1s
          }
          .wrap:hover div{
            height: auto
          }
          


          效果如下

          如果希望展開時有過渡動畫,例如這樣

          通常是借助 JS 動態去獲取元素的高度(還有些麻煩的,需要渲染后才能知道高度)。其實CSS 也有一個巧用max-height適配動態高度的解決方案,下面是偽代碼

          div{
            max-height: 0;
            transition: 1s
          }
          .wrap :hover div{
            max-height: 800px /*大概的值,需要超過元素高度*/
          }
          


          有興趣的可以參考這篇文章:CSS 奇技淫巧:動態高度過渡動畫,但是有一個局限性,高度差異越大,過渡效果越糟糕,假設元素真實高度只有 100px,如果 max-height為800px,那只有前1/8有動畫,就像這樣

          那么,有沒有更好的方式來解決這個問題呢?

          當然也是有的,這次就來介紹一個全新的方式來實現動態高度過渡,一起看看吧

          一、grid 布局中的 fr 單位

          grid布局中有一個全新的fr單位,用于定義網格軌道大小的彈性系數。grid布局比較復雜,三言兩語不可能說清楚,有興趣的可以參考grid相關教程,例如

          • 張鑫旭老師的寫給自己看的display: grid布局教程
          • 大漠老師的現代 Web 布局

          這里簡單介紹一下fr單位的用途,比如有這樣一個布局

          <div class="grid">
            <span class="item">1fr</span>
            <span class="item">1fr</span>
            <span class="item">1fr</span>
          </div>
          


          關鍵樣式如下

          .grid{
            display: grid;
            grid-template-columns: repeat(3, 1fr);
          }
          


          可以得到這樣的效果

          這里的repeat(3, 1fr)其實就是1fr 1fr 1fr的簡寫,表示 3 等分剩余空間。還可以設置在垂直方向上

          .grid{
            grid-template-rows: repeat(3, 1fr);
          }
          


          效果如下

          也可以改變各自的分配比例

          .grid{
            grid-template-rows: 1fr 2fr 1fr;
          }
          


          效果如下

          現在來看一種特殊情況,還可以將分配比例設置為0fr

          .grid{
            grid-template-rows: 0fr 2fr 1fr;
          }
          


          效果如下

          是不是有點奇怪,0fr怎么和1fr占比相同呢?

          其實這是由grid的最小尺寸規則決定的,此時的最小高度是min-content,也就是由內部文本決定的。如果沒有文字,0fr自然就不占空間了,下面是去除文字后的效果

          如果想保留文字并且不占空間怎么辦呢?可以直接手動設置最小尺寸

          span{
            min-height: 0
          }
          


          這樣0fr也會不占空間

          還可以借助超出隱藏,徹底隱藏子內容

          .grid{
            overflow: hidden;
          }
          span{
            min-height: 0
          }
          


          效果如下

          應該還是比較容易理解吧,那么和動畫有啥關系呢?接著往下看

          二、grid 中的過渡動畫

          有同學可能納悶了,為啥要折騰這個0fr呢?下面就來揭曉

          如果重新設置1fr,子內容又會重新出現

          .grid{
            grid-template-rows: 1fr 2fr 1fr;
          }
          


          下面重點來了,grid中的fr單位也是支持過渡動畫的(0fr=>1fr )

          .grid{
            grid-template-rows: 1fr 2fr 1fr;
            transition: .3s
          }
          


          效果如下

          由于高度是由內部文本撐開的,也就是高度不確定,而0fr到1fr的過渡變化,相當于實現了 高度不固定的過渡動畫

          進一步精簡一下,可以實現這樣的效果

          這就是高度不固定動畫的雛形了,換個文本多一點也完美支持

          完整 demo可以查看以下任意鏈接

          • CSS auto height transition (codepen.io)
          • CSS auto height transition (runjs.work)

          三、自適應高度動畫的兩個實例

          現在根據上面的原理來實現兩個實例。

          首先來看文章最開頭的示例,HTML 結構是這樣的

          <div class="wrap">
            <button class="trigger">鼠標放上來試試</button>
            <div class="grid">
              <div><p>歡迎關注前端偵探,這里有一些有趣的、你可能不知道的HTML、CSS、JS小技巧技巧,比如這篇文章,如何讓 auto height 支持過渡動畫?一起看看吧</p></div>
            </div>
          </div>
          


          簡單修飾一下,應該比較容易,可以得到這樣的效果

          然后通過上面的技巧將下拉內容隱藏起來,關鍵樣式如下

          .grid{
            display: grid;
            grid-template-rows: 0fr;
            transition: .3s;
            overflow: hidden;
          }
          .grid>div{
            min-height: 0;
          }
          


          然后通過hover觸發顯示,也就是改變grid-template-rows

          .wrap:hover .grid{
            grid-template-rows: 1fr;
          }
          


          這樣就實現了不定高度的過渡動畫

          完整 demo可以查看以下任意鏈接

          • CSS auto height drop (codepen.io)
          • CSS auto height drop (runjs.work)

          如果僅僅是懸浮窗口,由于是絕對定位,不會影響其他布局,其實是可以用transform scale 進行縮放的,再來看另外一個更加實用的例子,常見的菜單展開收起效果,就像這樣

          可以看到,在展開的同時,下方的元素也被擠壓下去了,這樣效果更加自然,也是transform實現不了的,這里的切換是通過:checked實現的,關鍵代碼如下

          <input hidden type="checkbox" id="s1" checked />
          <label for="s1">工作臺</label>
          <div class="sub">
            <ul>
              <li>項目列表</li>
              <li>數據配置器</li>
            </ul>
          </div>
          


          ul{
            min-height: 0;
          }
          .sub {
            display: grid;
            grid-template-rows: 0fr;
            transition: 0.3s;
            overflow: hidden;
          }
          :checked ~ .sub {
            grid-template-rows: 1fr;
          }
          


          完整 demo可以查看以下任意鏈接

          • CSS auto height menu (codepen.io)
          • CSS auto height menu (runjs.work)

          四、注意事項和一些局限性

          下面是一些注意事項。

          這里的動畫源于grid-template-rows的變化,也就是0fr到1fr

          **注意,注意,注意,**這里的0fr必須是0fr,不能是0或者0px,必須是fr單位

          下面是改為40px的效果(動畫丟失)

          再者,0fr也不支持calc計算,直接被認為不合法

          這意味著,例如你希望默認有一個固定高度(非0),然后展開到自適應高度,這種方法是無法實現過渡動畫的,略遺憾

          五、最后總結一下

          最后再來回顧一下實現關鍵過程

          .grid{
            display: grid;
            grid-template-rows: 0fr;
            transition: .3s;
            overflow: hidden;
          }
          .grid>div{
            min-height: 0;
          }
          .wrap:hover .grid{
            grid-template-rows: 1fr;
          }
          


          主要是利用了grid彈性布局可以實現過渡動畫的特點,下面總結一些實現要點

          1. 高度在設置成auto關鍵詞時不會觸發transition過渡動畫
          2. grid布局中的fr單位,可以用于定義網格軌道大小的彈性系數
          3. grid布局的尺寸計算規則是由最小高度決定的,默認是min-content,也就是由內部文本決定的,可以通過手動設置min-height來實現0fr
          4. grid布局也支持過渡動畫(0fr=>1fr ),這樣就實現高度不固定的過渡動畫
          5. 要使過渡動畫生效,必須是fr單位,其他單位不行,也不能通過calc計算
          6. 這種方法只能實現初始高度為0到自適應高度的過渡變化,略微遺憾

          最后,如果覺得還不錯,對你有幫助的話,歡迎點贊、收藏、轉發???


          作者:XboxYan
          鏈接:https://juejin.cn/post/7196843994030342200

          TML(超文本標記語言)中的元素可以分為兩類:塊級元素和內聯元素。塊級元素會自動占據一行,并且可以設置寬度和高度。內聯元素不會自動占據一行,而是根據文本內容的長度自動調整寬度。塊級元素可以包含其他元素,包括文本、圖像、鏈接等。內聯元素通常不包含其他元素。

          1. 塊級元素具有以下特點:

          • 塊級元素會自動占據一行,并且可以設置寬度和高度。
          • 塊級元素可以包含其他元素,包括文本、圖像、鏈接等。
          • 塊級元素可以設置背景顏色、邊框、字體等樣式屬性。

          以下是一些常見的塊級元素:

          • <div>:用于定義一個塊級容器,可以包含其他元素。
          • <p>:用于定義段落,通常包含文本內容。
          • <h1>到<h6>:用于定義標題,從h1到h6分別表示從大到小的標題級別。
          • <table>:用于定義表格,包含多個行和列。
          • <form>:用于定義表單,包含輸入框、按鈕等元素。
          • <ul>和<ol>:用于定義無序列表和有序列表,包含多個列表項。
          • <img>:用于定義圖像,用于在網頁中顯示圖片。

          這些塊級元素可以通過設置 CSS 樣式屬性來實現不同的布局和樣式效果,例如設置背景顏色、邊框、字體、大小、顏色等。同時,塊級元素還可以通過設置 CSS 定位屬性來實現定位和浮動效果,例如設置position: relative;、float: left;

          2. 內聯元素具有以下特點:

          • 內聯元素不會自動占據一行,而是根據文本內容的長度自動調整寬度。
          • 內聯元素可以設置字體、顏色、大小等樣式屬性。
          • 內聯元素通常不包含其他元素,而是直接嵌入文本內容中。

          以下是一些常見的內聯元素:

          • <a>:用于定義超鏈接,通常用于鏈接到其他網頁或文件。
          • <em>:用于定義強調文本,通常呈現為斜體效果。
          • <strong>:用于定義加粗文本,通常呈現為粗體效果。
          • <span>:用于定義自定義樣式的文本,通常用于應用特定的 CSS 樣式。
          • <img>:用于定義圖像,通常用于在網頁中顯示圖片。

          這些內聯元素可以通過設置 CSS 樣式屬性來實現不同的樣式效果,例如設置字體、顏色、大小等。同時,內聯元素還可以通過設置 CSS 定位屬性來實現定位和浮動效果,例如設置position: relative;、float: left。

          <img> 元素在 HTML 中既可以是塊元素,也可以是內聯元素,這取決于它的 display 屬性的值。

          默認情況下,<img> 元素是內聯元素,它會根據文本的流動方式進行布局。這意味著如果在一行中放置了多個 <img> 元素,它們會在一行中排列,并且不會自動換行。

          但是,如果將 <img> 元素的 display 屬性設置為 block,那么它就會成為塊元素。塊元素會占據一行,并且可以設置寬度和高度。在這種情況下,多個 <img> 元素會自動換行,并且可以通過設置 margin 屬性來調整它們之間的間距。

          html

          <img src="image.jpg" alt="圖片描述" style="display: block;">
          

          在上面的示例中,<img> 元素的 display 屬性被設置為 block,這會使它成為一個塊元素。你可以根據需要調整圖片的寬度和高度,以及 margin 屬性來控制圖片之間的間距。

          著 Web 技術的發展,有很多需要將 HTML 內容轉換為 PDF 文檔并下載的場景,比如常見的收據、發票、電子報告、對賬清單、文檔翻譯等等。

          本文將研究當前比較流行的基于 Node.js 技術棧的 HTML 轉 PDF 庫:Puppeteer、jsPDF 和 PDFKit,大綱如下:

          • Puppeteer 及優缺點
          • jsPDF 及優缺點
          • PDFKit 及優缺點
          • Puppeteer vs jsPDF vs PDFKit 功能對比

          1.Puppeteer

          1.1.使用 Puppeteer 生成 PDF

          Puppeteer 是谷歌開發的一個 Node.js 庫,為控制無頭(或完整)Chrome 或 Chromium 瀏覽器提供了一個高級 API。它是最流行的開源 HTML 到 PDF 轉換器,支持 HTML、CSS 和 JavaScript。

          Puppeteer 允許您自動化Web瀏覽器中的各種任務,例如 Web 抓取、網站測試、截圖創建和 PDF 生成。它利用 Chrome 或 Chromium Web 瀏覽器的功能將 HTML 內容呈現為 PDF 文件。

          下面使用 Puppeteer 快速初始化一個項目:

          nvm use 20.6.1
          
          mkdir puppeteer-demo
          
          cd puppeteer-demo
          
          npm init -y
          
          npm install puppeteer
          
          touch index.js
          
          

          index.js 中添加如下代碼:

          import puppeteer from 'puppeteer';
          
          (async ()=> {
            const browser=await puppeteer.launch({
              headless: 'new',
            });
          
            const page=await browser.newPage();
          
            await page.setContent(
              `<!DOCTYPE html>
              <html lang="en">
              <head>
                <meta charset="UTF-8">
                <meta name="viewport" content="width=device-width, initial-scale=1.0">
                <title>Document</title>
              </head>
              <body>
                <style>
                  body {
                    display: grid;
                    place-items: center;
                    margin: 0;
                    background-color: #ccc;
                    min-height: 100vh;
                  }
                </style>
                <h1>Hello, Puppeteer!</h1>
              </body>
              </html>`
            );
          
            await page.pdf({ path: 'result.pdf', format: 'A4' });
          
            await browser.close();
          })();
          

          在上面的代碼中,我們導入 Puppeteer 庫,啟動無頭 Chromium 瀏覽器,并在瀏覽器中創建一個新頁面。我們還會根據頁面內容和指定選項(如路徑和格式)生成 PDF,生成完成后關閉瀏覽器并釋放資源。

          1.2.優點

          • 您可以完全控制要在 PDF 中包含網頁的哪些部分。您可以指定具體的元素、部分或整個頁面
          • Puppeteer 提供了自定義選項,如指定頁面大小、邊距、頁眉和頁腳,使您可以根據特定需求定制 PDF 布局
          • Puppeteer 可以捕捉 PDF 中的交互元素,如超鏈接和表單字段,適用于生成交互式 PDF 文件。

          1.3.缺點

          • 使用 Puppeteer 生成的 PDF 有時可能比使用類似庫生成的PDF要大。這會影響下載時間和存儲成本。
          • 使用 Puppeteer 渲染復雜或大型網頁可能會消耗資源,導致PDF生成變慢和內存使用增加。

          2.PDFKit

          PDFKit 是 JavaScript 生態系統中最古老和最成熟的 PDF庫 之一。目前仍得到良好維護并定期更新。該庫通常使用 Node.js 在服務器端環境中創建和操作 PDF 文檔。它允許您通過定義每個頁面的內容、布局和格式來以程序方式生成PDF文件。

          PDFKit 提供了用于 PDF 文檔生成的高級 API,并支持各種功能,使其成為創建自定義 PDF 的多功能工具。作為 PDFKit 的包裝器,已開發出多個 PDF 庫,支持自定義字體和圖像嵌入。

          2.1.使用 PDFKit 生成 PDF

          讓我們來快速初始化一個 PDFKit 項目:

          nvm use 20.6.1
          
          mkdir pdfkit-demo
          
          cd pdfkit-demo
          
          npm init -y
          
          npm install pdfkit
          
          touch index.js
          

          index.js 中添加如下代碼:

          import fs from 'node:fs';
          import PDFDocument from 'pdfkit';
          
          const doc=new PDFDocument();
          
          const stream=fs.createWriteStream('example.pdf');
          
          doc.pipe(stream);
          doc.fontSize(12).text('Hello, PDFKit!', { align: 'center' });
          doc.end();
          
          stream.on('finish', ()=> {
            console.log('success');
          });
          

          執行 node index.js 后,可以看到 PDF 可以生成生成,并觸發 finish 事件的回調函數執行,打印出了 success 。

          2.2.優點

          • 由于它是開源的,并由社區積極維護,PDFkit 可以不斷改進和更新
          • PDFKit 可對 PDF 文檔的內容、布局和格式進行精細控制。您可以根據自己的特定需求創建高度定制的 PDF 文檔
          • PDFKit 是根據用戶請求、數據或其他服務器端進程動態生成 PDF 的絕佳選擇

          2.3.缺點

          • 創建具有高級布局和功能的復雜 PDF 可能具有挑戰性,可能需要充分了解庫的 API
          • 對于新手來說,PDFKit 的學習曲線可能比更直接的 HTML 到 PDF 轉換工具更陡峭,因為它需要對文檔結構進行更多的手動控制

          3.jsPDF

          jsPDF 是一個流行的 JavaScript PDF 生成器,允許用戶動態在 Web 瀏覽器中生成 PDF 文件。這個庫維護良好,穩定易用,并且有豐富的文檔。

          jsPDF 在客戶端操作,非常適合在 Web 應用程序中生成 PDF ,無需在服務器端生成。它可以修改現有布局,并允許用戶通過自定義來控制他們的 PDF。還可以用來編輯現有的 PDF 文檔或從頭創建一個,包括圖像、表格和形狀等內容。

          3.1.使用 jsPDF 生成 PDF

          示例中使用官方提供的 CDN 地址 https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js

          <!DOCTYPE html>
          <html lang="en">
            <head>
              <meta charset="UTF-8" />
              <meta name="viewport" content="width=device-width, initial-scale=1.0" />
              <title>Document</title>
              <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
            </head>
            <body>
              <style>
                body {
                  display: grid;
                  place-items: center;
                  margin: 0;
                  background-color: #ccc;
                  min-height: 100vh;
                }
              </style>
              <h1>Hello, jsPDF!</h1>
              <script>
                document.addEventListener("DOMContentLoaded", function () {
                  const pdf=new window.jsPDF();
                  const element=document.body;
          
                  pdf.html(element, {
                    callback: function (pdf) {
                      // Save the PDF to a file or display it
                      pdf.save("output.pdf");
                    },
                  });
                });
              </script>
            </body>
          </html>
          
          

          文檔地址:http://raw.githack.com/MrRio/jsPDF/master/docs/index.html

          3.2.優點

          • jsPDF 完全在客戶端(頁面)上運行,這使它成為在 Web 應用程序中生成 PDF 的一個很好的選擇,而無需外部服務
          • jsPDF 相對易于使用,尤其是對于基本的 PDF 生成任務。您只需幾行 JavaScript 代碼即可創建 PDF 文檔
          • 由于 jsPDF 是一個 JavaScript 庫,它可以與 Web 應用程序無縫集成,并可以與其他 JavaScript 庫和框架一起使用

          3.3.缺點

          • 在客戶端生成 PDF 可能會耗費大量資源,尤其是大型或復雜文檔。這會影響瀏覽器性能或導致內存消耗問題
          • jsPDF 在現代 Web 瀏覽器中得到廣泛支持,但在舊的瀏覽器或具有較少 JavaScript 支持的環境中可能無法按預期工作
          • 與 PDFKit 等服務器端 PDF 生成庫不同,jsPDF 具有有限的高級功能和能力。它可能不適用于復雜的PDF要求。

          4.Puppeteer、jsPDF 和 PDFKit 功能比較

          為便于大家參考,下面總結了 Puppeteer、jsPDF 和 PDFKit 庫在 PDF 生成、文件大小、瀏覽器集成和社區支持方面的比較:

          5.結論

          當為 HTML 轉 PDF 需求選擇實現方案時,可以參考以上實現方案。如果你想從頭開始生成 PDF,PDFKit 可能是你最好的選擇。要通過 HTML 或者 SVG 內容快速轉換為 PDF,jsPDF 可能更合適。對應網頁渲染和交互式內容,強烈建議你選擇 Puppeteer。

          最后,方案選擇在很大程度上還取決于你的項目類型、規范及開發者個人喜好。


          如果文章對你有幫助,歡迎關注和轉發,感謝你的支持!


          主站蜘蛛池模板: 综合激情区视频一区视频二区| 色综合视频一区二区三区| 久久精品国内一区二区三区| 精品不卡一区中文字幕| 成人精品视频一区二区三区| 精品福利一区二区三区| 国产一区二区在线观看app| 精品乱人伦一区二区三区| 久久精品亚洲一区二区三区浴池| 精品人妻AV一区二区三区| 精品国产一区在线观看| 国产伦精品一区二区三区视频金莲| 亚洲啪啪综合AV一区| 国产乱码一区二区三区四| 国产精品美女一区二区 | 国产av一区最新精品| 色多多免费视频观看区一区| а天堂中文最新一区二区三区| 激情一区二区三区| 性色AV一区二区三区无码| 久久婷婷色综合一区二区| 国产精品视频分类一区| 午夜视频久久久久一区 | 中文字幕aⅴ人妻一区二区 | 国产精品一区二区无线| 国产亚洲3p无码一区二区| 中文字幕无码不卡一区二区三区 | 国产在线精品一区二区不卡麻豆| 麻豆一区二区99久久久久| 波多野结衣中文字幕一区| 人妻无码久久一区二区三区免费| 国产一区二区在线观看麻豆| 久久精品黄AA片一区二区三区| 男人免费视频一区二区在线观看 | 国产精品久久久久久麻豆一区| 亚洲乱码国产一区网址| 亚洲一区二区三区在线网站| 超清无码一区二区三区| 成人精品一区二区激情| 久久久国产精品亚洲一区 | 亚洲高清偷拍一区二区三区|