{"id":82,"date":"2008-04-02T07:00:40","date_gmt":"2008-04-02T12:00:40","guid":{"rendered":"http:\/\/cssnewbie.com\/message-box-javascript-css\/"},"modified":"2008-04-02T07:00:40","modified_gmt":"2008-04-02T12:00:40","slug":"message-box-javascript-css","status":"publish","type":"post","link":"https:\/\/cssdeck.com\/blog\/message-box-javascript-css\/","title":{"rendered":"Perma-Closing Message Boxes with JavaScript + CSS"},"content":{"rendered":"<p><img src='https:\/\/cssdeck.com\/blog\/wp-content\/uploads\/2008\/04\/messagebox-400.gif' alt='message box' \/><\/p>\n<p>Earlier this week <a href=\"\/harnessing-positioning-2\/\">I talked a bit about message boxes<\/a> \u2013 how to style them and position them on your page to get them noticed. But a message that pops up every single time your website is loaded could get annoying. It\u2019d be useful to give your users the ability to close those messages. For that, we\u2019ll turn to our friend JavaScript.<\/p>\n<p>We\u2019ll start by building our message box in XHTML. Mine looks like this:<\/p>\n<pre lang=\"html4strict\" escaped=\"true\" line=\"1\">&lt;div id=&quot;message-1&quot; class=&quot;msgbox&quot;&gt;\n\t&lt;a href=&quot;#&quot; id=&quot;close&quot; title=&quot;Close This&quot;&gt;X&lt;\/a&gt;\n\t&lt;p&gt;My uber-important message goes here!&lt;\/p&gt;\n&lt;\/div&gt;<\/pre>\n<p>I\u2019ve made a div with both an ID and a class. This will come in handy later when we need to reference our object in our JavaScript. Inside, I put an anchor tag with a class of \u201cclose.\u201d This will become my close button later. And then I simply added a paragraph to hold my message.<\/p>\n<p>Next up, we\u2019ll want to style that message box. You can make it look pretty much however you want, and <a href=\"http:\/\/woork.blogspot.com\/2008\/03\/css-message-box-collection.html\">Woork has a nice article on styling message boxes,<\/a> if you\u2019re interested in discovering alternative styles. For my message box, I wrote this:<\/p>\n<pre lang=\"css\" escaped=\"true\" line=\"1\">.msgbox {\n\tposition: absolute;\n\ttop: 15px;\n\tright: 20px;\n\twidth: 20em;\n\tbackground-color: #b00;\n\tborder: 1px solid #333;\n\tcolor: #fff;\n\tfont-weight: bold; }\n.msgbox p {\n\tmargin: 0;\n\tpadding: 5px 10px; }\n.msgbox a.close {\n\tfloat: right;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\tcolor: #333;\n\tbackground-color: #fff;\n\tborder-left: 1px solid #333;\n\tborder-bottom: 1px solid #333;\n\tpadding: 0 4px;\n\tmargin-left: 5px; }<\/pre>\n<p>Three rules are at play here. First, I\u2019m styling the message box itself, using the class I gave it. I\u2019m absolutely positioning the element and giving it a width. I\u2019m also giving it a red background, bolding the text inside and turning it white, and applying a border. Then I\u2019m applying a bit of styling to the paragraph inside to push it away from the side of the box. <\/p>\n<p>Why didn\u2019t I apply that padding to the message box itself? Because of the \u201cclose\u201d link. I wanted to be able to float it to the right of the box and give it some styles to make it look more like a \u201cclose\u201d button. After all of that CSS, this is what I have:<\/p>\n<p><img src='https:\/\/cssdeck.com\/blog\/wp-content\/uploads\/2008\/04\/messagebox1-400.gif' alt='example message box' \/><\/p>\n<p>But so far, we just have a message box. That close button doesn\u2019t do much of anything. For the rest, we\u2019ll turn to JavaScript. All we need is a little function like this:<\/p>\n<pre class=\"javascript\">function closeBox(toClose) {\n\tdocument.getElementById(toClose).style.display = \"none\";\n}<\/pre>\n<p>This function takes a single argument (toClose) which tells it the ID of the element we want to make disappear. We supply argument when we call the JavaScript. In this case, because we want it to happen when someone clicks our close box, we\u2019d add it to our XHTML like this:<\/p>\n<pre lang=\"html4strict\" escaped=\"true\" line=\"1\">&lt;a href=&quot;#&quot; class=&quot;close&quot; \nonclick=&quot;closeBox('message-1'); return false;&quot; \ntitle=&quot;Close This&quot;&gt;X&lt;\/a&gt;<\/pre>\n<p>We\u2019ve added the \u201conclick\u201d attribute to our &#8220;close&#8221; link tomake it fire a bit of JavaScript when the element is clicked. We\u2019re telling it to call our closeBox function that we just wrote, and we&#8217;re giving it the ID of the message box we want to close. The \u201creturn false\u201d part basically tells it to stop (that is, not to actually go to our specified href afterwards). <\/p>\n<p>That\u2019s all we need to create a message box that closes! However, if your users close the box and then refresh the page, the message box comes right back. What if we want it to close permanently? For that, we\u2019ll need some more fancy JavaScript, because we\u2019ll need to make use of cookies.<\/p>\n<p>The cookie will act as a check that we can refer back to. When the user closes the message box, we\u2019ll set a cookie. Then, when they come back to the page, we\u2019ll check to see if the cookie is set. If there\u2019s no cookie, we\u2019ll show them the message. If there <em>is<\/em> a cookie, we\u2019ll keep the message box hidden.<\/p>\n<p>First, we\u2019ll make a small change to our CSS:<\/p>\n<pre lang=\"css\" escaped=\"true\" line=\"1\">.msgbox {\n\tdisplay: none; \/* Start out hidden. *\/\n\tposition: absolute;\n\ttop: 15px;\n\tright: 20px;\n\twidth: 20em;\n\tbackground-color: #b00;\n\tborder: 1px solid #333;\n\tcolor: #fff;\n\tfont-weight: bold; }<\/pre>\n<p>All we\u2019re doing is adding a \u201cdisplay: none\u201d to the top of the element. By default, we don\u2019t want our message box to show up. Instead, we\u2019ll use JavaScript to display it if we want to see it. Why? It\u2019s a usability thing: this way, if a user doesn\u2019t have JavaScript enabled, they don\u2019t see the message box. That may seem like a bad thing, but consider the alternative: if we didn\u2019t set this rule, then anyone without JavaScript couldn\u2019t <strong>get rid of<\/strong> your message box. And depending on its placement, that could be a big usability problem.<\/p>\n<p>So now we need two extra functions in our JavaScript: one to set the cookie when we close the box, and another to check to see if the cookie exists when the user comes back.  Our JavaScript now looks like this:<\/p>\n<pre class=\"javascript\">function closeBox(toClose) {\n\tdocument.getElementById(toClose).style.display = \"none\";\n\tsetCookie(toClose, \"closed\", 365);\n}\nfunction setCookie(cName, value, expiredays) {\n\tvar expDate = new Date();\n\texpDate.setDate(expDate.getDate()+expiredays);\n\tdocument.cookie=cName + \"=\" + escape(value) + \n\t\";expires=\" + expDate.toGMTString();\n}\nfunction loadMsg(msgClass) {\n\tmsg = document.getElementsByTagName(\"div\");\n\tfor (i=0; i&lt;msg.length; i++) {\n\t\tif(msg[i].className == msgClass) {\n\t\t\tif(document.cookie.indexOf(msg[i].id) == -1) {\n\t\t\t\tmsg[i].style.display = \"block\";\n\t\t\t}\n\t\t}\n\t}\n}<\/pre>\n<p>First off, we modified our closeBox() function to make a call to the setCookie() function after it\u2019s hidden the message box. <\/p>\n<p>Next comes the setCookie() function. It takes three arguments: the name of the cookie, the value to be set, and how long the cookie should last before it expires (in days). We could have hard-coded some of this stuff to save time and space, but this way you can reuse this same function to set cookies all over your site \u2013 not just for this purpose. <\/p>\n<p>Also, note that we\u2019re using the toClose variable for our cookie name in setCookie()&#8230; which you might also remember is the ID of the message box itself. This is a useful trick, because this means you could theoretically have multiple message boxes with different IDs (all with the same .msgbox class) on your page, and you could open and close them separately, because each of their states would be set in a unique cookie. <\/p>\n<p>Next comes the loadMsg() function. It takes one argument: msgClass. This variable represents the class you\u2019ve set on all your message boxes. Our loadMsg() function cycles through all the &lt;div&gt; tags on your website and checks to see if they have the \u201cmsgClass\u201d class set (whatever that happens to be&#8230; in my document, that was \u201cmsgbox\u201d). If it finds such a div, it checks to see if it can find a cookie with a name that matches the ID set on that div \u2013 in our example it would be looking for \u201cmessage-1.\u201d If it <strong>doesn\u2019t<\/strong> find a match (meaning the user hasn\u2019t closed the box), then it sets that div to \u201cdisplay: block,\u201d meaning it will show up normally. Otherwise, the message box stays hidden.<\/p>\n<p>Now, all we need to do is ensure the loadMsg() function runs when the page first loads. To do that, I just modified my body tag like so:<\/p>\n<pre lang=\"html4strict\" escaped=\"true\" line=\"1\">&lt;body onload=&quot;loadMsg('msgbox');&quot;&gt;<\/pre>\n<p>The \u201conload\u201d attribute fires when the page has finished loading, and it will call the loadMsg() function for us, displaying our message boxes as needed. And that\u2019s all there is to it! <a href=\"\/example\/closable-message-boxes\/\">You can see a functioning example here.<\/a><\/p>\n<p>Now, I did want to mention a couple of things before you try this on your own:<\/p>\n<ul>\n<li>I\u2019ve built this example specifically to make it work with multiple message boxes. Otherwise, it would have been easier and faster to reference our message box by its ID in our loadMsg() function.<\/li>\n<li>This obviously only works if your users have JavaScript and cookies enabled. If they have JavaScript turned off, they won\u2019t see a message box. If they have <em>cookies<\/em> turned off, they won\u2019t be able to get rid of your message box. And I don&#8217;t know of a good way around this usability problem. That\u2019s just the way the cookie crumbles.<\/li>\n<li>You could achieve this same functionality in about half the space using a JavaScript framework. I have nothing against frameworks generally, but I <em>do<\/em> have something against forcing your users to download 50KB+ of JavaScript if you\u2019re only going to use 1KB (or less) of it. For some things, frameworks make sense. For others, it\u2019s better to just write it by hand.<\/li>\n<\/ul>\n<p>But enough from me&#8230; I want to hear what <em>you<\/em> have to say about this technique. Leave me a comment!<\/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>\n<p>Earlier this week I talked a bit about message boxes \u2013 how to style them and position them on your page to get them noticed. But a message that pops up every single time your website is loaded could get [&#8230;]<\/p>\n<p><a class=\"more-link article\" href=\"https:\/\/cssdeck.com\/blog\/message-box-javascript-css\/\" title=\"Click to read 'Perma-Closing Message Boxes with JavaScript + CSS'\">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,55,303,372],"_links":{"self":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/posts\/82"}],"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=82"}],"version-history":[{"count":0,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/posts\/82\/revisions"}],"wp:attachment":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/media?parent=82"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/categories?post=82"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/tags?post=82"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}