JSFiddle - React, Tailwind, and code Playground

by GolezTrol

HTML

<p class="expandable" id="text2">text to hide</p>

<p class="expandable showing" id="text2">text that is showing by default.</p>

CSS

/* This CSS is to support the hide/show behaviour, which only works with JavaScript */

/* Default look and feel of the show/hide link */
.js .expandable.showing::before,
.js .expandable.hiding::before {
    display: block;
    content: "show text";
    color: blue;
}

/* Alternate text */
.js .expandable.showing::before {
    content: "hide text";
}

/* Hide content */
.js .expandable.hiding > div {
    display: none;
}

JavaScript

/* Simply add the class 'expandable' to an element to introduce this behaviour.
   No other markup is needed.
   Show/hide button is not visible when JavaScript is disabled.
   All texts are visible when JavaScript is disabled.
   
   Caveats:
   - Uses classList which is not available in IE9-
   - Uses a couple of feature which are not available in IE8-
   - Binds click event to the text itself, so a click anywhere on the text toggles 
     it, not just the button. This can be solved by adding an extra element and 
     binding the click event to that, instead of using `::before` pseudo-element which
     can not have its own click handler.
*/

// Instead of adding behaviour to the HTML, add it from JavaScript. You can do this when 
// the document is loaded. Add an event listener for this.
window.addEventListener('load', function(){

    // Tell CSS we got JavaScript support.
    document.body.classList.add('js');
    
    // The function that handles the toggling.
    var toggle = function() {
        this.classList.toggle('hiding');
        this.classList.toggle('showing');
    }

    // Get all texts that should have this behaviour.
    var texts = document.getElementsByClassName('expandable');
    
    for(var i = 0; i < texts.length; i++) {
        // Wrap the contents into a div, so it can be hidden separately from the hide/show button.
        texts[i].innerHTML = "<div>" + texts[i].innerHTML + "</div>";
        
        // Make sure that either the class 'showing' is set (keep if set) or 
        // 'hiding' is set (add 'hiding' if neither was added in the HTML).
        texts[i].classList.toggle('hiding', !texts[i].classList.contains('showing'));
        
        // Add the click event listener.
        texts[i].addEventListener('click', toggle);
    }
});