Friday, August 21, 2015

Blogspot Spoiler Tag

While we are on the topic of modifying blogspot themes I thought I may as well go over the spoiler tag, since this is also something I added. At first I followed the steps provided here, but I didn't like the look of the spoiler tag. It worked, so I didn't put too much stock into changing it at the time. But I wanted something that stood out, and so I searched codepen.io hoping I would find one that caught my fancy. Alas, this was not the case. So I went ahead and made my own.

You can find my codepen with only what I did here.

The first thing I wanted was an encompassing div which I apply the class "spoiler" to. This I thought would be useful for JavaScript and to provide cleaner separation. It ended up working out well because in my CSS I was able to apply a margin-bottom to the .spoiler class so if there are two spoilers immediately adjacent to each other, they don't overlap and look weird.

The next step was to create another div with a "spoiler-header" class that would be used to display the message you want to display to the user. Some additional logic could be applied in the JavaScript to change the content of this, but I opted to exclude this for the time being. If I were to do this, I would probably embed a span tag to select off of and modify the text and keep a +/- sign to delineate the state of the spoiler tag (as if it wasn't obvious). In the CSS I also apply a cursor to this class so it is obvious you are supposed to click on it. Aside from that there is some padding and border-radius for style. Finally, the color is set - by default I chose a grey, no particular reason #dadada just was easy to type. This can be changed to whatever matches your theme.

The last step was to create the actual spoiler content which is hidden in a "spoiler-content-hidden" class. When the "spoiler" div is clicked it changes the class of this div from "spoiler-content-hidden" to "spoiler-content". The hidden CSS just has a display:none; property. While the "spoiler-content" class has additional formatting such as a background color, some padding, a border (whose color matches the header because it looks sharper). I again had no reason for choosing the background color aside from #efefef looking pretty good and being easy to type.

So far we have something like the following HTML:
+ Spoiler
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam eu sodales tortor, posuere mattis nunc. Integer eget sapien ullamcorper diam mollis laoreet. Praesent dignissim id urna at malesuada. Etiam id nisl vitae ante vestibulum volutpat.
+ Spoiler
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam eu sodales tortor, posuere mattis nunc. Integer eget sapien ullamcorper diam mollis laoreet. Praesent dignissim id urna at malesuada. Etiam id nisl vitae ante vestibulum volutpat.
I follow the same steps outlined in the other article - which pretty much amount to going to template, customize, advanced, add css. Alternatively you could add these directly to your template in the b:skin tag. This is where they get placed anyways using the other method.

The CSS looks something like this:
.spoiler { 
  margin-bottom: 10px;
}
.spoiler-header {
  cursor: pointer;
  background: #dadada;
  border-radius: 5px 5px 0px 0px;
  padding: 5px;
}
.spoiler-content { 
  background: #efefef;
  display:block;
  border-radius: 0px 0px 10px 10px;
  padding: 10px 10px 10px 15px;
  border: 1px solid #dadada;
}
.spoiler-content-hidden {
  display:none;
}
Now all we are missing is the JavaScript. I wanted something simpler than the code I was using, it was rather tedious to provide a unique id for each spoiler. Which is part of the reason I wanted to nest these divs in the div with the "spoiler" class. This is how I tied them together. Then in my JavaScript I was able to have the header have an onclick property that would call my toggle_spoiler JavaScript function and pass the id to it. Because they are next to each other, I could then use JavaScript's "nextElementSibling" property to get the "spoiler-content-hidden" classes div and change the state. The JavaScript is really basic and looks like this:
function toggle_spoiler(id)
{
  var spoilerContent = id.nextElementSibling;
  if(spoilerContent.className == "spoiler-content-hidden")
  {
    spoilerContent.className = "spoiler-content";
  }
  else
  {
    spoilerContent.className = "spoiler-content-hidden";    
  }
  return;
}
We'll put this in the template, just like the other example says. I put mine at the bottom of my template before the </body> tag so that it doesn't impact loading (it shouldn't but I do it anyways).

Finally we get spoiler tags that look like this:
+ Spoiler
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam eu sodales tortor, posuere mattis nunc. Integer eget sapien ullamcorper diam mollis laoreet.

Praesent dignissim id urna at malesuada. Etiam id nisl vitae ante vestibulum volutpat.
+ Spoiler
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam eu sodales tortor, posuere mattis nunc. Integer eget sapien ullamcorper diam mollis laoreet.

Praesent dignissim id urna at malesuada. Etiam id nisl vitae ante vestibulum volutpat.
I like this solution because I don't have to specify the ids for the header and the spoiler-content. I also like that I was able to do the task in simple JavaScript and did not have to pull jQuery in, although it might make tying the onclick event a little easier. Perhaps that will be an update for next time.

No comments:

Post a Comment