skip to Main Content

I have set a white-space: nowrap with text-overflow: ellipsis in some text and, when the user hovers, it should change the white-space value to normal. The hover code works fine, but I cant make the transitions work.

This is the CodePen link: https://codepen.io/anon/pen/qwYoyR

.App p {
  margin-bottom: 3px;
}
.App .bg-row {
  box-shadow: 0px 0px 5px #bdc3c7;
  background-color: #ecf0f1a3;
  padding: 20px;
  border-radius: 5px;
}
.App .bg-row .repositorios {
  transition: all 0.2s ease;
  margin-bottom: 20px;
}
.App .bg-row .repositorios:hover .repo-content {
  background-color: #d2d6d8;
  transition: 500ms ease-in-out;
}
.App .bg-row .repositorios .repo-image {
  width: 100%;
  height: auto;
  box-shadow: 0px 0px 5px #bdc3c7;
  -webkit-transition: all 0.2s ease;
  -moz-transition: all 0.2s ease;
  -o-transition: all 0.2s ease;
}
.App .bg-row .repositorios .repo-content {
  padding: 10px;
  transition: 500ms ease-in-out;
  overflow: hidden;
  box-shadow: 0px 0px 5px #bdc3c7;
  transition: 500ms ease-in-out;
  background-color: #ecf0f1;
}
.App .bg-row .repositorios .repo-content p {
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
}
.App .bg-row .repositorios .repo-content .read-more {
  transition: 500ms ease-in-out;
  cursor: pointer;
}
.App .bg-row .repositorios .repo-content .read-more:hover {
  white-space: normal;
  transition: 500ms ease-in-out;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container App">
  <div class="row bg-row">
    <div class="col-sm-6 col-md-4 col-lg-3 repositorios">
      <div class="repo-content">
        <p class="read-more">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s</p>
      </div>
    </div>
  </div>
</div>

7

Answers


  1. I don’t think you can animate this with css only. To animate the height you need to set it explicitly. I’d try to get the real height with js, limit the height and then apply the height in js on hover.

    Login or Signup to reply.
  2. CodePen example you can check

    You need to fixed width of col-sm-6 col-md-4 col-lg-3 = “100%” this way you achieve your answer

    <div class="container App">
        <div class="row bg-row">
          <div class="repositorios">
            <div class="repo-content">
              <p class="read-more">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s</p>
          </div>
      </div>
    </div>
    

    Apply this CSS it will work for you

    .App {
      p {
        margin-bottom: 3px;
      }
      .bg-row {
        box-shadow: 0px 0px 5px #bdc3c7;
        background-color: #ecf0f1a3;
        padding: 20px;
        border-radius: 5px;
        .repositorios {
          transition: all 0.2s ease;
          margin-bottom: 20px;
          &:hover {
            .repo-content {
              background-color: #d2d6d8;
              transition: 500ms ease-in-out;
            }
          }
          .repo-image {
            width: 100%;
            height: auto;
            box-shadow: 0px 0px 5px #bdc3c7;
            -webkit-transition: all 0.2s ease;
            -moz-transition: all 0.2s ease;
            -o-transition: all 0.2s ease;
          }
          .repo-content {
            padding: 10px;
            transition: 500ms ease-in-out;
            overflow: hidden;
            box-shadow: 0px 0px 5px #bdc3c7;
            transition: 300ms ease-in-out;
            background-color: #ecf0f1;
            p {
              white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
        width: 200px;
            }
            .read-more {
              transition: 500ms ease-in-out;
              cursor: pointer;
              &:hover {
                white-space: normal;
        transition: 300ms ease-in-out;
        width: 100%;
              }
            }
          }
        }
      }
    }
    
    Login or Signup to reply.
  3. Or you can do it with Jquery like in this codepen

    $('.repo-content').hover(function(e){
      $(this).animate({height: '100%'}, 100);
      $('.bg-row.row').animate({height: '100%'}, 500);
    },function(){
      $(this).animate({height: '50px'}, 500);
    });
    .App p {
      
    	 margin-bottom: 3px;
    }
     .App .bg-row {
       transition: 500ms ease-in-out;
    	 box-shadow: 0px 0px 5px #bdc3c7;
    	 background-color: #ecf0f1 a3;
    	 padding: 20px;
       z-index:99;
       height:100px;
    	 border-radius: 5px;
    }
     .App .bg-row .repositorios {
    	 transition: all 0.2s ease;
    	 margin-bottom: 20px;
    }
     .App .bg-row .repositorios:hover .repo-content {
    	 background-color: #d2d6d8;
    	 transition: 500ms ease-in-out;
    }
     .App .bg-row .repositorios .repo-image {
    	 width: 100%;
    	 height: auto;
    	 box-shadow: 0px 0px 5px #bdc3c7;
    	 -webkit-transition: all 0.2s ease;
    	 -moz-transition: all 0.2s ease;
    	 -o-transition: all 0.2s ease;
    }
     .App .bg-row .repositorios .repo-content {
    	 padding: 10px;
    	 overflow: hidden;
       height:50px;
    	 box-shadow: 0px 0px 5px #bdc3c7;
    	 background-color: #ecf0f1;
    }
     .App .bg-row .repositorios .repo-content p {
    	 text-overflow: ellipsis;
    	 overflow: hidden;
     
    }
     .App .bg-row .repositorios .repo-content .read-more {
    	 transition: 500ms ease-in-out;
    	 cursor: pointer;
       z-index:99;
    }
     .App .bg-row .repositorios .repo-content .read-more:hover {
    	 
    	 transition: 500ms ease-in-out;
    }
    <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="container App">
        <div class="row bg-row">
          <div class="col-sm-6 col-md-4 col-lg-3 repositorios">
            <div class="repo-content">
              <p class="read-more">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s</p>
          </div>
    </div>
    </div>
      </div>

    BTW, I don’t know scss so i converted your scss to css, I apologize for that.

    Login or Signup to reply.
  4. The issue is because white-space is not an animate-able property. You can animate max-height property – see updated codepen and relevant excerpt:

     .read-more {
          transition: 500ms ease-in-out;
          cursor: pointer;
          max-height: 2em; /* added */
          &:hover {
            white-space: normal;
            max-height: 100vh; /* added */
            transition: 500ms ease-in-out;
          }
        }
    

    But when hover is off, the return animation will not work as white-space: nowrap ruins it.


    Here is a hacky solution that just uses max-height for the transition and the ellipsis is handled by a pseudo element – see codepen and snippet below:

    .App p {
      margin-bottom: 3px;
    }
    .App .bg-row {
      box-shadow: 0px 0px 5px #bdc3c7;
      background-color: #ecf0f1a3;
      padding: 20px;
      border-radius: 5px;
    }
    .App .bg-row .repositorios {
      margin-bottom: 20px;
    }
    .App .bg-row .repositorios:hover .repo-content {
      background-color: #d2d6d8;
    }
    .App .bg-row .repositorios:hover .repo-content .read-more {
      transition: all 500ms ease-in-out;
      white-space: normal;
      max-height: 100vh;
    }
    .App .bg-row .repositorios:hover .repo-content .read-more:after {
      transition: all 0.5s linear;
      opacity: 0;
    }
    .App .bg-row .repositorios .repo-image {
      width: 100%;
      height: auto;
      box-shadow: 0px 0px 5px #bdc3c7;
    }
    .App .bg-row .repositorios .repo-content {
      padding: 10px;
      overflow: hidden;
      box-shadow: 0px 0px 5px #bdc3c7;
      background-color: #ecf0f1;
    }
    .App .bg-row .repositorios .repo-content p {
      overflow: hidden;
    }
    .App .bg-row .repositorios .repo-content .read-more {
      transition: all 500ms ease-in-out;
      text-align: justify;
      display: flex;
      cursor: pointer;
      max-height: 1.7em;
      /* added */
    }
    .App .bg-row .repositorios .repo-content .read-more:after {
      transition: all 0.5s linear;
      content: '...';
      opacity: 1;
    }
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css">
    
    <div class="container App">
        <div class="row bg-row">
          <div class="col-sm-6 col-md-4 col-lg-3 repositorios">
            <div class="repo-content">
              <p class="read-more">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s</p>
          </div>
    </div>
    </div>
      </div>
    Login or Signup to reply.
  5. These are not properties which can be transitioned.

    white-space: nowrap;
    text-overflow: ellipsis;
    

    In order to transition to one property to another, CSS requires intermediary values.
    There are no intermediary values from nowrap to normal, as there are no intermediary values from heright: 0 to auto, or from display: none to block.

    The only way to achieve this with CSS is to use max-height for your element, and transition that on hover. Yet, the white-space/ellipsis themselves would have to go => replace them with a pseudo-element with the same backgroundColor as the parent:

    .x {
        position: relative;
        overflow: hidden;
    
        max-height: 20px;                /* set this to the height your first row would be */
        background-color: red;           /* you can change this, ofc */
        transition: max-height .5s;      /* the duration of the transition */
    }
    .x:after {
        content: '...';
        position: absolute;
        top: 0; right: 0;
    
        height: 1.5em;                   /* positioning it in line with the text - hacky */
        padding: 0 .2em;
        background-color: red;           /* keep the same as parent - it cannot be transparent unfortunately */
    
        opacity: 1;
        transition: opacity 0s .5s;      /* will delay the appearance of the '...' until the expanding transition has finished */
    }
    .x:hover {
        max-height: 1000px;              /* can be lower to create smoother response time */
    }
    .x:hover::after {
        opacity: 0;
        transition: opacity 0s 0s;       /* will apply the appearance of the '...' when hovered */
    }
    

    Hacky, improvable, but working with only CSS.

    Login or Signup to reply.
  6. This can be achieve with height: auto but CSS transition required height fixed value. But you can resolve this by using jQuery. I just write a basic mouseenter, mouseleave method and some logic to get content expand/collapse height. All mentioned changes applied on below code, you can also review the working fiddle. I hope it’ll help you out. Thanks

    Working Fiddle Example – https://jsfiddle.net/creative_sid5/bgpus3q6/42/

    var rm = $('.read-more');   
    var rmInitialHeight = 0;
    var rmExpandedHeight = rm.outerHeight() + 'px';
    rm.removeClass('active');
    setTimeout(function(){
      rmInitialHeight = rm.outerHeight() + 'px';
      rm.height(rmInitialHeight);
    }, 500)
    rm.mouseenter(function() {	    		
      toggle(rmExpandedHeight);
    });
    rm.mouseleave(function() {	    		
      toggle(rmInitialHeight);
    })  
    
    function toggle(h) {
      rm.toggleClass('active').css('height', h);
    }
    .App p {
      margin-bottom: 3px; }
    
    .App .bg-row {
      box-shadow: 0px 0px 5px #bdc3c7;
      background-color: #ecf0f1a3;
      padding: 20px;
      border-radius: 5px; }
      .App .bg-row .repositorios {
        transition: all 0.2s ease;
        margin-bottom: 20px; }
        .App .bg-row .repositorios:hover .repo-content {
          background-color: #d2d6d8;
          transition: 500ms ease-in-out; }
        .App .bg-row .repositorios .repo-image {
          width: 100%;
          height: auto;
          box-shadow: 0px 0px 5px #bdc3c7;
          -webkit-transition: all 0.2s ease;
          -moz-transition: all 0.2s ease;
          -o-transition: all 0.2s ease; }
        .App .bg-row .repositorios .repo-content {
          padding: 10px;
          transition: 500ms ease-in-out;
          overflow: hidden;
          box-shadow: 0px 0px 5px #bdc3c7;
          transition: 500ms ease-in-out;
          background-color: #ecf0f1; }
          .App .bg-row .repositorios .repo-content .read-more {
            transition: 500ms ease-in-out;
            cursor: pointer;
            white-space: nowrap;
            text-overflow: ellipsis;
            overflow: hidden; }
          .App .bg-row .repositorios .repo-content .active {
            white-space: normal; }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
    
    <div class="container App">
      <div class="row bg-row">
        <div class="col-sm-6 col-md-4 col-lg-3 repositorios">
          <div class="repo-content">
            <p class="read-more active">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s</p>
          </div>
        </div>
      </div>
    </div>
    Login or Signup to reply.
  7. I’v got here an example using React and CSS, but you can achieve the same in plain JS or a framework of your choice.
    The key thing here is to measure the element expanded(hidden, cloned one) height and collapsed height and then handle animation by CSS transition.

    import React, { useState } from "react";
    
    const ShowMore = ({ text }) => {
      const [isOpen, toggle] = useState(false);
      const [
        isOnGoingCollapseTransition,
        setisOnGoingCollapseTransition
      ] = useState(false);
      const [initialHeight, setInitialHeight] = useState(0);
      const ref = React.useRef();
      const measureRef = React.useRef();
      React.useLayoutEffect(() => {
        setInitialHeight(ref.current.getBoundingClientRect().height);
      }, []);
      const onTransitionEnd = () => {
        if (isOpen) {
          setisOnGoingCollapseTransition(true);
        } else {
          setisOnGoingCollapseTransition(false);
        }
      };
      return (
        <div className="relative">
          <div className="absolute hidden" ref={measureRef}>
            {text}
          </div>
          <div
            onTransitionEnd={onTransitionEnd}
            className="overflow-hidden transition"
            style={{
              height: isOpen
                ? measureRef.current.getBoundingClientRect().height
                : initialHeight
            }}
          >
            <div
              ref={ref}
              className={
                !isOpen && !isOnGoingCollapseTransition ? "overflow-ellipsis" : ""
              }
            >
              {text}
            </div>
          </div>
          <span className="text-blue" onClick={() => toggle(open => !open)}>
            {isOpen ? <span>show less</span> : <span>show more</span>}
          </span>
        </div>
      );
    };
    
    export default ShowMore;
    

    CSS:

        .relative{
          position: relative;
        }
        .absolute{
          position: absolute;
        }
        .overflow-ellipsis{
          white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        .overflow-hidden{
          overflow: hidden;
        }
        .text-blue{
          color: blue;
          cursor: pointer;
        }
        .transition{
          transition: 225ms height linear;
        }
        .hidden{
          transform: translate(1000px);
        }
    

    Checkout this working example Ellipsis collapse transition

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search