もっと見るボタン付近だけいい感じに透過グラデーションする
2024-02-04
10 months ago
開発環境
- next 14.0.4
- tailwind 3.4.1
前提
コンテンツ中身の高さに応じて「もっと見る」ボタンを出し分けるカスタムフックを実装します。
加えて、「もっと見る」ボタンとコンテンツの間あたりにいい感じの透過グラデーションを入れます。
本題
完成イメージはこちら
containerRefを渡した要素の、中のコンテンツの高さがmax-heightを超えた場合にisOverflowingをtrueで返すHooksを実装します。
また、「もっと見る」ボタンを押下した際にコンテンツをmax-heightいっぱいに広げる関数とstateも一緒に返します。
'use client';
import { useCallback, useEffect, useRef, useState } from 'react';
export const useScrollSize = () => {
const [isOverflowing, setIsOverflowing] = useState(false);
const [isShowAll, setIsShowAll] = useState(false);
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const container = containerRef.current;
if (!container) return;
const checkOverflow = () => {
const isContentOverflowing =
container.scrollHeight > container.clientHeight;
setIsOverflowing(isContentOverflowing);
};
checkOverflow();
window.addEventListener('resize', checkOverflow);
return () => {
window.removeEventListener('resize', checkOverflow);
};
}, []);
const open = useCallback(() => setIsShowAll(true), []);
return { isOverflowing, containerRef, open, isShowAll };
};
そして以下はHooksを利用する例です。
'use client'
import type { ReactNode } from 'react'
import { useScrollSize } from '@/hooks/use-scroll-size'
type ContainerSampleProps = {
children: ReactNode
}
export const ContainerSample = ({ children }: ContainerSampleProps) => {
const { containerRef, isOverflowing, isShowAll, open } = useScrollSize()
return (
<div className='container bg-white py-6'>
<div
className={`
relative flex w-full overflow-y-hidden p-8
${isShowAll ? 'h-full' : 'max-h-60'}
`}
ref={containerRef}
>
{children}
{isOverflowing && !isShowAll && (
<div className='absolute bottom-0 z-10 h-12 w-11/12 bg-gradient-to-b from-white/40 to-white/90' />
)}
</div>
{isOverflowing && !isShowAll && (
<div className='py-4 text-center'>
<button className='hover:underline' onClick={open}>
もっと見る
</button>
</div>
)}
</div>
)
}
さいごに
一定の高さで要素の表示/非表示を切り替える実装はよくありますが、そこにプラスアルファで「まだ要素が下にあるよ」というレイアウト実装例です。
tailwindでもっと良いやり方があれば知りたい・・