Simple Callout Boxes For Info, TLDR, And So On
Here's an example tl;dr callout box.
Background
I had a need for simple callout boxes for items like tl;drs, info boxes, etc., like the one you see above. I'm using a WYSIWYG editor that I structured into my admin backend views to work on my articles and I don't want to spend a lot of time editing html in the editor. Instead, the solution I came up with was to have designated classes to style the callouts along with a bit of javascript to add icons and labels depending on the class.
For brevity, I'm only demonstrating the tl;dr & info options, but there's a whole assortment you could add.
CSS
For the style, my goal was to be consistent with the color schemes that Bootstrap has already established. We're used to seeing those colors around the web so there's a bit of intrinsic context there. The tl;dr theme is not a Bootstrap color, however. Because it doesn't really fit with the info/success/warning/danger set, I went with a purple to remain distinctly removed from their domain. For the background colors, I simply blended white into the RGB codes three times to lighten (add 255 to each color code and divide by two).
p, ul {
padding: 15px;
border: 1px solid;
border-radius: 5px;
}
p.tldr, ul.tldr {
border-color: rgb(128, 0, 128);
background-color: rgb(240, 224, 240);
}
p.info {
border-color: rgb(13, 202, 240);
background-color: rgb(225, 249, 254);
}
ul li {
margin-left: 20px;
}
ul li:first-of-type {
margin-top: 10px;
}
.tldr .icon, .info .icon {
margin-right: 5px;
font-weight: bolder;
}
.tldr .icon {
color: rgb(128, 0, 128);
}
.info .icon {
color: rgb(12, 182, 216);
}
.tldr .icon > i, .info .icon > i {
margin-right: 5px;
}
JavaScript
To add another dimension of context, I use javascript to create a new element containing a Font Awesome icon and text label appropriate to the context. Because Font Awesome is moving towards a metered billing strategy requiring private "kits," I instead used their older Font Awesome 4 library to avoid this constraint so I don't have to expose a resource unique to my account in this example. If you're building this into your own project, you may want to create an account and use a private kit. There are free options available.
The flow of the JavaScript logic is as follows:
- Select the elements based on certain classes
- Loop through each element queried
- Generate a new element and give it a class of 'icon'
- Add the appropriate innerHTML containing the icon and label; and
- Prepend (add to beginning of parent) the child to the contents of the parent
// add icon and label to parent
const tldrContent = '<i class="fa fa-bolt"></i>tldr:'
const infoContent = '<i class="fa fa-info-circle"></i>info:'
const targets = document.querySelectorAll('.tldr, .info')
targets.forEach(parent => {
const child = document.createElement('span')
child.classList.add('icon')
if (parent.classList.contains('tldr')) {
child.innerHTML = tldrContent
parent.prepend(child)
} else if (parent.classList.contains('info')) {
child.innerHTML = infoContent
parent.prepend(child)
}
})
Result
Here's a Codepen to illustrate how everything comes together:
See the Pen callout-box by Ian Waldron (@Ian-Waldron) on CodePen.
Final Thoughts
If I were to continue adding functionality to this feature, I might check whether the contents of the parent element (<p> tag etc.), contain already something like a label. For example, the paragraph already begins with "tl;dr:" before the JavaScript runs. Since redundantly displaying this information could look a bit odd, you could check if the text contents begins with your labels and cut that text out if so. Since you might be affecting sentence structure, I would also check ensure there isn't any unexpected, residual punctuation before the content begins and that the first letter is capitalized.
That said, since I'm the only one working with content on my site, I'll just assume that I'm aware not to add any labels to the text contents directly and instead relying on the JavaScript to do so.