Search code examples
javascripthtmlcssreactjsstyled-components

Show more based on height in React


I have successfully implemented the show more/show less. My problem is that I want to achieve it based on the number of lines or height of the screen. I don't want it to be based on number of characters since it would look bad on certain screens. like kinda cut on larger screen while too long on small screens.

Pls check my codesandbox here CLICK HERE

  <DescriptionText>
    {isShowMore ? text.slice(0, 300) : text}
  </DescriptionText>
  {text && text.length > 300 && (
    <ShowMoreText onClick={toggleReadMore}>
      {isShowMore ? "Show more..." : "Show less"}
    </ShowMoreText>
  )}

Solution

  • Since you are using styled-components I've found a great utility package for it: polished.js

    You would be looking for the ellipsis utility.

    ellipsis

    CSS to represent truncated text with an ellipsis. You can optionally pass a max-width and number of lines before truncating.

    ellipsis(width: (string? | number?)?, lines: number): Styles
    

    Example: Display up to 3 lines when show more, otherwise full text.

    import { ellipsis } from 'polished';
    
    ...
    
    const DescriptionText = styled.div`
      font-size: 14px;
      margin-top: 20px;
      margin-bottom: 20px;
      ${({ showMore }) => showMore && ellipsis(undefined, 3)}
    `;
    
    ...
    
    const Description = () => {
      const [isShowMore, setIsShowMore] = useState(true);
      const toggleReadMore = () => setIsShowMore(show => !show);
    
      return (
        <MainContainer>
          <TitleText>Description</TitleText>
          <DescriptionText showMore={isShowMore}>{text}</DescriptionText>
          <ShowMoreText onClick={toggleReadMore}>
            {isShowMore ? "Show more..." : "Show less"}
          </ShowMoreText>
        </MainContainer>
      );
    };
    

    enter image description here enter image description here

    Edit show-more-based-on-height-in-react

    You seem to have mentioned in another answer that you don't want to add any new dependencies, so here is the CSS that is applied via the ellipsis utility. Though, I'd still recommend adding polished to your project if you can as it has many useful styling utilities I've found fairly invaluable.

    import styled, { css } from "styled-components";
    
    const DescriptionText = styled.div`
      font-size: 14px;
      margin-top: 20px;
      margin-bottom: 20px;
      ${({ showMore }) =>
        showMore &&
        css`
          display: -webkit-box;
          max-width: 100%;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: normal;
          word-wrap: normal;
          -webkit-box-orient: vertical;
          -webkit-line-clamp: 3;
        `}
    `;
    

    To handle different screen sizes/responsiveness you can use media queries and specify a different number of lines you want to initially display.