Giới hạn số dòng text với CSS

Như chúng ta đã biết thuộc tính text-overflow: ellipsis; trong CSS được hỗ trợ bởi nhiều trình duyệt khác nhau mặc dù vậy nó chỉ giúp chúng ta giới hạn một dòng text. Vậy đối với trường hợp bạn muốn giới hạn nhiều hơn một dòng text thì sao? Trong bài viết này mình sẽ giới thiệu đến các bạn một trick để thực hiện điều đó với CSS.

Với trình duyệt Chrome và Safari

Chrome và Safari hỗ trợ -webkit ta có thể dùng line-clamps. Line-clamps cho phép bạn đặt số dòng được phép hiển thị và phần text còn lại sẽ bị cắt đi và ta dùng text-overflow: ellipsis để thêm '...' ở cuối dòng. Trước hết ta tạo một mixin với 3 argument font-size , line-heightlines-to-show.

@mixin excerpt($font-size: $paragraph-font-size, $line-height: 1.4, $lines-to-show: 3, $excerpt-bg: transparent) {
  background: $excerpt-bg;
  display: -webkit-box;
  font-size: $font-size;
  line-height: $line-height;
  -webkit-line-clamp: $lines-to-show;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}

Good, mixin trên hoạt động với Chrome, Safari.

Với trình duyệt không hỗ trợ webkit (Firefox, IE...)

Thật không may là line-clamp không được hỗ trợ bới những trình duyệt non-webkit vì vậy ta phải tạo fallback cho những trình duyệt này.

@mixin excerpt($font-size: $paragraph-font-size, $line-height: 1.4, $lines-to-show: 3, $excerpt-bg: transparent) {
  background: $excerpt-bg;
  display: block; /* Fallback for non-webkit */
  display: -webkit-box;
  max-height: $font-size*$line-height*$lines-to-show; /* Fallback for non-webkit */
  font-size: $font-size;
  line-height: $line-height;
  -webkit-line-clamp: $lines-to-show;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  // Fallback for non-webkit
  @media screen and (min--moz-device-pixel-ratio:0), 
  screen and (-ms-high-contrast: active), 
  screen and (-ms-high-contrast: none) {
    overflow: hidden;
    position: relative;
    &:before {
      background: $excerpt-bg;
      bottom: 0;
      position: absolute;
      right: 0;
      float: right;
      content: '\2026';
      margin-left: -3rem;
      width: 3rem;
    }
    &:after {
      content: '';
      background: $excerpt-bg;
      position: absolute;
      height: 50px;
      width: 100%;
      z-index: 1;
    }
  }
}

Ở đây ta đã giới hạn height của container chứa text dựa trên chiều cao số dòng text cần giới hạn. Những dòng text vượt quá chiều cao này sẽ được ẩn đi. Việc cần làm tiếp theo là thêm '...' ở cuối dòng. Ta dùng 2 pseudo elements :before:after. Element :before chứa ellipsis unicode (content: '\2026;') và chỉ được hiển thị khi text dài vượt quá chiều cao tối đa của container. Element :after chứa nội dung rỗng với nhiệm vụ là che đi element :before (dấu '...') khi độ dài text không vượt quá số dòng qui định. Cuối cùng ta cần detect trình duyệt để chỉ áp dụng những psudo element này với trình duyệt non-webkit. Trong mixin trên ta dùng screen and (min--moz-device-pixel-ratio:0) để detect trình duyệt là Firefox và screen and (-ms-high-contrast: active), screen and (-ms-high-contrast: none) để detect trình duyệt là IE 10 trở lên.

Như vậy mình vừa giới thiệu đến các bạn cách để giới hạn text với nhiều dòng. Hi vọng sẽ có ích với các bạn trong những trường hợp cần dùng đến.

References

Targeting IE10 & IE11 Browsers with CSS Multi-line Ellipsis Using Pure CSS As a Workaround