The Black Magic of HTML5 Data Attributes

Okay, so, rewind to about a year and a half ago, when I was lying on the sofa, having a whine about my retail job du jour, and remembered that I actually had some skills outside of smiling and accepting the blame for my store being out of arbitrarily-sized t-shirts. This train of thought ended up with a friend of mine sending me copies of a couple front-end ebooks to get me up to speed on HTML5 (which had just come out) and CSS3, since I was a little out of date with what was going on in the Great Big Hello World of Web Development.

So, I’m reading this HTML5 book, all like:

But, there was one thing that it either didn’t cover, or—more likely—I got bored and quit reading before I got that part, because it wasn’t like I couldn’t already HTML, and reading about HTML is not the most exciting thing on Earth. (Also, HTML is now a verb, I’ve decided.) The thing that I missed? Data attributes, or, as they are also known, black freakin’ magic. The first time I saw them being used, I was like:

…look, kids, back in the day, we had to come up with weird names for CSS classes and use JavaScript to parse them into something meaningful if we wanted data available in the DOM. Now, you just prefix with “data-*” on an element, and you can store whatever the heck kind of string you want in there (within reason). You can store JSON in it, for example, which is just—whaaaaaat, where has this been all my life? (Or maybe not—HTML5 is only two years old, so for the vast majority of my life it hasn’t existed… still, have I totally been living under a rock for two years?!)

So now, say I have an unordered list, and I want to grab a value (or several values) and display it when the user selects a list item, without making an Ajax call or querying a database or any of that nonsense. I’ll just stick my data in some data attributes—let’s call them “data-registration-number”, “data-color”, and “data-codename”:

  • <ul id="nonsenseList">
    
     <li data-registration-number="1701" data-color="yellow"
    
     data-codename="Enterprise">Nonsense</li> 
    
     <li data-registration-number="74656" data-color="blue"
    
     data-codename="Voyager">More Nonsense</li>
    
     <li data-registration-number="74205" data-color="red"
    
     data-codename="Defiant">Even More Nonsense</li>
    
     </ul>

So now, I can use JavaScript to grab one of those values from my list items, and use it however I want:

<script> 
//this first script uses the element.getAttribute() function to nab the value from our data attribute:
var nonsenseList = document.getElementById("nonsenseList"); 
var firstItem = nonsenseList.children[0]; 
firstItem.onmouseover = function(){ 
 var regNumber = firstItem.getAttribute("data-registration-number"); 
 window.alert("Registration Number: " + regNumber); 
}; 
</script>

Admittedly, this is a pretty lame example with little/no practical application. The point is, I was able to tell my script to get the value of the attribute named “data-number” off a particular element, and it did. You should note that in order to have to a valid data attribute, the attribute name must be prefixed with “data-”, have at least one character after the first hyphen, be XML-compatible, and contain no uppercase ASCII letters (as per w3 spec for HTML documents, read more here).

But wait! There’s more. There is actually an even better way to access what is stored in your data attributes, and it’s through the new HTML5 dataset API. This API exposes an element attribute named dataset, which returns a DOMStringMap object. The DOMStringMap keys are the names of the data attributes (without the “data-” prefix), and the corresponding values are the string values contained in the attributes themselves. If the data attribute name is made of multiple words (like our data-registration-number), it’s converted to camelCase (in this case, registrationNumber). The dataset API is dead simple to use, too—just call it using dot notation on a chosen element:

<script>
//let's try it again using the dataset API:
var nonsenseList = document.getElementById("nonsenseList"); 
var secondItem = nonsenseList.children[1]; 
secondItem.onmouseover = function(){
 var regNumber = secondItem.dataset.registrationNumber; 
 window.alert("Registration Number: " + regNumber); 
}; 
</script>

The dataset API is widely supported in modern desktop and mobile browsers (aside from in Internet Explorer, which only supports it in IE11, because it’s Internet Explorer). There is a shim out there for it (only a Google search away), but if you’re concerned about compatibility, you can always fall back on using more vanilla Javascript functions like getAttribute(). I’ve also read that using the dataset API is slower, but unless you’ve got a load of stuff stored in your attributes or need to read out of a whole bunch of them very quickly, performance shouldn’t be a concern—and, side note, if this is an issue, it’s my opinion that you’re probably weighing down the DOM with too much data, and need to rethink your architecture.

Another side note: data attributes should only be used when a suitable HTML5 element or attribute does not already exist. Additionally, unlike microformats, data attributes are meant to be private—that is, they are not intended to be read by outside software, and are meant only for custom data in the context of the site they are located on. Data attributes are meant to be used by the site’s own scripts, meaning that you shouldn’t be implementing them to store publicly-usable metadata. If you want to do that, use microformats, that’s what they’re for!

If you’d like to try it with some quick and dirty code, here’s the pointlessness that I threw together for this post–feel free to pop it into your editor of choice and use it as a starting point for playing around with data attributes:

<html> 
<head>
 <!--doing some quick/dirty styling so that things aren't as ugly-->
 <link href="https://fonts.googleapis.com/css?family=Homemade+Apple" rel="stylesheet"> 
 <style>
 .container { 
 width: 25%; 
 text-align: center;
 }
 li { 
 display: block; 
 margin: 10%; 
 padding: 10%;
 border: 5px solid black; 
 border-radius: 10px;
 font-family: 'Homemade Apple', cursive;
 }
 </style>
</head>
<body>
 <div class="container">
 <ul id="nonsenseList">
 <li data-registration-number="1701" data-color="yellow"
 data-codename="Enterprise">Nonsense</li> 
 <li data-registration-number="74656" data-color="blue"
 data-codename="Voyager">More Nonsense</li>
 <li data-registration-number="74205" data-color="red"
 data-codename="Defiant">Even More Nonsense</li>
 </ul>
 </div>
</body>
</html>

<script> 
//this first script uses the element.getAttribute() function to nab the value from our data attribute:
var nonsenseList = document.getElementById("nonsenseList"); 
var firstItem = nonsenseList.children[0]; 
firstItem.onmouseover = function(){ 
 var regNumber = firstItem.getAttribute("data-registration-number"); 
 window.alert("Registration Number: " + regNumber); 
}; 
</script>

<script>
//let's try it again using the dataset API:
var nonsenseList = document.getElementById("nonsenseList"); 
var secondItem = nonsenseList.children[1]; 
secondItem.onmouseover = function(){
 var regNumber = secondItem.dataset.registrationNumber; 
 window.alert("Registration Number: " + regNumber); 
}; 
</script>

Gettin’ Sass-y with CSS

Cascading Style Sheets came into the world 19 years ago, which is coincidentally about the time I realized I could build my own websites and put them online. Since my formative years were largely dedicated to messing around on the internet, I put in a lot of practice writing CSS in junior high and high school. Like, a lot of practice. However–still, to this very day, when I write CSS and need to figure out why something doesn’t work, it often ends with my banging my head into the desk and reminding myself that “they’re called Cascading Style Sheets because they cascade.”

Here’s what’s up: the CSS I’ve been writing hasn’t really been much different than the CSS I was writing in high school. Sure, I knew of the existance of those fancy extensions/preprocessors, but I wasn’t about to actually use them. It’s just CSS. How fancy does it need to get?

Well, I was working on my little group management app, CoLeadr–remember that? And as I was writing up the CSS for the main dashboard view, it occurred to me that it would, in fact, be really awesome if I could use variables in my stylesheet. I tend to develop in black and white and add a color scheme in later, and I was starting to see that particular stylesheet becoming a pain in the butt. So I decided to check out a CSS preprocessor.

I chose Sass (Syntactically Awesome Stylesheets), for the very grown-up and professional reason that “sass” sounds a lot more fun than “less”. So I typed “sass” into Google, and Google knew exactly what I meant because Google is magic. One line in the terminal later, and I was up and running.

There’s actually two different types of Sass file: the original indented syntax .sass, and the more recent .scss, which is similar to CSS. Both get interpreted to CSS with a simple terminal command, or you can set it up to watch individual files or entire directories for changes, and Sass will automagically interpret to CSS whenever there’s an update. I’ve been writing .scss, so I don’t have to teach myself very many new syntactical tricks. I also keep a terminal window open specifically for being able to repeat this command:

toribrenneison$ sass sass/marketing_sassy.scss marketing.css

Using variables is super easy. Sass recognizes colors, numbers, booleans and strings as variable values. Variables are declared with a dollar sign (or–someone introduced me to this and I have been in love with it since–a bling) at the start of your Sass file, and can then be used anywhere in the rest of the file. When the file is processed to CSS, Sass will fill in the variable values for whatever CSS is being compiled, so this:

$body-background-color: #ffffff;
body { background-color: $body-background-color; }

Turns into this:

body { background-color: #ffffff; }

You can see how that would make a massive CSS file a lot more manageable when it comes to changing the values for things like colors, margins/padding, borders, and the like. Speaking of massive CSS files, Sass has some handy methods for splitting your Sass into manageable chunks. A partial Sass file _starts _with _an _underscore, and although they’re not generated into CSS files with the same magic, Sass was also kind enough to give us an @import command to bring those partials in and add them to the CSS file it compiles.

Sass also gives us mixins, which are like reuseable chunks of code. Let’s snag the example from Sass’s own website and say, for example, that you want to declare a border-radius value that will appear in several different places. Since it’s best practice to declare styles with several vendor prefixes (Google webkit, Mozilla, Microsoft, Opera) so that your code has the best chance of working in all browsers, typing can get tedious pretty quickly. With a Sass mixin, you can declare once (their example uses a variable for good measure):

@mixin border-radius($radius) {
-webkit-border-radius: $radius;
-moz-border-radius: $radius;
-ms-border-radius: $radius;
border-radius: $radius;
}

And use it anywhere:

.box { @include border-radius(10px); }

Which compiles to:

.box {
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
-ms-border-radius: 10px;
border-radius: 10px;
}

Something else that is totally amazing about Sass? Inheritance. Sass will let you nest your declarations, although you should beware of going too deep, which will lead to over-qualified CSS (I’m looking at you, Bootstrap). So you can nest a declaration for a line item or a link inside of the declaration for your navigation class, which keeps the Sass file easy to read. Straight-up inheritance also works: just use the @extend command, and you’ll be able to add on to already-existing declarations. To once again steal from Sass’s website, you can build “success” and “error” off of an existing “message” class:

.message {
border: 1px solid #ccc;
padding: 10px;
color: #333;
}
.success {
@extend .message;
border-color: green;
}
.error {
@extend .message;
border-color: red;
}

Will turn into:

.message, .success, .error {
border: 1px solid #cccccc;
padding: 10px;
color: #333;
}
.success {
border-color: green;
}
.error {
border-color: red;
}

Sass will also do some math for you, but since I’m terrible at math, I’ve left that alone. I like to use a grid system like Bootstrap/Foundation/Skeleton to do my layouts, so I don’t really need Sass to do crazy layout calculations for me, anyway–I can see the value in it, of course, but it’s not something I’m ready to try and use myself.

Would I recommend Sass to a friend? I certainly would, and I’m doing it right now. Perhaps, at some point, I’ll try and play around with Less. But for now, I’m getting Sass-y, and loving it.

You can find documentation and read more about Sass by visiting the official website: sass-lang.com.

How I Won my Coding Bootcamp by Ponyrolling

If you’ve been on the internet for longer than ten minutes, you are probably familiar with Rickrolling–tricking someone into listening to the earbug that is Rick Astley’s Never Gonna Give You Up under the guise of sending them legitimate information.  Before Rickrolling, there was Duckrolling, which is where you’d get sent this stupid wheeled duck instead of Rick Astley.  Either way, *rolling is bait-and-switch, you expect one thing and get another.  For example, I won my bootcamp by ponyrolling.

It all started three weeks into the program.  We had whiteboard tabletops, and I drew this on the table:

My Little Pony: Coding is Magic

It was pretty funny, the instructor took a photo of it, I took a photo of it, everyone laughed.  So a week later, I drew another pony while we were talking about data structures.  And I drew a couple ponies when we talked about exception handling.  And it got to be a thing that I was making ponies out of programming concepts and computer languages.  Just a quirky little thing, right?  Ponies on whiteboards.  Nothing extravagant.

We were assigned final projects with a week to go: make a portfolio website using ASP.NET MVC, hook it up to a database, do some other stuff, it has to have this, this, and this other thing.  By the middle of the week, a classmate had told me that I had to put a pony on it, because of the whiteboard ponies.  So I brought in my Macbook, opened up Photoshop and made a good version of that original C# pony:

C# Pony

Originally, I just had C# Pony hanging out on the home index view as a way to take up space.  I was going to remove her and put in another image later, but people would walk by and comment on the pony, and then they were upset when I said I wasn’t going to keep her there.  So I tweaked the stylesheet to make the site purple, and kept the pony, because so many people said they really liked the pony.

I got done with the site pretty quickly, and decided to make another pony.  Since the site was done in C# + HTML and drew project information and image URLs from a database, I decided that C# Pony’s companion would be SQL Pony:

SQL Pony

People were getting a pretty good laugh out of the ponies, which made me happy.  I really like My Little Pony, although I’m not completely sure why.  At least part of it is nostalgia value, having watched the cartoons and played with the toys growing up.  The newest incarnation of My Little Pony, Friendship is Magic, is actually a really good cartoon, if you can get over the characters being colorful small horses.  Plus the main character reminds me a lot of myself (Twilight Sparkle is a total nerd unicorn who special talent is being a total nerd), and her friend Pinkie Pie is a dead ringer for my dear friend Terri (in personality, of course, Terri is a real person and not a pony).  I don’t really have a large problem with being an adult who likes a little kid cartoon, either, although it’s also not as though I go to parties and introduce myself to people by comparing myself to Twilight Sparkle the nerd unicorn.

Moving on.  People were getting a pretty good laugh out of the ponies, and I liked that.  I like it when I can make other people laugh, especially when it’s over something small and silly.  I also don’t particularly mind making a fool of myself for a joke, so long as I’m sure people are going to laugh and not just silently wonder if I need to be institutionalized.

That Saturday evening, a little more than 24 hours before the project was due, it came to me:  it’s not enough to have two ponies.  If my bootcamp pals wanted ponies, then by all means, I would give them ponies.  I would give them so many ponies. 

Just as I had finished reading about session data and writing up some very basic code that switched the CSS the site used based on a session variable, my classmate Stephanie posted something on my Facebook wall.  She was at Plato’s Closet, which is a kind of resale clothes shop, and she had found a marvelously pink My Little Pony sweater, in my size, for $8:

pony sweater

Just as I was about to ask her to get it for me and I’d pay her back, she asked if I wanted her to get it for me and I could pay her back.  Of course I wanted it, because it was the perfect accompaniment for my plan to unleash so many ponies on my unsuspecting classmates.

I spent most of Sunday at Panera, eating an almost sickeningly sweet carrot cake muffin, drawing ponies and giggling to myself in the corner.  Late in the afternoon, I had a stylesheet that my eight-year-old self and her collection of My Little Ponies would have been immensely proud of.  I just still felt as though it was missing something

Only one of my classmates knew of my daring plan.  When I confessed on Facebook Messenger that I felt as though my utterly ridiculous style change was not ridiculous enough, this happened:

Him: My recommendation: have the ponies dance by tilting them left and right with 2 stunning frames of animation.
Me: …oh my god
Me:  You’re a genius.
Me:  That idea was too much for Visual Studio, apparently, because it’s crashed.
Him:  You should be able to do it with the same CSS animation tools I used for blinky text.
Me:  It’s perfect.
Me:  You don’t know why it’s perfect because you are not looking at the pony extravaganza right now, but trust me, it’s perfect.
Him:  I’m helping!
Me:  You’ve just saved Christmas.

It ended up being more a gentle rocking motion than the original vision of “two stunning frames of animation”, but that actually ended up as a good thing.  The effect is mesmerizing.  He also suggested making the cursor into a pony, which is surprisingly easy to do with CSS3.  I remember back in the day when loading up a horrible, hard-to-use custom cursor on your Geocities page required a ton of JavaScript, but now all you have to do is something like this in your stylesheet:
body {
cursor: url("Other_Images/ponycursor.png"), auto;
}

So I had a custom pony cursor, dancing ponies, a rainbow gradient header background, fluffy clouds for the body background, I had a very girly cursive font courtesy of Google Fonts… and the majority of my content was the same.  For all intents and purposes, I had taken a very boring, adult website and overloaded it with pink/purple/rainbow/ colors and so many ponies.

Stephanie brought my awesome new pony sweater to class on Monday morning, and I parted with $8.  I put the sweater on and waited until just before lunch to present my masterpiece.

I got my laptop plugged into the projected and started.  The site begins looking like this:

site with normal stylesheet (boring!)

I clicked through the pages, pretending like nothing was wrong and like I also wasn’t wearing a pink fuzzy pony sweater.  A couple people who had seen the site that Friday were disappointed that the ponies were removed.  Good.

The project page has all of my bootcamp projects laid out in little display boxes.  There is actually a box for the ponies, and, because I have the projects being sorted alphabetically on the back end, they ended up right next to box for the portfolio project.  So I could laugh it off, haha, yeah, I put the ponies on here for you guys, you can find the ponies on Github.  (You can, for the record, find the ponies on my Github.)  I clicked into the detail view for the portfolio project to show off the jQuery lightbox (Fancybox) I’d used to scroll through the screenshots for the project… I had included one of the second stylesheet.

Down at the bottom of the page, tucked under the copyright information in the footer, are three small icons.  Clicking an icon fires an AJAX post to the server that resets the session variable; when the post is successful, some jQuery takes care of scrolling back to the top of the page and refreshing the browser window.  Some Razor at the top of the layout partial view for the site loads the session variable and uses it to determine which stylesheet to apply, so clicking the second icon flips it from the above image to looking like this:

moderate pony stylesheet

There were some laughs, oh, I got them good, haha, the site is purple and there’s ponies!  I clicked through all the pages on this, too, just to show that it was the same site with a different stylesheet.

But wait.  There are three icons at the bottom of the page.

I toyed with my sweater a little.  The thing about being an adult who likes My Little Pony, I said, not quite looking at anything, is that you really have to own up to it.  It’s not just a casual thing, you kind of have to really go big or go home… so I decided to go big.

Are you ready for Super Bonkers Pony Mode?

Are you really ready for Super Bonkers Pony Mode?

Because here it is:

super bonkers pony mode

The ponies in the header sway gently back and forth.  Constantly.  The cursor is a tiny pony (unfortunately, Windows screenshots don’t pick up the cursor).  The only thing it doesn’t do is play the My Little Pony theme song, because I absolutely hate websites that auto-play music… but I’m kind of thinking that maybe it should do that.  I was also hoping to get some things to sparkle, but the jQuery plugin I found to make DOM elements sparkle didn’t work, and I ran out of time to futz with it.

The reaction to Super Bonkers Pony Mode was outstanding.  I wish I could have taken a photo.  There was so much laughter.  It was everything I had hoped it would be.

On my peer review form, under the question, “What could be improved?  How?”  someone wrote:

Nothing.  She won, it’s over.

…and that, ladies and gents, is the story of how I won my coding bootcamp by ponyrolling.  Please hire me, I’m funny.