{"id":112,"date":"2008-05-05T11:38:46","date_gmt":"2008-05-05T16:38:46","guid":{"rendered":"http:\/\/cssnewbie.com\/?p=112"},"modified":"2008-05-05T11:38:46","modified_gmt":"2008-05-05T16:38:46","slug":"showhide-content-css-javascript","status":"publish","type":"post","link":"https:\/\/cssdeck.com\/blog\/showhide-content-css-javascript\/","title":{"rendered":"Show\/Hide Content with CSS and JavaScript"},"content":{"rendered":"<p><a href=\"\/example\/showhide-content\/\" title=\"Click to see this technique in action.\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/cssdeck.com\/blog\/wp-content\/uploads\/2008\/05\/showhide-400.gif\" alt=\"\" title=\"\" width=\"400\" height=\"128\" class=\"alignnone size-full wp-image-114\" \/><\/a><\/p>\n<p>There are plenty of reasons why you might feel the urge to wax verbose on your website\u2019s front page: to prevent your users from having to click through to a new page to find your information, to avoid having to reload the page, or even to improve your front page\u2019s SEO. But just because your front page is text-heavy doesn\u2019t mean it all needs to be visible at once.<\/p>\n<p>Today\u2019s tutorial will show you how to hide away extra bits of content using CSS and JavaScript, to be revealed at the click of a button. This is a great technique, because displaying the additional content doesn\u2019t require a refresh or navigation to a new page and all your content is still visible to search engine bots that don\u2019t pay any attention to CSS or JavaScript.<\/p>\n<p>We\u2019ll start with structuring our XHTML appropriately: <\/p>\n<pre lang=\"html4strict\" escaped=\"true\" line=\"1\">&lt;p&gt;...This is all visible content... \n&lt;a href=&quot;#&quot; id=&quot;example-show&quot; class=&quot;showLink&quot; \nonclick=&quot;showHide('example');return false;&quot;&gt;See more.&lt;\/a&gt;\n&lt;\/p&gt;\n&lt;div id=&quot;example&quot; class=&quot;more&quot;&gt;\n\t&lt;p&gt;...This content is hidden by default...&lt;\/p&gt;\n\t&lt;p&gt;&lt;a href=&quot;#&quot; id=&quot;example-hide&quot; class=&quot;hideLink&quot; \n\tonclick=&quot;showHide('example');return false;&quot;&gt;Hide this content.&lt;\/a&gt;&lt;\/p&gt;\n&lt;\/div&gt;<\/pre>\n<p>There are three things of importance here: the \u201cshow\u201d anchor, the \u201chide\u201d anchor, and our \u201chidden\u201d div. Each has been given an ID and a class. The IDs are used by our JavaScript to locate and style the items appropriately. I\u2019m then using the classes to set our \u201cdefault\u201d CSS. Technically you could just use the IDs the set that CSS as well, but if you wanted more than one hidden section on your page, that could get messy.<\/p>\n<p>You\u2019ll notice in the code above that all of our IDs are fairly similar. This is a trick I\u2019m using to simplify our JavaScript, as you\u2019ll see later on down the road, so I suggest doing something similar. The class names have no relationship to the JavaScript whatsoever, and could really be whatever you wanted them to be.<\/p>\n<p>It\u2019s also important to note that we\u2019re calling our JavaScript using the \u201conclick\u201d call, and passing it the name of our hidden div. Our JavaScript will use that single variable to do the rest of the work.<\/p>\n<p>Now that we have our XHTML in place, let\u2019s put together our default CSS:<\/p>\n<pre lang=\"css\" escaped=\"true\" line=\"1\">.more {\n\tdisplay: none;\n\tborder-top: 1px solid #666;\n\tborder-bottom: 1px solid #666; }\na.showLink, a.hideLink {\n\ttext-decoration: none;\n\tcolor: #36f;\n\tpadding-left: 8px;\n\tbackground: transparent url('down.gif') no-repeat left; }\na.hideLink {\n\tbackground: transparent url('up.gif') no-repeat left; }\na.showLink:hover, a.hideLink:hover {\n\tborder-bottom: 1px dotted #36f; }<\/pre>\n<p>I\u2019m technically doing far more styling than is necessary here, mostly for aesthetic purposes. The only truly important style is the \u201cdisplay: none;\u201d rule on our .more class. This hides our extra content by default. The rest of the CSS simply adds a border to our div (the border is hidden by the display rule, but becomes visible later) and fancied up our show\/hide anchors by putting down\/up arrows next to them and replacing the standard underline with a dotted border. You could style these yourself however you like, and everything would still work just fine.<\/p>\n<p>Next comes the JavaScript, which looks far more complicated than it is:<\/p>\n<pre lang=\"javascript\" escaped=\"true\" line=\"1\">function showHide(shID) {\n\tif (document.getElementById(shID)) {\n\t\tif (document.getElementById(shID+'-show').style.display != 'none') {\n\t\t\tdocument.getElementById(shID+'-show').style.display = 'none';\n\t\t\tdocument.getElementById(shID).style.display = 'block';\n\t\t}\n\t\telse {\n\t\t\tdocument.getElementById(shID+'-show').style.display = 'inline';\n\t\t\tdocument.getElementById(shID).style.display = 'none';\n\t\t}\n\t}\n}<\/pre>\n<p>Our JavaScript is doing four things here:<\/p>\n<ol>\n<li>It checks to see if it can find an element with an ID that matches the variable we passed it.<\/li>\n<li>If so, it checks to see if our \u201cshow\u201d link is visible (this is where the ID naming convention starts to matter).<\/li>\n<li>If the \u201cshow\u201d link is visible, that means our content is still hidden. The JavaScript then hides the link and displays our hidden content.<\/li>\n<li>If the \u201cshow\u201d link is hidden, that means our extra content is currently visible. So it just reverses course, displaying our link again and hiding our extra content.<\/li>\n<\/ol>\n<p>And that\u2019s it! <a href=\"\/example\/showhide-content\/\">You can see a working example in action here.<\/a><\/p>\n<p>Our job has been made much simpler by a few tricksy tricks. First off, we\u2019re using the same function to show and hide our content, which saves us a bit of coding time. Our function simply checks on the state of things: if things are hidden, it shows them, and vice-versa. <\/p>\n<p>Second, by using a defined schema for our element IDs (\u201cexample,\u201d \u201cexample-show,\u201d and \u201cexample-hide,\u201d in our example above), we only need to pass our JavaScript a single variable. It then uses that variable to find all of our other elements and style them appropriately.<\/p>\n<p>And finally, we put our \u201chide this content\u201d anchor <em>inside<\/em> the hidden div. This means that we never have to set its display property: it\u2019s hidden when the container is hidden, and visible when the container is. That saves us two lines of JavaScript and at least one line of CSS.<\/p>\n<p>This technique could be used in loads of situations. Say for example that you have a WordPress blog and the front page shows excerpts instead of the full article. You could use this technique to have the whole article on the front page for the search engines to find, visible to your users at the click of a button. Or maybe you have a complex form that could use some detailed in-page explanation, but you don\u2019t always want the help content visible, eating up real estate when some users already know what to do. Or&#8230; well, anything, really. Let me know if you come up with any creative uses!<\/p>\n<div class=\"wp-socializer wpsr-share-icons \" data-lg-action=\"show\" data-sm-action=\"show\" data-sm-width=\"768\" ><h3>Share and Enjoy !<\/h3><div class=\"wpsr-si-inner\"><div class=\"wpsr-counter wpsrc-sz-32px\" style=\"color:#000\"><span class=\"scount\"><span data-wpsrs=\"\" data-wpsrs-svcs=\"facebook,twitter,linkedin,pinterest,print,pdf\">0<\/span><\/span><small class=\"stext\">Shares<\/small><\/div><div class=\"socializer sr-popup sr-32px sr-circle sr-opacity sr-pad sr-count-1 sr-count-1\"><span class=\"sr-facebook\"><a rel=\"nofollow\" href=\"https:\/\/www.facebook.com\/share.php?u=\" target=\"_blank\"  title=\"Share this on Facebook\"  style=\"color: #ffffff\" ><i class=\"fab fa-facebook-f\"><\/i><span class=\"ctext\"><span data-wpsrs=\"\" data-wpsrs-svcs=\"facebook\">0<\/span><\/span><\/a><\/span>\n<span class=\"sr-twitter\"><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/intent\/tweet?text=%20-%20%20\" target=\"_blank\"  title=\"Tweet this !\"  style=\"color: #ffffff\" ><i class=\"fab fa-twitter\"><\/i><\/a><\/span>\n<span class=\"sr-linkedin\"><a rel=\"nofollow\" href=\"https:\/\/www.linkedin.com\/sharing\/share-offsite\/?url=\" target=\"_blank\"  title=\"Add this to LinkedIn\"  style=\"color: #ffffff\" ><i class=\"fab fa-linkedin-in\"><\/i><\/a><\/span>\n<span class=\"sr-pinterest\"><a rel=\"nofollow\" href=\"https:\/\/www.pinterest.com\/pin\/create\/button\/?url=&amp;media=&amp;description=\" target=\"_blank\"  title=\"Submit this to Pinterest\"  style=\"color: #ffffff\" data-pin-custom=\"true\"><i class=\"fab fa-pinterest\"><\/i><span class=\"ctext\"><span data-wpsrs=\"\" data-wpsrs-svcs=\"pinterest\">0<\/span><\/span><\/a><\/span>\n<span class=\"sr-print\"><a rel=\"nofollow\" href=\"https:\/\/www.printfriendly.com\/print?url=\" target=\"_blank\"  title=\"Print this article \"  style=\"color: #ffffff\" ><i class=\"fa fa-print\"><\/i><\/a><\/span>\n<span class=\"sr-pdf\"><a rel=\"nofollow\" href=\"https:\/\/www.printfriendly.com\/print?url=\" target=\"_blank\"  title=\"Convert to PDF\"  style=\"color: #ffffff\" ><i class=\"fa fa-file-pdf\"><\/i><\/a><\/span><\/div><\/div><\/div>","protected":false},"excerpt":{"rendered":"<p>There are plenty of reasons why you might feel the urge to wax verbose on your website\u2019s front page: to prevent your users from having to click through to a new page to find your information, to avoid having to reload the page, or even to improve your front page\u2019s SEO. But just because your front page is text-heavy doesn\u2019t mean it all needs to be visible at once. [&#8230;]<\/p>\n<p><a class=\"more-link article\" href=\"https:\/\/cssdeck.com\/blog\/showhide-content-css-javascript\/\" title=\"Click to read 'Show\/Hide Content with CSS and JavaScript'\">Read Article<\/a><\/p>\n","protected":false},"author":18,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[165,184],"tags":[62,79,55,303],"_links":{"self":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/posts\/112"}],"collection":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/users\/18"}],"replies":[{"embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/comments?post=112"}],"version-history":[{"count":0,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/posts\/112\/revisions"}],"wp:attachment":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/media?parent=112"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/categories?post=112"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/tags?post=112"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}