Hello 小夥伴們早上、中午、下午、晚上和深夜好,這裡是 jsliang~
今兒要實現的是:Photo Album 瀑布流相簿
本期將和小夥伴們探討:
- √ 透過簡單幾步,帶大家用 HTML + CSS + JavaScript 速通瀑布流畫冊
本例項的程式碼地址:
本例項系列整體效果可見:https://liangjunrong.github.io/
當然,jsliang 還貼心準備了影片教程,手把手帶你逐步完成:
一 前言
本 CSS 系列文章:
- 主推學以致用。結合面試題和工作例項,讓小夥伴們深入體驗 61 個工作常見的 CSS 屬性和各種 CSS 知識。
- 主推純 CSS。儘可能使用 HTML + CSS 完成學習目的,但仍然有 “一小部分” 功能需要用到 JavaScript 知識,適合新人學習 + 大佬複習。
如果文章在一些細節上沒寫清楚或者誤導讀者,歡迎評論/吐槽/批判,你的關注和點贊是我持續更新的動力,謝謝大家 ❤
- 更多知識分享文章可見:jsliang 的文件庫
二 本期知識點
2.1 @media
關於 @media,小夥伴們在 MDN 上可以看到介紹:
@media
規則可用於基於一個或多個媒體查詢的結果來應用樣式表的一部分。
什麼意思呢?大概就是對於一個元素,你可以指定它在不同裝置下的展示。
例如:
<h1>jsliang 的例項系列</h1>
h1 {
font-size: 36px;
color: deepskyblue;
}
@media screen and (max-width: 1000px) {
h1 {
font-size: 24px;
}
}
這 2 段程式碼,即表示對於 <h1>
元素,在 1000+ px
上,表現為 36px
的字型大小,而在 1000 px
下,則為 24px
大小。
透過這樣 @media
,小夥伴們也可以聯想下,本次需要實現的功能,在不同解析度下如何嘗試實踐出來。
2.2 filter
關於 filter,小夥伴們在 MDN 上可以看到介紹:
- CSS 屬性
filter
將模糊或顏色偏移等圖形效果應用於元素。濾鏡通常用於調整影像、背景和邊框的渲染。
我們很容易就聯想到一些特殊日子,很多網站的置灰效果,有些正是用上了 filter
屬性。
.gray {
filter: grayscale(100%);
filter: gray;
}
當然,本文也會透過 filter
來完成圖片遮罩效果。
三 實現步驟
OK,話不多說,我們開始完成本例項,讓我們開始吧!
3.1 實現一個畫框
對於上面這種效果,在小夥伴們看來,想必是已經熟能生巧:
index.html
<div class="photo-container">
<div class="show">正常顯示</div>
</div>
在這裡,.photo-container
是紅色的,而 .show
是內部的藍色框。
index.css
/* 重置樣式 Start */
body, html { margin: 0; padding: 0; }
body {
display: flex;
justify-content: center;
color: #fff;
font-size: 24px;
}
/* 重置樣式 End */
.photo-container {
width: 400px;
height: 400px;
background: red;
padding: 10px;
position: relative;
}
.show {
width: 100%;
height: 100%;
background: deepskyblue;
}
3.2 實現畫框 hover 出彈窗
在滑鼠 hover 的時候,能出來一個彈窗,遮擋住 .show
這個元素,並且左下角有一個 jsliang
的小文字,想必也很簡單:
index.html
<div class="photo-container">
<div class="show">正常顯示</div>
+ <div class="hover-show">
+ hover 顯示
+ <div class="author">
+ <span>jsliang</span>
+ </div>
+ </div>
</div>
CSS 稍微補充一下:
index.css
/* 大框 hover 後顯示效果 */
.photo-container:hover .hover-show {
display: block;
}
.hover-show {
display: none;
width: calc(100% - 20px);
height: calc(100% - 20px);
background: orange;
position: absolute;
top: 10px;
left: 10px;
}
/* 左下角作者 */
.author {
position: absolute;
left: 0;
bottom: 0;
color: deepskyblue;
font-size: 18px;
background: papayawhip;
padding: 10px;
cursor: pointer;
}
3.3 實現畫框 hover 的彈窗再 hover 出作者詳情
再下來就是在滑鼠 hover 到作者的時候,能展開上邊的「作者 hover 顯示」彈窗,這也不難:
index.html
<div class="photo-container">
<div class="show">正常顯示</div>
<div class="hover-show">
hover 顯示
<div class="author">
<span>jsliang</span>
+ <div class="author-hover-show">
+ 作者 hover 顯示
+ </div>
</div>
</div>
</div>
同樣也是補充一點 CSS:
index.css
/* 作者 hover 出作者詳情 */
.author:hover .author-hover-show {
display: block;
}
.author-hover-show {
display: none;
position: absolute;
width: 200px;
height: 100px;
background: blue;
bottom: 40px;
left: 0px;
}
3.4 Copy 彈窗,透過 JS 實現瀑布流
下面壓力來到 JS 這邊,我們如何「批次」製造響應式瀑布流呢?
這裡我們們挑了「瀑布流的 N 種實現方式」之一來完成:
index.html
<body>
- <!-- 刪除了很多內容 -->
+ <div class="photo-album"></div>
+ <script src="./index.js"></script>
</body>
index.js
window.onload = () => {
// 假裝後臺請求介面給到的圖片資料
const imgList = Array.from(Array(100), (item, index) => index + 1);
const renderDOM = document.querySelector('.photo-album');
let prevMode = 1;
// func: 滾動查詢元素並將 String 累計起來,最終渲染到 renderDOM 節點上
const reduceDOM = (limit) => {
// 生成 limit 條字串
const htmlString = Array.from(Array(limit), () => '<div class="photo-list">');
// 遍歷並將 <img/> 新增到每一列上
imgList.forEach((item, index) => {
const surplus = index % limit;
if (surplus < limit) {
htmlString[surplus] += `
<div class="photo-container">
<div class="show">正常顯示 ${item}</div>
<div class="hover-show">
hover 顯示
<div class="author">
<span>jsliang</span>
<div class="author-hover-show">
作者 hover 顯示
</div>
</div>
</div>
</div>
`;
}
});
// 結尾設定 String
for (let i = 0; i < limit; i++) {
htmlString[i] += '</div>';
}
// 渲染到 HTML 上。記得處理下陣列,要不然會產生逗號
renderDOM.innerHTML = htmlString.join('');
};
// func: 重排節點
const resize = () => {
const width = window.innerWidth;
// 超過 1000px 顯示 3 列,否則顯示 2 列
if (width >= 1000 && prevMode !== 3) {
prevMode = 3;
reduceDOM(prevMode);
} else if (width < 1000 && prevMode !== 2) {
prevMode = 2;
reduceDOM(prevMode);
}
};
// 1、每次進來先執行一遍
resize();
// 2、每次拖拽,判斷是否需要重新渲染
window.onresize = () => {
resize();
};
};
接著我們稍微補充一點 CSS 即可:
index.css
/* 相簿主容器 */
.photo-album {
display: flex;
width: 100%;
}
/* 相簿列表 */
.photo-list {
/* 防擠壓 */
flex-shrink: 0;
width: calc(33% - 20px);
margin-left: 20px;
}
/* 自適應 */
@media screen and (max-width: 1000px) {
.photo-list {
width: calc(50% - 30px);
}
}
這樣,我們就完成了瀑布流相簿的雛形。
3.5 補充「億」點點細節
jsliang 我想學真正的技術,別拿小框框敷衍我!
好的好的,麻瓜讓道,魔法來了~
其實就是照著「Pexels」補充 CSS 細節:
OK,這樣我們本次的 CSS 之旅就完成啦!
本例項的程式碼地址:
本例項系列整體效果可見:https://liangjunrong.github.io/
當然,jsliang 還貼心準備了影片教程,手把手帶你逐步完成:
四 參考文獻
不折騰的前端,和鹹魚有什麼區別!
覺得文章不錯的小夥伴歡迎點贊/點 Star。
如果小夥伴需要聯絡 jsliang:
個人聯絡方式存放在 Github 首頁,歡迎一起折騰~
爭取打造自己成為一個充滿探索欲,喜歡折騰,樂於擴充套件自己知識面的終身學習斜槓程式設計師。
jsliang 的文件庫由 梁峻榮 採用 知識共享 署名-非商業性使用-相同方式共享 4.0 國際 許可協議 進行許可。<br/>基於 https://github.com/LiangJunrong/document-library 上的作品創作。<br/>本許可協議授權之外的使用許可權可以從 https://creativecommons.org/licenses/by-nc-sa/2.5/cn/ 處獲得。