概要
スクロール要素の端を徐々に透過させるように見せることで、スクロールできる=続きがある感を演出してみました。
CSSにて線形グラデーションでの透過は困難なので、白色グラデーション要素をマスクして上下に霧がかかったように効果をつけることで、透過されているように見せています。
スクロールし切った状態ではこの効果は不要のため、スクロール状態に応じて動的にこの効果を切り替えるようにしました。
実演
See the Pen 上下の霧かけ by itanium (@itanium-R) on CodePen.
つくった経緯
MacにてChromeでWebページを閲覧すると、デフォルトでスクロールバーが非表示であり、スクロールしようとしない限り表示されません。
ブラウザのデフォルト挙動を尊重しつつ続きがある感じを演出するため、よく[続きを見る]を押下させるページにて採用されている白色グラデーションの帯を擬似要素で被せる方式を採用しました。
実装
HTML
<div class="wrap">
<div class="fog-added">
ここに要素の中身を詰め込む。
</div>
</div>
CSS
div.wrap {
display: block;
position: relative;
}
div.fog-added {
width: 300px;
height: 300px;
overflow-y: scroll;
}
div.fog-added::before {
content: "";
width: 100%;
height: 0px;
display: block;
background: linear-gradient(#fff, rgba(255, 255, 255, 0));
position: absolute;
top: 0;
left: 0;
}
div.fog-added::after {
content: "";
width: 100%;
height: 0px;
display: block;
background: linear-gradient(rgba(255, 255, 255, 0), #fff);
position: absolute;
bottom: 0;
left: 0;
}
JavaScript
const fogHeight = 50;
/**
* @param {string} querySelector
* @returns {CSSStyleRule?}
*/
function getCSSRule(querySelector) {
for (const sht of document.styleSheets) {
for (const c of sht.cssRules) {
if (c.selectorText === querySelector) return c;
}
}
}
/**
* @param {Element} target
*/
function addFog(target) {
const remainingScrollHeight =
target.scrollHeight - target.offsetHeight - target.scrollTop;
const topFogHeight = Math.min(
target.scrollTop,
target.offsetHeight / 2,
fogHeight
);
const buttomFogHeight = Math.min(
remainingScrollHeight,
target.offsetHeight / 2,
fogHeight
);
getCSSRule("div.fog-added::before").style.height = `${topFogHeight}px`;
getCSSRule("div.fog-added::after").style.height = `${buttomFogHeight}px`;
}
const fogAddedElm = document.querySelector("div.fog-added");
fogAddedElm.addEventListener("scroll", (e) => addFog(e.target));
addFog(fogAddedElm);
ポイント
- 擬似要素 (before, after) の style は JS で
Element
から直接操作できません。-
document.styleSheets
からCSSStyleRule
を取得し操作することで回避できました。
-
- 霧がかかったような効果をつける範囲は、以下の条件を満たすように決定されるようにしています。
- スクロールし切る端に近づけば近づくほど短くし、端では0pxとする
- 当該要素の外にはみ出さない
- 標準の大きさを超えない
- CSSの
background
の#fff
は配置場所の背景色にあわせることで背景と透過するように演出できます。
考慮事項
-
div.fog-added::before
,div.fog-added::after
が2回定義されるとうまく動きません。 JSのgetCSSRule()
を書き換えれば動くようにできますが、簡単のためこの仕様にしています。 - 今回
add-fog
を class 指定していますが、このコードでは当該 class が1要素のときのみしか考慮していません。複数使いたい時は追加で手を加える必要があります。
おわりに
続きがある感じをどうやって表現すればいいかをデザイナーの方と考えた結果、この表現方法ができました。
デザイナーさんには日々感謝感謝です。
チームのメンバーで知恵を絞りあって、より伝わりやすい表現・UI・UXを考えていきたいですね。