Multiple Read More button only on smaller screens?

This is what I have used so far, however it only works for one button. How can I do this with multiple? It works with one button however not with multiple and I really can’t figure it out

Thanks

Not sure what you mean – do you mean with multiple “#read_more” buttons? ID’s need to be unique. That said, it wouldn’t be hard to make something that does what you want.

  • Instead of using id’s, you’d use classes.
  • Finding the hidden element to show would be relative to the button.

Here’s how I made it work, and here’s a repl demonstrating it:

// First, get all the read more buttons,
let readMoreBtns = document.querySelectorAll(".read_more_btn");
// Attach the event listener to each button.
readMoreBtns.forEach(function(){
  this.addEventListener( 'click' , changeClass);
})

/***
 * So the listener does some funkiness. First,
 *  I want to save a reference to the clicked
 *  button (the event.target). Using that, the
 *  parentNode is the div containing the displayed
 *  el, the hidden el, and the button -- so by
 *  getting the parentNode, I can then find the
 *  hidden child and show it.
 * By doing THIS, it is the hidden el related to
 *  this particular "show more" button.
 */
function changeClass(event) {
  let btn = event.target,
      context = event.target.parentNode,
      toggleEl = context.querySelector(".extra_content");
    
    toggleEl.classList.toggle('show');
    
    if (toggleEl.classList.contains("show")) {
            btn.innerHTML = "Show Less";
        } else {
            btn.innerHTML = "Show More";
        }

}
1 Like

Works well, thanks! Forgot how to do it, is there any way to hide the buttons when on desktop? Not hiding for me when on desktop mode.

Thanks!

It’s all about the CSS media queries. Found a great gist about this very thing, comprehensively breaking it down to very atomic parts: https://gist.github.com/gokulkrishh/242e68d1ee94ad05f488

There are FAR more than you need here, may make sense to hide it in all cases, then simply show it in mobile media queries.

1 Like

Also, doesn’t your demo not use unique IDs? It works well for multiple, however I can’t figure out how to hide the buttons like I had previously :confused:

Thanks!

Figured out! Here is my CSS:

/* read more on mobile */

@media (max-width: 650px)  {
	.extra_content {
		display: none;
	}
	.readmorestyling {
		display: block !important;
	}
}

.read_more  {
	display: none;
}

.show {
	display: block!important;
}

.readmorestyling {
	display: none;
	padding:5px 15px;
	background: -moz-linear-gradient(-45deg, #1308fe 0, #0094d5 100%);
	background: -webkit-linear-gradient(-45deg, #1308fe 0, #0094d5 100%);
	background: linear-gradient(135deg, #1308fe 0, #0094d5 100%);
	border:0 none;
	cursor:pointer;
	-webkit-border-radius: 5px;
	border-radius: 5px;
	color: #fff;
}

Probably not the best syntax but it works.

Generally, there’s always a different way. You’re using !important to override any other rule on this selector, but that’s a poor practice. Instead, use the magic of cascading styles.

The purpose of cascading styles is this: I can apply styles from the most general to the most specific use cases.

  • .readmorestyling {...} is a pretty general style – it’s a class-based style.
  • button.readmorestyling {...} is a little more specific. It would override the above style, as the way CSS works is the more general is always replaced by the more specific.
  • .read-more-container .readmorestyling {...} is also more specific, as is read-more-container > div {...}
  • !important overrides EVERYTHING. Thus, if later you want to apply a style, and you aren’t aware of an !important rule on line 533, you’ll be beating your head on a wall for some time.

So rather than using !important at all, try something like this:

@media (min-width: 320px) and (max-width: 480px) {
  .extra_content {
    display: none;
  }
  /* This is a MORE SPECIFIC rule, applied to the same element as below.
   *   because it is more specific, on a mobile app it will override the general rule.
   */
  button.read_more_btn {
    display: inline-block;
  }
}

/* By default, I've set a general rule applied in every case */
.read_more_btn  {
  display: none;
}

.show {
   display: block!important;
}
1 Like

Here is another version. And a little “design” because i was bored.

2 Likes

Thanks, I’ll give that a go.