Pure CSS - Several Read more Read less
As I asked my question I kept on working on the solution.
Please find snippet in question as the working solution.
Pure CSS - Read more/Read Less images
Should be able to use the same idea for the height of all images inside the .read-more-target
.
Something like this:
.read-more-target img {
height: 0;
}
.read-more-state:checked ~ .read-more-wrap .read-more-target img {
height: auto;
}
Here is an edit to your fiddle that does this: https://jsfiddle.net/xrtxqu94/20/
Pure CSS Read More/Less button not working
The problem is your label is not in the same level in your site. The operator ~
will target the siblings elements only, not their child or grandchild. Let me explain with the example. Look at the below code.
.test ~ .example {
background:green;
}
<p class="test">Test</p>
<p class="nothing">Nothing</p>
<p class="example">Example</p>
<p><span class="example">Second Level Example</span></p>
How to implement Read more / Read less in pure CSS
How does the CodePen achieve this behavior?
All that the code in the demo does is modify the max-height
of the wrapper div
based on the check-box being checked or unchecked and whilst doing so also change the content of the label
.
Now lets have a look at the key individual selectors in CSS that help perform this:
.read-more-state:checked ~ .read-more-wrap .read-more-target
- This selector means that when an
input
withclass = 'read-more-state'
is checked, select the elements withclass = 'read-more-target'
which are present under a wrapper withclass = 'read-more-wrap'
when the wrapper is also a sibling of the checkbox (the reference element).
.read-more-state ~ .read-more-trigger:before
- This is the one that populates the default text for the
label
. What it does is set thecontent
as "Show more" for the::before
element oflabel
withclass = 'read-more-trigger'
when thelabel
is also a sibling of the checkbox.
.read-more-state:checked ~ .read-more-trigger:before
- This is the one that modifies the text of the
label
when the checkbox is clicked. The selector means that when theinput
withclass = 'read-more-state'
is:checked
, set thecontent
of the label's before element as "Show less".
Also, note the for
attribute in the label
tag. The value of this field points to the id
of the input
tag and so whenever the label is clicked, the input
element's state gets toggled automatically. This will happen irrespective of where in DOM the label
and input
elements are.
.read-more-state {
display: none;
}
.read-more-target {
opacity: 0;
max-height: 0;
font-size: 0;
transition: .25s ease;
}
.read-more-state:checked ~ .read-more-wrap .read-more-target {
opacity: 1;
font-size: inherit;
max-height: 999em;
}
.read-more-state ~ .read-more-trigger:before {
content: 'Show more';
}
.read-more-state:checked ~ .read-more-trigger:before {
content: 'Show less';
}
.read-more-trigger {
cursor: pointer;
display: inline-block;
padding: 0 .5em;
color: #666;
font-size: .9em;
line-height: 2;
border: 1px solid #ddd;
border-radius: .25em;
}
/* Other style */
body {
padding: 2%;
}
p {
padding: 2%;
background: #fff9c6;
color: #c7b27e;
border: 1px solid #fce29f;
border-radius: .25em;
}
<div>
<input type="checkbox" class="read-more-state" id="post-1" />
<p class="read-more-wrap">Lorem ipsum dolor sit amet, consectetur adipisicing elit. <span class="read-more-target">Libero fuga facilis vel consectetur quos sapiente deleniti eveniet dolores tempore eos deserunt officia quis ab? Excepturi vero tempore minus beatae voluptatem!</span>
</p>
<label for="post-1" class="read-more-trigger"></label>
</div>
<div>
<input type="checkbox" class="read-more-state" id="post-2" />
<ul class="read-more-wrap">
<li>lorem</li>
<li>lorem 2</li>
<li class="read-more-target">lorem 3</li>
<li class="read-more-target">lorem 4</li>
</ul>
<label for="post-2" class="read-more-trigger"></label>
</div>
how to add read more/read less after 3 paragraphs inside div with multiple paragraphs
This code should work. It first splits the text based on "</p>
" to get the paragraphs and then print the top 3 only. And then adds Read More link to it.
var paraHolder = document.getElementsByClassName("page-content")[0];
var readMore = paraHolder.innerHTML;
var para = readMore.split("</p>");
var maxParas = 4;
if (maxParas < para.length - 1) {
paraHolder.innerHTML = "";
for (i = 0; i <= maxParas - 1; i++) {
paraHolder.innerHTML += para[i] + "</p>";
}
readLess = paraHolder.innerHTML;
paraHolder.innerHTML += '<a href="#" onclick="readMoreFunction()">Read More...</a>';
}
function readMoreFunction() {
paraHolder.innerHTML = readMore + '<a href="#" onclick="return readLessFunction()">Read Less...</a>';
}
function readLessFunction() {
paraHolder.innerHTML = readLess + '<a href="#" onclick="return readMoreFunction()">Read More...</a>'
}
<div class="page-content">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc dolor risus, tempus eu eros sodales, convallis consequat urna.</p>
<p> Fusce ut neque sit amet turpis commodo facilisis. Etiam nunc nisi, porta nec ligula nec, cursus sodales orci. </p>
<p> Cras lacinia odio ut elit pretium blandit. Suspendisse potenti. Ut leo est, pulvinar at urna sed, bibendum vestibulum ligula. </p>
<p>Mauris efficitur velit in tortor pharetra, ut posuere sapien vulputate. Pellentesque venenatis quam vel suscipit consequat. </p>
<p>Mauris efficitur velit in tortor pharetra, ut posuere sapien vulputate. Pellentesque venenatis quam vel suscipit consequat. </p>
</div>
Show More/Less with pure Javascript
A conversion like this isn't a very lengthy process.
Here is a very useful resource to know how to replace a common jquery code with plain (vanilla) javascript.
At the same time, I also took the liberty of modifying your javascript in a new fiddle.
var click_event = function() {
var linkText = this.innerHTML.toUpperCase();
if (linkText === "SHOW MORE") {
this.innerHTML = "Show less";
this.previousElementSibling.classList.remove("hideContent");
this.previousElementSibling.classList.add("showContent");
}
else {
this.innerHTML = "Show more";
this.previousElementSibling.classList.remove("showContent");
this.previousElementSibling.classList.add("hideContent");
}
};
var elements = document.getElementsByClassName("show-more");
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', click_event, false);
}
This code implements all the basic functionalities in vanilla JS. However, I have left out the 400ms time delay, which I think would be a very interesting exercise for you to work on. I hope this helps you in future events.
Read more read less function
You can try to find out various element with relation to button which was clicked. You can also use class name instead of Id to select elements.
function myFunction(event) {
const parentSibling = event.target.parentElement.previousElementSibling;
const dots = parentSibling.querySelector(".dots");
const moreElement = parentSibling.querySelector(".more");
const btnElement = event.target;
if (dots.style.display === "none") {
dots.style.display = "inline";
btnElement.innerHTML = "READ MORE";
moreElement.style.display = "none";
} else {
dots.style.display = "none";
btnElement.innerHTML = "READ LESS";
moreElement.style.display = "inline";
}
}
<p>1. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.<span class="dots">...</span><span class="more" style="display: none"> Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</span></p>
<div class="col-md-12">
<button onclick="myFunction(event)" class="myBtn" class="rm">READ MORE</button>
</div>
<p>2. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.<span class="dots">...</span><span class="more" style="display: none"> Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</span></p>
<div class="col-md-12">
<button onclick="myFunction(event)" class="myBtn" class="rm">READ MORE</button>
</div>
Related Topics
Css3 Appearance Property for Ie
Css: Fixed with Horizontal Menu, with Variable Width Tabs, Using Ul
iOS CSS Opacity + Visibility Transition
Add Prefixes to CSS Class Names Using Less or SASS
Change Navbar Height in Bootstrap3
Border-Radius CSS Property Curve Outside
Center Align Position Absolute Object Horizontally
Bootstrap 3: Can the Glyphicons Be Stacked Like Font Awesome's Icons
CSS Styling - How to Put These Two Div Boxes Adjacent
CSS Calc - Round Down with Two Decimal Cases
CSS - Position: Absolute; - Auto Height
CSS Transitions with :Before and :After Pseudo Elements
Anyway to Have a Label Respond to :Focus CSS
In Visual Studio 2010, How to Easily Comment Out Lines in CSS