25

I'm looking for a way to create a slide out 'show more' feature on my responsive site, which cuts off after two lines of a paragraph.

I've achieved this before with a static website, by applying a set height to the container and using overflow: hidden, and then animating the height of the container.

But being responsive, the container squashes the text at different browser widths, so the text might take up more/less room. Also there may be different content above the paragraph each time pushing it down. So the setting height might not cover two lines exactly.

Please check out this jsFiddle: http://jsfiddle.net/XVAzU/ if you need to demonstrate.

So I need to cut off after two lines of the paragraph, no matter what width the container is or what comes before or after that paragraph.

Thanks for looking!

shrewdbeans
  • 11,971
  • 23
  • 69
  • 115
  • 1
    Using CSS you can apply `line-height: 1em` and `height: 2em` which should always show two lines. I don't know about cross-browser compatibility but the DEMO I attached to my answer shows only two lines of the text as expected in Chrome, FireFox, IE9 and IE8. – Nope Sep 06 '12 at 21:02

4 Answers4

33

Starting from your fiddle and wrapped the content into a <div> with a default class of content, used for selection and a class called hideContent which will be swapped with showContent when clicking the show more/show less link.

I also removed the <p> the text was in. The text is now within the content-div and we are also now able to apply correct height and line-height settings.

HTML:

<div class="text-container">
    <h1>Title goes here</h1>
    <h2>Subtitle</h2>
    <div class="content hideContent">
        Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
        <p>Some more text</p>
        <ul>
            <li>Some more text</li>
            <li>Some more text</li>
            <li>Some more text</li>
        </ul>
    </div>
    <div class="show-more">
        <a href="#">Show more</a>
    </div>
</div>​

CSS:

.hideContent {
    overflow: hidden;
    line-height: 1em;
    height: 2em;
}

.showContent {
    line-height: 1em;
    height: auto;
}

I'm assuming setting the line-height will ensure it is the same in all browsers. I'm not 100% certain on that though.

I attached a click event to the "show more" link which switches the classes on the div using jQueryUI switchClass():

$(".show-more a").on("click", function() {
    var $this = $(this); 
    var $content = $this.parent().prev("div.content");
    var linkText = $this.text().toUpperCase();    

    if(linkText === "SHOW MORE"){
        linkText = "Show less";
        $content.switchClass("hideContent", "showContent", 400);
    } else {
        linkText = "Show more";
        $content.switchClass("showContent", "hideContent", 400);
    };

    $this.text(linkText);
});​

JsFiddle Demo - show more / show less and applying line-height and animation

$(".show-more a").on("click", function() {
  var $this = $(this);
  var $content = $this.parent().prev("div.content");
  var linkText = $this.text().toUpperCase();

  if (linkText === "SHOW MORE") {
    linkText = "Show less";
    $content.switchClass("hideContent", "showContent", 400);
  } else {
    linkText = "Show more";
    $content.switchClass("showContent", "hideContent", 400);
  };

  $this.text(linkText);
});
div.text-container {
  margin: 0 auto;
  width: 75%;
}

.hideContent {
  overflow: hidden;
  line-height: 1em;
  height: 2em;
}

.showContent {
  line-height: 1em;
  height: auto;
}

.showContent {
  height: auto;
}

h1 {
  font-size: 24px;
}

p {
  padding: 10px 0;
}

.show-more {
  padding: 10px 0;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>

<div class="text-container">
  <h1>Title goes here</h1>
  <h2>Subtitle</h2>
  <div class="content hideContent">
    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata
    sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
    <p>Some more text</p>
    <ul>
      <li>Some more text</li>
      <li>Some more text</li>
      <li>Some more text</li>
    </ul>
  </div>
  <div class="show-more">
    <a href="#">Show more</a>
  </div>
</div>

The above code is an example only but should get you started into the right direction.

Nope
  • 22,147
  • 7
  • 47
  • 72
  • 1
    I was working on something similar, but i think i like your solution more. Just as an alternative http://jsfiddle.net/XVAzU/4/. I would set the initial class to showContent though, and replace it with the hideContent class in js on load of the document, just for people that have js disabled. – Pevara Sep 06 '12 at 21:30
  • @owen: Let me know if this is what you were looking for or if you need any additional help with that. – Nope Sep 08 '12 at 01:28
  • @François Wahl, looking at your jsFiddle, it looks perfect! Thank you for the time you put into this. I haven't had time myself to test it on the actual site yet, something urgent has come up, but I'm going to mark the answer as correct, as the jsFiddle is just what I was looking for. – shrewdbeans Sep 10 '12 at 11:09
  • @Owen: No worries, if you need a hand for some troubleshooting let me know. – Nope Sep 10 '12 at 11:21
  • nice example @FrançoisWahl, worked perfectly for what I needed – Robert Petz Feb 08 '14 at 00:15
  • @RobertPetz: Thank you. Glad you found it useful. – Nope Feb 08 '14 at 01:08
  • @FrançoisWahl This code is working fine on DEMO. but when i copyied it in my hard drive. it dont work any more. do you have any idea why. I have added jquery in my html too – Adnan Ali Feb 14 '16 at 18:34
  • @Nope I would recommend `overflow-y: hidden;` on `.showContent`, as in certain conditions there is a flicker when the content gets closed – Binar Web Apr 24 '19 at 10:22
9

If you're searching for a css only solution check this out:

HTML

 <div class="show-hide-text">
  <a  id="show-more" class="show-less" href="#show-less">Show less</a>
  <a  id="show-less" class="show-more" href="#show-more">Show more</a>
  <p>
    Lorem Ipsum is simply dummy text of  the printing and typesetting industry...
  </p>
</div>

// CSS

.show-hide-text {
  display: flex;
  flex-wrap: wrap;
}

.show-hide-text a {
  order: 2;
}

.show-hide-text p {
  position: relative;
  overflow: hidden;
  max-height: 60px; // The Height of 3 rows
}

.show-hide-text p {
  display: -webkit-box;
  -webkit-line-clamp: 3; // 3 Rows of text
  -webkit-box-orient: vertical;
}

.show-less {
  display: none;
}

.show-less:target {
  display: block;
}

.show-less:target ~ p {
  display: block;
  max-height: 100%;
}

.show-less:target + a {
  display: none;
}

An example: https://codepen.io/srekoble/pen/WGBzZa?editors=1100

Vangel Tzo
  • 8,885
  • 3
  • 26
  • 32
1

My suggestion to solve the problem

$("#slider_desc_toogler").on( "click", function() { 
  $('#slider_desc_toogler > i').toggleClass('fa-arrow-circle-down')
  $('#slider_desc_toogler > i').toggleClass('fa-arrow-circle-up')
  if ($("#slider_desc_toogler > i").hasClass( "fa-arrow-circle-down" )) {
    $(".slider_desc").css("max-height","38px");
  } else $(".slider_desc").css("max-height","500px");
});
.slider_desc {
  margin: 16px;
  margin-top: 0px;
  color: #333333;
  font-family: Arial;
  font-size: 14px;
  line-height: 18px;
  text-align: justify;
  overflow: hidden;
  transition: all 0.5s ease 0s;
  max-height: 38px;
}

#slider_desc_toogler{
  border-top: silver 1px dotted;
  margin-bottom: 30px;
  margin-top: 20px;
  width: 70%;
  margin-left: auto;
  margin-right: auto;
}

#slider_desc_toogler i {
      position: absolute;
      text-align: center;
      color: silver;
      font-size: 25px;
      font-family: fontawesome;
      left: calc(50% - 10px);
      margin-top: -13px;
      background: #fff;
  }
<link href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<div class="slider_desc">
            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, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.


            </div>
            <div id="slider_desc_toogler"><i class="fas fa-arrow-circle-down"></i></div>
m4rlb0r0
  • 11
  • 1
0

I modified the previous code to NOT use jQueryUI switchClass(), here you are:

$(document).ready(function() {
  $(".show-more a").on("click", function() {
    var $this = $(this); 
    var $content = $this.parent().prev("div.content");
    var linkText = $this.text().toUpperCase();    

    if (linkText === "SHOW MORE") {
      linkText = "Show less";
      $content.removeClass("hideContent");
      $content.addClass("showContent");
    } else {
      linkText = "Show more";
      $content.removeClass("showContent");
      $content.addClass("hideContent");
    };

    $this.text(linkText);
  });
});
div.text-container {
  margin: 0 auto;
  width: 75%;    
}

.hideContent {
  overflow: hidden;
  line-height: 1em;
  height: 2em;
}

.showContent {
  line-height: 1em;
  height: auto;
}
.showContent{
  height: auto;
}

h1 {
  font-size: 24px;        
}
p {
  padding: 10px 0;
}
.show-more {
  padding: 10px 0;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>

<div class="text-container">
  <h1>Title goes here</h1>
  <h2>Subtitle</h2>
  <div class="content hideContent">
    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
    <p>Some more text</p>
    <ul>
      <li>Some more text</li>
      <li>Some more text</li>
      <li>Some more text</li>
    </ul>
  </div>
  <div class="show-more">
    <a href="#">Show more</a>
  </div>
</div>
Tyler2P
  • 2,324
  • 26
  • 22
  • 31