I have a paragraph tag I am wanting to check if the ellipsis is showing, but I am using the -webkit-line-clamp
css property.
I have the following ponent and hook, however using width values doesn't work. The values for scrollWidth
, clientWidth
and offsetWidth
are always the same value.
const Description = ({ data }: Props) => {
const [open, setOpen] = useState<boolean>(false);
const ref = useRef<HTMLParagraphElement>(null);
const isTruncated = useIsTruncated(ref);
return (
<>
<div className="my-3 max-h-[4.5rem] relative">
<p ref={ref} className="inline line-clamp-3">
{data.description}
</p>
{isTruncated && (
<button
className="text-blue-600 leading-none absolute bottom-0 right-0 font-medium"
onClick={() => setOpen(true)}
>
more
</button>
)}
</div>
<Modal open={open} setOpen={setOpen} />
</>
);
};
const useIsTruncated = (element: RefObject<HTMLParagraphElement>) => {
const determineIsTruncated = () => {
if (!element.current) return false;
return element.current.scrollWidth > element.current.clientWidth;
};
const [isTruncated, setIsTruncated] = useState(determineIsTruncated());
useEffect(() => {
const resizeListener = () => setIsTruncated(determineIsTruncated());
window.addEventListener("resize", resizeListener);
return () => {
window.removeEventListener("resize", resizeListener);
};
}, []);
return isTruncated;
};
Is this possible using -webkit-line-clamp
?
I am using tailwindcss, the css for line-clamp-3
is:
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
I have a paragraph tag I am wanting to check if the ellipsis is showing, but I am using the -webkit-line-clamp
css property.
I have the following ponent and hook, however using width values doesn't work. The values for scrollWidth
, clientWidth
and offsetWidth
are always the same value.
const Description = ({ data }: Props) => {
const [open, setOpen] = useState<boolean>(false);
const ref = useRef<HTMLParagraphElement>(null);
const isTruncated = useIsTruncated(ref);
return (
<>
<div className="my-3 max-h-[4.5rem] relative">
<p ref={ref} className="inline line-clamp-3">
{data.description}
</p>
{isTruncated && (
<button
className="text-blue-600 leading-none absolute bottom-0 right-0 font-medium"
onClick={() => setOpen(true)}
>
more
</button>
)}
</div>
<Modal open={open} setOpen={setOpen} />
</>
);
};
const useIsTruncated = (element: RefObject<HTMLParagraphElement>) => {
const determineIsTruncated = () => {
if (!element.current) return false;
return element.current.scrollWidth > element.current.clientWidth;
};
const [isTruncated, setIsTruncated] = useState(determineIsTruncated());
useEffect(() => {
const resizeListener = () => setIsTruncated(determineIsTruncated());
window.addEventListener("resize", resizeListener);
return () => {
window.removeEventListener("resize", resizeListener);
};
}, []);
return isTruncated;
};
Is this possible using -webkit-line-clamp
?
I am using tailwindcss, the css for line-clamp-3
is:
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
So the trick with this was to check the height, not width.
const determineIsTruncated = () => {
if (!element.current) return false;
return element.current.scrollHeight > element.current.clientHeight;
};
The accepted answer is not correct, or well the original code in the question is not correct, as it always returns false. This code works:
const useIsTruncated = element => {
const determineIsTruncated = () => {
if (!element.current) return false;
return element.current.scrollWidth > element.current.clientWidth;
};
useEffect(() => {
if (!element.current) return false;
return setIsTruncated(
element.current.scrollHeight > element.current.clientHeight,
);
}, element.current);
const [isTruncated, setIsTruncated] = useState(determineIsTruncated());
useEffect(() => {
const resizeListener = () => setIsTruncated(determineIsTruncated());
window.addEventListener('resize', resizeListener);
return () => {
window.removeEventListener('resize', resizeListener);
};
}, []);
return isTruncated;
};