Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple lines in a box which have ellipsis and vertical-align middle

Tags:

html

css

I have containers which have dynamic content and multiple lines of text. I want to show ellipsis (...) if the text does not fit into the container. Also it should be vertically aligned middle.

I created a Codepen http://codepen.io/anon/pen/ewnxG with this HTML:

<div class="vertically-centered">vertically centered with</div>
<div class="vertically-centered">vertically centered with hello</div>
<div class="vertically-centered">one line</div>

and this CSS:

.vertically-centered {
  border: 1px solid red;
  height: 6rem;
  overflow: hidden;
  font-weight: bold;
  font-size: 2.5rem;
  text-overflow: ellipsis;
  width: 300px;
  line-height: 1.2;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.vertically-centered:after {
  content: "";
  height: 100%;
  display: inline-block;
  vertical-align: middle;
}

In IE11 and Firefox the ellipsis "..." are missing, that is okay to me. In Safari and Chrome it works.

You see, that the first div does not work, the text is cut off. The second and third div works. So my solution is dependent on the text length. How can I solve this problem without using JavaScript?

like image 690
Tim Avatar asked Sep 08 '14 07:09

Tim


2 Answers

Please check this simple solution with no additional markup:

.vertically-centered {
    border: 1px solid red;
    height: 6rem;
    overflow: hidden;
    font-weight: bold;
    font-size: 2.5rem;
    text-overflow: ellipsis;
    width: 300px;
    line-height: 1.2;
    display: flex;  /* enables centering for modern non-webkit browsers */
    flex-direction: column;
    justify-content: space-around; /* centers for modern non-webkit browsers */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    -webkit-box-pack: center; /* centers in -webkit-box automagically! */
}
<div class="vertically-centered">vertically centered with</div>
<div class="vertically-centered">vertically centered with hello</div>
<div class="vertically-centered">one line</div>
You can also see this solution in action in the edited CodePen example.

How it works: your original code is already using Flexbox layout for WebKit-based browsers (in fact, it's outdated 2009 syntax of Flexbox, but, unfortunately, -webkit-line-clamp doesn't work with new implementations). Flexbox has its own mechanism for vertical centering. All you need to get the desired behavior in WebKit-based browsers is to remove the :after pseudo-element and to add instead the following line of code to .vertically-centered:

   -webkit-box-pack: center;

For other modern browsers, like Firefox 22+ and IE11+, the same layout (except the ellipsis, but you said it's OK) can be achieved by using the new version of Flexbox:

   display: flex;
   flex-direction: column;
   justify-content: space-around;

This must be place above display: -webkit-box in the code, so Webkit-browsers will still be able to apply -webkit-line-clamp.

You can also make it work in IE10 by adding its prefixed version of Flexbox (2011 transitional syntax):

   display: -ms-flexbox;
   -ms-flex-direction: column;
   -ms-flex-pack: center;

The pen with IE10 support is here: http://codepen.io/anon/pen/otHdm

The :after vertical centering approach didn't work for you in first 'cell' for the following reason: for ilnine-level CSS boxes (like usual text, inline blocks, images etc.) vertical-align adjusts the baselines of all such boxes that form a line box (see CSS2.1 spec). The height of the line box is computed so that all inline-level boxes in the line fit into it, so the height of the line box can't be less than the height of the tallest inline-level box in it. So your :after inline block, which gets 100% of the container height, becomes the tallest element in the last line of your block, and because of vertical-align: middle the baseline of the text in that last line is moved to meet the vertical middle of the text with the middle of this tall inline-block. This is OK when there is only one lime (it's the typical use case for such centering) and when the last line is hidden with overflow, but not OK when it's visible).

like image 128
Ilya Streltsyn Avatar answered Sep 23 '22 13:09

Ilya Streltsyn


here you can find a simplified solution:

.vertically-centered {
  margin: 0 auto;
  border: 1px solid red;
  font-size: 50px;
  width: 300px;
  display: -webkit-flex;
  -webkit-align-items: center;
}

.vertically-centered p {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  max-height: 106px; /* set max-height for ie */
}

for a markup like this:

<div class="vertically-centered"><p>vertically centered with</p></div>
<div class="vertically-centered"><p>vertically centered with hello</p></div>
<div class="vertically-centered"><p>one line</p></div>

an example: http://codepen.io/srekoble/pen/pHgjf

As you will see you could wrap your text inside a p tag so you can apply the truncate method to p tag and the vertical align method to div tag

like image 23
Vangel Tzo Avatar answered Sep 24 '22 13:09

Vangel Tzo