In creating a price a good place to start is to estimate how many hours it will take you to complete (including how many hours a month you plan to work in provided support). Once you have a number you should probably double it as you have to account for overhead (meetings, trading emails etc.) and for a lack of experience in making these estimates.
Pricing Like Zombie Punching is Hard
The Zombie Isn’t Always Right
While the “customer is always right” is said a lot, even if you believe that, they’re not hiring you to be a yes man or yes woman. Bring your expertise and tell them if a way they want to go is a bad idea. If they insist and it turns out disastrously, you’re on record as opposing the idea. If you don’t protest, they’ll blame you, anyway.
Format Zombies in the Neck
Typical formatting for HTML tags is to indent child tags (e.g., the <li>s), but leave the parent’s opening and closing tags (<ol> and </ol>) un-indented. This helps us visually see where tags begin and end. If you have child tags that have child tags, you just indent the grandchild tags again and so on.
Counting Zombies (on Your Fingers)
The letters i, j, and k are traditionally used as loop counters (a variable that counts the number of iterations used). You don’t have to use these as your counter values, but if you don’t, name your counters clearly. For clearer code, it’s best not to use i, j, or k for any other variable.
Looping the Reanimated Dead
If you’re writing an animation that loops, the easiest way to start is to set 0% and 100% to the same values. That way, the animation ends where it started, and you won’t have a jump between the end of one run of the animation and the beginning of the next animation.
Connecting Antidotes with Contagion
Connecting your design/website skills to the client’s business needs and goals can help the client say, “Yes!” to your proposal even if your pricing is higher than other proposals.
Fewer Keyframes, Fewer Zombies to Fight
It’s best to use as few keyframes as possible to get your desired result. Fewer keyframes are easier to manage and easier to update if you make a big change. That said, you need enough keyframes to get the movement or change that you want, so use as many as you need.
“You’re As Good at Picking Technology as a Zombie!”
“Your technology choice sucks.” Someone will always believe this to be true no matter what you choose. As long as you’ve thought through what technology to use and why, balancing the pros and cons, they are wrong.
Daisy Chaining Your Post-Apocalyptic Weapons
JavaScript processes functions, and so on, from the left, so you can daisy chain functions together like:
document.getElementById("list").appendChild( listOfHumanRefuges );Code language: CSS (css)JavaScript will take the document object and run the getElementById on it. When getElementById returns an element, it’ll then run appendChild on that element. If this is still confusing or makes less sense to you, there’s no need to worry about it. Structure your code whatever way makes sense to you and whatever way will make sense to whomever looks at it later (including future you)
CamelCasing Zombie CSS (in JavaScript)
About the only major CSS property that doesn’t follow the exact property name (e.g. color) or camelCase for hyphenated properties (e.g. backgroundColor) is float, because float is a reserved word in JavaScript. The CSS float property in JavaScript is cssFloat:
#zombie {
float: left;
}Code language: CSS (css)zombie.style.cssFloat = "left";Code language: JavaScript (javascript)In JavaScript, float stands for floating-point numbers, more commonly known as decimals, or any number that includes a decimal point. In computer science, integers (whole numbers with no decimal point) and floating-point numbers/decimals are treated a bit differently because of how they have to be stored by the computer.
Reordering the Undead
Switching things around on-screen (rows vs columns, etc.) will not change the order in the source code; thus, screen readers and search engines will read things in the code order. If the order of items affects how someone might understand the content, it’s best to change the source code/content, not just the visual display.
Transforming Transformed Undead
If you separate them with a space, you can do multiple transform functions at a time (e.g., a translation and a rotation). The order you put them in is very important, as the next transform function will take the result of the previous transform as its input. This means that if you translate and then rotate, you’ll have moved the element over, and then rotated it. If you rotate and then translate, the element and its X axis will rotate before it will be translated—it will be moved along an angle instead of right or left. This is best seen visually:
Try it Out:
Codepen Demo: https://codepen.io/undeadinstitute/pen/LYEoOxy
HTML Demo: https://undead.institute/files/animation/009-order-of-undead-transformations.html
Bookmarking Undead Forms
To make a form submission bookmark-able, e.g., like on a search page set the method attribute to get.
Misspelling Zombers
Proofread
Proofread
Proofreed
And than
Cheque yore spell ling manual lee four err ores.
Fractional Antidotes
CSS grid brought us the fr unit. 1fr or one fraction of the space is kind of like setting it to auto. However with fr units you can set multiple column widths and do more complex ratios e.g. grid-column-template: 1fr 3fr 1fr 2fr which would split up the area into four columns with the first and third being the same size, the fourth being twice the width of the first and third, and the second column being three times the width of the first and third.
Only Zombies Disregard Copyright Laws
Whenever you use images, be sure to follow their license. While it is common for people to Google an idea and grab images from that search to use on your site, except in very rare cases, that violates copyright law and you can be sued or required to pay retroactively for use of those images. While that’s less likely to happen for a social media post or something ephemeral you post just for yourself (unless you have a lot of followers or deep pockets) it is pretty likely to happen if you build a site for a business or post something for a business and use unlicensed and copyrighted images, because a business typically has deeper pockets than an individual and a lawsuit may be more worthwhile. There are many sources for licensable images, some even available for free, but don’t use an image unless the license says you can and if the license has requirements like attribution, be sure you attribute it properly and do whatever else might be required.
Excoriating Zombies
I was once excoriated on a public listserv of my peers and colleagues, a listserv I started. It was awesome in every opposite sense of that word. While the person probably went too far in a professional setting, many of her points were accurate, and I might have dismissed them if they weren’t delivered in such a caustic manner. Much as I hate to say it, because of her feedback, the work was better.
Try to set your pained feelings aside and look at it objectively. If part of you agrees with their assessment of the work, swallow your pride, smash a zombie in their honor, and make it better.
Well the Zombies Might Come…
Building a site/page/etc is one thing. Getting people to come to it is a whole other thing. “Build it and they will come” may work for baseball diamonds in cornfields, but it doesn’t work on the Internet. Create a marketing plan ASAP if you want anyone to see your work. It doesn’t have to be long or detailed, but the if-you-build-it-they-will-come marketing strategy almost never works. You cannot count on being in that other portion.
No Following (or indexing) Zombies!
The nofollow and noindex are the oldest and best supported suggestions to search engines. They prevent links in comment spam and other types of content you can’t control from affecting your SEO (and to prevent zombie sympathizers and other internet degenerates from preying on your innocent site in attempts at garnering search engine rankings).
Regularly Express Your Zombies
Regex aka Regular expressions are powerful ways to search for patterns in text. While this isn’t technically web development, a lot of web development involves manipulating text and there’s nothing better at manipulating text than regular expressions.
Fence Off Undead Dates
You can use min and max attributes to put upper and lower limits around what dates you want a user to use in a date input.
Functional Contagion Size
While there is some disagreement on the best way to use functions, whether you do almost everything in small functions or use more monolithic functions, both have their advantages. More functions can make it harder to follow the code and can make things confusing because the code won’t be as linear and will jump around from location to location wherever the function is defined. If something’s wrong, it’s confined to a rather small section of code. Using more monolithic functions can make it easier to find the function the problem is in, but that is often an extensive section of code.
I’d recommend a middle approach. When you start out, have your functions do one thing at a time and anything you do multiple times. They’re easier to debug (figure out where the code went wrong/why it’s not doing what you intend), and, once you have some practice, you’ll get a handle on when you need a function or not, and what makes sense to you.
Some Zombies Are More Equal Than Others
How can things be more or less equal (outside of Animal Farm)? This is because of one way that a computer saves memory. Our bucket metaphor will break down a bit here, but let’s say we had a bucket full of something complex, such as a loaf of bread. There’s a lot of information there. It’s complex, and it takes up space.
The human resistance commander needs to see what rations are available, but he’s in the field with the resistance fighters. We could create a copy or 3-D model of the bread (super easy in this computer-i-fied example), but that would take up as much space as the original, and we might run out of buckets. We’d also have to transport the bread or model out to him, which can get complicated when you have quite a few buckets to transport.
So we take a picture of the bread instead. In very general terms, the loaf and the picture are equivalent because one is the loaf and one points to or is a picture of that same loaf. (In computer science, the picture from our analogy is called a pointer because it “points” to the original.) That’s the double equals == level of equality. The triple equals === is when you’re trying to see if two loaves of bread are the same or, rather, if one of them isn’t a pointer to/picture of the other.
In code, a simplified version of that might look like
7 == “7” //true
7 === “7” //falseCode language: JavaScript (javascript)Transforming Undead Boxes
To be transformed using the transform property, an element must use the CSS Box model—that is, it must be a flow element or set to some flavor of display: block (display: grid and display: flex count too, but any that include “inline” do not).
Letter-space that Zombie in the Gut
You should use word and letter-spacing rarely and intentionally. Fonts have built-in kerning for most situations, but there will be times when you need to make adjustments. This will often be for headings and larger text as opposed to body copy. For instance, if you create a headline in all caps, adding a little letter-spacing can make it more readable.
Pseudo-Elements and Voidable Contagion
Void tags (those that have no closing tags, such as input and img and br) cannot contain before or after pseudo elements. Unless you use a CSS trick where you set the appearance property to none. This prevents the browser from replacing the element and allows you to have pseudo-elements (that said, you’ll also not have the image or form field you replaced, so only use this when you know what you’re doing check out: https://www.htmhell.dev/adventcalendar/2023/2/ for a usage example and some more info)
Collapsing a Zombie in the Face
One weird thing about vertical margins in CSS is margin collapse. It’s when two (but sometimes more) margins combine into a single margin that’s only as tall as the tallest margin. It happens most often when you have two adjacent elements. If the top and bottom margins are set to 2em on both the first element and the second element, the distance between them will not be 4em, but 2em because the margins collapsed. This can also happen if both an element and its first child have margins set. For instance if you have a div with a top margin of 2em and an h3 as its first child with a margin of 1em, you’ll have a 2em total top margin. The h3’s margin will collapse into its parent’s margin.
There are a few other cases where this may happen too, but they are less common. Check out this Mozilla Developer Network article for more details: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing
Deleting Zombies
You can delete and modify elements from within developer tools. It, of course, won’t delete/update the element in your files or from a site on the server, but it can let you see what would happen if an element wasn’t there or had different data.
Performative Zombie (Re)Animation
For better performance, use transformations in your animations. Moving HTML elements with margin and padding will bring the client computer to its knees and make your site look amateur.
Blending Zombies in the Face
Blend modes can add depth and interest to your work (they can also help you create complex imagery directly in the website). You can use background-blend mode to blend an element’s contents with its background-color, while mix-blend-mode mixes an element with the elements below/behind it. Possible blend modes include multiply, screen, overlay, darken, lighten, color-dodge, color-burn, hard-light, soft-light, difference, exclusion, hue, saturation, color, and luminosity. (For an in depth look at how each of these blend modes work, check out Advanced CSS: Zombie in a Ballgown)
SVG Symbolizing the Undead
The <symbol> SVG element takes reusability to a whole new level by embedding its own coordinate system inside the element. The symbol’s content then no longer has to obey the SVG’s larger coordinate system and you can resize, reshape or do whatever you need to the repeated element.
Debugging Zombies
Sometimes adding a temporary background color or border can be the easiest way to see what’s happening on the page and to get a handle on what your code is actually doing.
Can You Use Zombies?
Caniuse.com has lots of great info on what browser versions support what HTML, CSS and JS features. Which is really helpful in knowing what you can do given your audience and the browsers they use. If you don’t have that information, you can start collecting it with analytics, or if there’s no current website, focus on the most common versions of each browser.
Decreasing Specificity Weapons
Most often you need to increase specificity, but every once in a while you need to decrease it. You could use a class instead of an id, but that might be that much more clutter or maybe you can’t change the HTML. One way to do it is instead of using the id of the element, you can use an attribute selector to select the id, reducing it to class specificity while still selecting the exact id you want.
<div id="zombie"></div>Code language: HTML, XML (xml)[id="zombie"] { }Code language: JSON / JSON with Comments (json)Project vs. Hourly Zombie Smacking
I prefer project based payment to hourly payment. I think project based payment puts the incentives in the right place for everyone. If I finish a project in less time than I think I will, my hourly rate goes up. I also have an incentive to complete the project early, whereas with hourly work, the incentive is to take longer so you can charge more. The project-based customers also know exactly what they’re paying and you won’t surprise them with a higher bill than they expected. The downside, though, is if the project takes longer than I expect. So you probably shouldn’t start out with project pricing and should only move there when you have a handle on how long a project might take, how to set boundaries with client requests, and what your time is worth.
Thwacking Spacing Zombies
When using Flexbox for a three-column grid, you can add an ::after pseudo element to the end of the parent element to help space-* feel more natural on the last line. If there are only two items in the last row, they often get spread to each side. The pseudo element acts as a third element in the list and thus pushes the last real element to the center position. If you then have three elements on the bottom, it’s 1px tall and shouldn’t have much impact on your layout. Make sure the pseudo element is 1px high so that if it overflows to the next line, it won’t cause any issues. See it: https://codepen.io/undeadinstitute/pen/xxpBomZ
Post-Apocalyptic Database Weapons
Having some SQL knowledge probably won’t directly help you build a site, but it can come in super useful if you’re moving a site from one place to another or creating a new version of a site that handles things differently. You also don’t need a lot of SQL knowledge, just a good enough understanding so that you know what SQL can do for you. Most of the time I look up the syntax and format of any SQL command I need to write right before I write it.
Custom Undead Weapons
Custom properties are kind of like CSS variables. You set them by adding two dashes followed by the variable name. Then put whatever you want the variable to hold after the colon.
--zombie-color: chartreuse;Code language: SQL (Structured Query Language) (sql)To get the value out of the variable/custom property use the var function
color: var(- -zombie-color);Code language: JavaScript (javascript)In this way you can update one property and change all or most of the colors on a site e.g. for a dark mode version.
You can also add a default value so that if the variable can’t be found you have a fallback.
color: var( - -zombie-color, yellowgreen);Code language: JavaScript (javascript)Clients Aren’t Zombies (Even If They Act That Way Sometimes)
Your client doesn’t always know what they want or, worse, they don’t always know what their boss wants. It’s often your job to help them figure that out before you can do the work they hired you to do. This is very frustrating, but if you can stick it out and get buy-in from who you’re working with, they’ll be clients for life and/or provide a great recommendation/testimonial.
Automatic Undeading
If you want to center an element horizontally within its parent element using margins, you need to set it to display block (if it’s already a block-level element you don’t need to set it explicitly), you need to have defined a width, and then you can use margin: auto;
<div class="centering-the-zombie">Zombie</div>Code language: HTML, XML (xml).centering-the-zombie {
display: block;
width: 100px;
margin: auto;
}Code language: CSS (css)You can also set the top and bottom margin using the shortcut property and still set the left and right margin to auto like so
margin: 1em auto;Stop Zombies with Reading
Line-height is just one of many factors affecting readability. Font-size, font-family, and line-height have the biggest impact overall though.
Meta Robots vs. Zombies
To use more than one value in your meta robots tag, separate them with a comma.
<meta name="robots" description="nofollow, max-snippet: 77">Code language: HTML, XML (xml)You Can’t Stop Zombies With Zombies
Don’t use deprecated/obsolete/zombie tags and clean them up when you can. That said, if they take more time to clean up than is worth it, they shouldn’t hurt much.
Post-Apocalyptic Structural Elements
All structural elements (header, footer, nav, main, etc) render as block level elements, but show no visual difference between them. However, by looking at the tag, you know something about the content in it (assuming the developer coded it correctly). This makes it easier to maintain but also provides a wealth of information to Search Engines as they rank your site and visually impaired users who might use screen reader software to access your site.
Better Performance; Better Zombie Smashing
For users on mobile with an often shaky or slow connection, the faster you can get your site to them and the faster it can run on their low-powered processors, the happier they will be. And happy users are users that kill zombies (and buy your stuff).
Multi-variable Zombie Punches
In JavaScript, you can define more than one variable at a time by using a comma between variable names. I’m using let below, but it works with var and const too.
let zombie, undead;Code language: JavaScript (javascript)You can also set their values while chaining them:
let horde = 700, humanityInTrouble = true;Code language: JavaScript (javascript)Margin: auto the Zombie’s Face
You can use margin: auto to center items horizontally, but you can also use it to separate items in a flexbox layout.
If you’re creating a menu, it’s not uncommon to need the main portion of the menu on one side of the page and one or two links on the far side. Add an auto margin to the left side of the item you want on the far side (if the main portion of your menu is on the right side, put the auto margin on the right side). The automatic margin will fill the available space and push the two sections apart.
Floating All Children on a Parent
When floating all children in a parent element, the children no longer contribute to parent’s height making the parent’s height 0. That means a background color won’t show behind those elements nor will a border show around them.
<div class=“zombie-nest”>
<div id=“fred” class=“zombie”></div>
<div id=“keesha” class=“zombie”></div>
</div>Code language: HTML, XML (xml).zombie-nest {
background-color: chartreuse;
border: red 1px solid;
}
#fred {
height: 100px;
width: 100px;
float: left;
background-color: peachpuff;
}
#keesha {
height: 100px;
width: 100px;
float: right;
background-color: orchid;
}Code language: CSS (css)Use the overflow property to make those floated child elements contribute to the height again. Just about any value besides the default (auto) should work, but I tend to like hidden, particularly if I don’t need the floated elements to show outside the parent.
.zombie-nest {
overflow: hidden;
}Code language: CSS (css)Drop-shadow vs. Box-shadow vs. Zombie Shadows
One important distinction in the syntax between drop-shadow and box-shadow is how to do multiple shadows. In drop-shadow you need to repeat the drop-shadow function for each shadow you add to the element. Box-shadow allows you to just add a comma.
.zombie4a {
filter: drop-shadow(15px 15px 5px greenyellow) drop-shadow(-15px -15px 5px greenyellow);
}
.zombie4b {
box-shadow: 15px 15px 5px greenyellow, -15px -15px 5px greenyellow;
}Code language: CSS (css)Animation Direction (Rolling Back and Forth Over Zombies)
The last frame and first frame of an animation will depend on the animation-direction property. CSS considers this based on the play order i.e. what frames are played first or last. So if you run the animation normally the first frame will be 0% and the last frame 100%. If you run the same animation in reverse, the first frame would be 100% and the last frame 0%. If you alternate it, wherever the animation starts is the first frame and wherever it finishes is the last (thus, in the case of alternate, it will also depend on the animation-iteration-count).
Language Attributes and HTML
For increased accessibility, add a lang attribute set to the language of the page; for instance, or or.
Zombie Clients and Their Requests
When (not if) you have a client that seems completely unreasonable, try to first give them the benefit of the doubt. Maybe their text came across different than they intended or they were making a joke that didn’t work in the format they were using. Give them the benefit of the doubt and try not to take anything they say personally. Try also to talk to them to better understand what’s going on and what they’re seeing from their point of view. This tends to clear up 90% of issues, but if you’ve tried your best to see things from their point of view and made every attempt at working through an issue or miscommunication and they’re still completely unreasonable, drop them like a zombie shuffling toward your Mom. (Of course, make sure you do it when contracts allow. If you break a contract it makes you look bad and will probably make things worse between you.) Just because they are your client doesn’t make them right and it also doesn’t make them your boss (unless you choose to look at them that way)
Flattening SVGs (and the Undead)
When exporting an SVG from a graphics editing platform try setting it to flatten zombies… errr… I mean flatten transforms. This may lead to an initially larger file, but once optimized with svgomg or svgo it may end up being much, much smaller. Plus editing or animating parts of the SVG file later will be much more straightforward.
“The Pre-apocalypse, Google Bombing, and Failures”
Nothing can drive home the importance of link text better than a situation back in 2006 when if you searched for the phrase “miserable failure” on Google, the number-one result was the official bio page for the sitting US president, George W. Bush. The second result was someone from the opposite ideological perspective, filmmaker Michael Moore. Neither of these men wanted to rank for those keywords, nor did they have those keywords on their websites. A group of people got together and began linking to the pages for Mr. Bush and a different group linked to the pages of Mr. Moore using the same phrase “miserable failure.” Enough people did this that Google associated both sites with that search term, viewing the link text as a label for that site. Thus, when you searched “miserable failure,” the pages for these men came up. Today we call this Google bombing. Since then, Google has changed its algorithm to decrease the likelihood of this kind of campaign working. That said, the link text you choose is still very important.
“Working for Family, Friends and Zombies”
When you’re starting out it’s tempting to take on projects from family and friends to get some experience and when experience is the most important thing, go for it. But family and friends are often the worst kind of clients (other than zombies): getting your time for free and valuing none of it. As soon as you have a portfolio you are proud of or have landed the kind of job you want never take another family/friends job unless you want to AND they pay you. You can give them a discount, even a deep discount, but they need to know your time is valuable (and at the end, if they were a good client and you didn’t consider letting a zombie bite you just to get away from them, charge them less than you said you would). The same absolutely goes for charitable organizations.
Centering Elements (in their Horde)
The easiest way to center an element vertically is to punch a zombie in the face, then set display: grid on the parent and set align-items to center. (You can also center it horizontally by kicking a zombie in the shin and setting justify-content to center)
Show Links In Printed Websites
You can make a link show up on a print page using pseudo elements and the attr function like this:
a::after { content: “ (“ attr(href) “)”;}Code language: CSS (css)This will make a link like Zombie Smashing Awesomeness appear as:
Zombie Smashing Awesomeness (https://undead.institute)Code language: JavaScript (javascript)when printed.
Preloading Your Zombie Smashing Weapons
You can preload custom fonts using
<link rel="preload" as="font" href="zombie-fonty.woff2">Code language: HTML, XML (xml)in your head. This allows the browser to schedule the download of the font even before it finds the font in the CSS @font-face rule. It’s kind of like letting the quartermaster know about a particular need or requirement before he finds where it’s listed. He can send an assistant to get it at the beginning instead of waiting till he’s waded through a mountain of paperwork.
SVG Compression and the Undead
Like a limbless zombie, SVG paths are almost always the most compact form of drawing in SVG and optimizers will typically turn other elements into paths to make the SVG smaller. However, they can only optimize what’s already there. If your graphics program converted a drop-shadow into an image (a common though unnecessary step), they won’t be able to rewrite that image, or put it back into a vector.
Floating (Zombie) Bullets
If you ever float an image or other element left and wrap text around it, most text wraps fine, however, if you use an ordered or unordered list you’ll find the bullets/numbers aren’t indented the way you’d expect. Often the text is aligned with the other text e.g. paragraphs above and below it and the bullets or numbers are hanging out in space to the left, sometimes even on top of the element you floated. The margin and padding of the list is applied, but it’s applied in the far left, basically underneath your floated image. Like a zombie bunker, you can add more padding and margin to try to overcome the issue, but that assumes that you know the size of the images and that every time the list and image/element match up, is the same size or same proportions. There is a simpler way to solve this though, add the overflow property to the list element (ul or ol). It will then include the margin and padding as you would anticipate and the list will look like it’s supposed to anywhere else on the site.
Semantically Stopping the Apocalypse
Semantic code helps ensure consistent browser rendering because the browser has to make fewer decisions (read guesses) about what you intended. It knows how semantic code should be displayed. It does not know how some non-semantic gobbledygook somebody handed it is supposed to be displayed and so it guesses. Different browsers will make different guesses and thus there will be inconsistencies between how they show your non-semantic code. Meaning zombies will shuffle right through your fingers and into the wider world.
Units and Custom Properties
You can add units to a number from a custom property by multiplying by 1% or 1em etc. But, like the contagion and human cells, you cannot remove them (yet).
Cursor(ing) the Apocalypse
You can change the cursor icon using the cursor property. Be careful when you do this as it can cause confusion , accessibility, zombification and/or user problems if you use it too often, but, every once in a while, changing the type of cursor someone sees e.g. a resize cursor on something you’ve made resizable that the browser doesn’t pick up on, can really help your users understand your site better.
Lazy Loading (the Undead)
loading=“lazy” is an attribute for images that allows it to be loaded later unless it’s needed i.e. when it’s visible in the viewport. In this way you can hold off downloading images further down the page (like setting the zombies to come in one-by-one vs all at once). This prevents those images from delaying the initial load or otherwise slowing down the page making the page feel snappier and your users happier. Plus once everything visible is downloaded, it’ll start downloading those images even if they aren’t in the viewport yet.
Usability over Beauty
Though it pains me to say it, in most cases usability should trump beauty (except in zombies, ugly trumps everything for zombies). That doesn’t mean ugly sites are the most usable, far from it. A site can be usable without being ugly and a site can be ugly without being usable, but if you ever have to decide between keeping a feature beautiful and making more plain but usable go for plain and usable. Users won’t remember the color of the button, but they will remember how the text on it was too small and had too little contrast from the background.
CSS and SVG Transforms
Like an equal caliber measured in mm vs one measured in inches, CSS transforms and SVG transforms are the same. They do the same thing. Work the same way. And you can continue or modify a transform from the SVG in your css. However, their syntax is slightly different e.g. SVG transforms use commas to separate their values whereas CSS uses spaces.
Contrasting Zombies
Get your color contrast correct. Dark text on a dark background, light text on a light background, middle text on a middle background, zombie text on a zombie background; all of these make distinguishing between letterforms much harder for the site visitor, let alone hit the zombie with the full force of a font. Adding contrast between the text and the background can make your site more usable (and more deadly to the undead).
Lately Loading JavaScript
You want to load your JavaScript code as late as possible in the downloading of the site—that is just before the closing body tag. If you load it earlier, such as in the head element, it can block the download of other assets (like zombies blocking a doorway with their bodies after you smack them with an HTML element). The total time spent downloading will be the same wherever the JavaScript is placed, but if it blocks download or rendering because the browser is waiting on your js file to download or your js code to execute, it can prevent the rest of the page from displaying, giving the user a blank screen for longer. Even if the page isn’t functional until the js loads, the user likes to see that things are working, and the browser rendering what it can will help. A blank page, like a zombie’s blank stare, usually means something is broken and users will assume as such. Some JavaScript may need to be executed before the page loads or to determine how the page loads, so the head may have some JavaScript in it, but push it to the bottom if you can.
Keep Learning New Ways to Stop Zombies
Take time to sharpen your skills. Coding challenges, hackathons, and satisfying your own curiosity are all great ways to keep working on your skills, expanding your knowledge, and holding down the zombie population.
Anonymous, Erroneous Zombies
Error 3014. Yon website has error-like conditions.
While it can be helpful to know that an error occurred, error messages like the one above aren’t helpful to visitors and don’t give them enough information to know how to fix an issue they may have caused. It’s even worse if this generic error message appears for multiple separate issues.
Make sure any error messages are robust and descriptive (unlike zombies). A visitor should be able to attempt to resolve any error they have control over e.g., putting the wrong input in a form field or when getting a 404 page (a page not found error). If it’s not something the visitor can fix themselves, they should be able to give enough info to your site support staff for the staff to know how to fix the issue and/or guide the visitor around the issue.
A secondary bonus here is that visitors should need less support and a percentage of those that do still need support should have the tools to help your support staff address the issue quickly and easily.
The SVG Stack
SVG stacks elements farthest from the viewer to closer to the viewer so the elements at the top of the file/element are at the back of the horde and elements at the bottom of the file are chomping on your face.
Safari Safari Duplicating Content Content
There is one egregious issue when using column-span in Safari. It sometimes duplicates the content above and below the span, so a paragraph or heading that exists in the code after the spanning element may appear both above and below the spanning element. Honestly, sometimes I think the browser makers want the zombies to win!
The Negatives of Subtracting
When using CSS’s calc() function, particularly when subtracting, be sure to put spaces around your hyphen. If you don’t the browser could interpret the subtraction sign as a negative sign (negative 5 pixels instead of minus 5 pixels) and the results may be different than expected or the browser, like a zombie who swallowed the tweezers from Operation the board game, might choke on the lack of an operator.
The Smart Thing About the Browser Ignoring Things It Doesn’t Understand
Browsers ignore tags and such that they don’t understand. So, if you’re showing Mom your web exploits on her computing dinosaur, the picture and source elements may get ignored, and it’ll just display the one it knows: the img tag. In this way we can add new things (HTML elements, CSS properties etc) without old browsers breaking or choking on the cool new things that we can use in new browsers.
Hovering on Mobile
Just like a zombie can’t comprehend a levitating magician without consciousness, you can’t hover on a touchscreen.
Full Width Elements
If you have an image or other piece of content that you want to be the full width of the browser window, even if its parent is smaller than that, you can use these three properties to make it happen.
width: 100vw;
margin-left: 50%;
transform: translateX( -50% );I’m not certain where I first saw this trick, but I believe it was on https://css-tricks.com
Daisy Chains, the Undead, and JavaScript Functions
JavaScript processes functions, and so on, from the left, so, while you can do it in multiple lines like a horde spreading out in ranks, you could also daisy chain functions together like:
document.getElementById("list").appendChild( listOfHumanRefuges );Code language: CSS (css)JavaScript will take the document object and run the getElementById on it. When getElementById returns an element, it’ll then run appendChild on that element. If this is still confusing or makes less sense to you, there’s no need to worry about it. Structure your code whatever way makes sense to you and whatever way will make sense to whomever looks at it later (including and especially future you).
Attribute Selectors and Performance
Use attribute selectors sparingly as they, like zombies hanging onto your car, can slow down your site if you have too many of them. Also if a narrower search function will find the element you’re looking for, use that over a wider search function as it should resolve more quickly.
Searching for Answers (and Antidotes)
Besides antidote creation, the ability to search for answers is one of the greatest skills you can have in web development. And if you can’t find the answer, ask for help. If you bang your head against a problem for what seems like forever and googling doesn’t help. Ask for help. You can ask on social media, on stack overflow or ask me directly (john@undead.institute). If I can answer your question or point you in the right direction I will. (Note: You can always ask an AI overlord for help too, but thoroughly test any answer they give as they’re known to hallucinate)
Listen to the Humans (Not the Zombies)
Swallow your pride and get lots of opinions about your work. That said, a zombie review may be more hurtful than helpful. Cultivate opinions and perspectives that are thoughtful, different from yours, and oriented toward making the best site possible (and towards smacking zombies).
Text Size and Readability
Keep your body text at or above 16px/12pt/1em to ensure readability and that zombies won’t eat your brains while you’re focused on reading too tiny print.
Zombie Index Inflation
Z-index should have reasonable numbers not so many 0’s that you’re sure it’s above the last one (that’s like sending a horde to check someone’s height). That said, leave some space. Don’t number by 1’s, number by 5’s, 10’s, or even 100’s so that if you ever have to stick something in between you don’t have to renumber everything. You can just slip it in halfway between the two elements you placed.
Underlined Cheating
Just like zombies and death, you can cheat a link’s underline and have more control over it using a border bottom instead of the default underline. In this way you can change colors, add thickness, make them dashed etc. though you’ll miss out on text-decoration-style: wavy;
Meta Keywords Isn’t Good For SEO
You may have heard of meta keywords tag:
<meta name="keywords" content="zombie, undead, web development, HTML, CSS, SEO">Code language: HTML, XML (xml)While we used it at the beginning of search engine optimization, it was abused, so search engines now shuffle past the meta keywords tag like a zombie hot on the trail of fresh brains. You may still see it in the wild, but you can ignore it. And if you see it, it wouldn’t hurt to delete it.
Choose Your Characters Carefully
Don’t use spaces in file or folder names or in urls in general. Sometimes servers will recognize spaces, sometimes they won’t and sometimes the same server will recognize them in one context but not in another. Save yourself multiple headaches and use a hyphen in place of spaces.
CSS Clamp Function
Clamp() – a CSS function for keeping a value between two extremes. The value won’t go above the max value and won’t go below the min value. This is particularly great for responsive design and font sizes. You can set the font-size in vw units so that it scales seamlessly as the page’s size changes. However, that’s likely to make the text too small to read on some mobile devices and might make it way too big on a particularly large desktop monitor. Thus clamp allows us to set thresholds across which the font-size doesn’t go, but still have text that seamlessly scales with the size of the window.
font-size: clamp( min, variable-size, max );
font-size: clamp(1.25rem, 3vw, 5rem);Code language: CSS (css)Container Queries
Container queries let you change a component’s look and feel based upon the size of the container. So if the component is in a small space, it will show one way and if it’s in a larger space it’ll show a different way. They’re just like media queries except they work based on the size of the parent not the size of the entire screen.
Shorthand Gotcha
Shorthand properties overwrite any value that isn’t set in the shorthand. For instance, if I set a background-image and then use background: no-repeat to prevent the image from tiling you’ve actually canceled the background image because the background short hand reset it to its default value.
Outline Property
Outline works similarly to border, but doesn’t contribute to width. It can be used to highlight an element during debugging without affecting your layout in any way. It also appears outside the border and thus can be used to highlight items that already have a border.
The Only Rule You Shouldn’t Break
Rules for great sites are generally helpful, but they are not inviolate. The only unbreakable rule is that you must have a good reason for breaking a rule. Every break brings some level of cognitive dissonance. Minimize cognitive dissonance as much as possible, but if it’s gone your site won’t be interesting.
Hexadecimal Transparency
You can add a fourth pair of hexadecimal numbers to a hexadecimal color to set an alpha value. FF would be fully opaque and 00 would be fully transparent e.g. color: #88DEAD88
Color Coded Code
Color coded code editors make your code a lot easier to read and help you spot errors when code you expect to be colored one way isn’t.
Feedback Shouldn’t Make You Cry
In design and even in development there can be a lot of negative feedback which is easy to take personally. Don’t. Just because someone doesn’t like what you did or the choices you made doesn’t mean you’re bad at your job. There is, however, always room for growth so if their feedback makes sense to you, take it under advisement.
Language Variants
If your website has several regional variants of a language, pick one and don’t include the region it applies to. This will then serve regional versions to those regions you’ve defined and ensure that any regions you don’t have a specific variant for still get a version in their language.
Usability Test Early, Usability Test Often
Do usability with paper sketches if you have to, but test the usability/intuitiveness of your site early and often.
Inputing Min and Max
In input fields, Minimum and maximum numbers are inclusive.
Boolean Attributes
Some HTML attributes, like most apocalyptic politicians, do not require values. These are usually boolean (true or false) in nature, and so adding the attribute constitutes true. For example, in the video element, if you want to include play/pause/stop controls, you can use the controls attribute
<video controls width="300" height="150"></video>Code language: HTML, XML (xml)Dot, Dot. Who’s There? Parent Directory
It’s not often needed, but it can be confusing if you don’t know what it means. Two dots in a path (..) means the parent folder. If you have <img src=”../images/zombie.jpg” alt=”Slobbering”> would mean go up to the parent directory of the current directory then into the images folder and then to zombie.jpg
Break Points And Design
When creating a responsive design don’t base your break points on hardware unless your site will be used under very, very specific hardware requirements. Otherwise it’ll be a never ending game of whack-a-screen. Instead place your break points based on the content and design of your site. This will ensure that everyone gets the best experience.
When 2 + 2 is actually 22
A common place where JavaScript’s internal typing system happens is when you try to add a number (2) and a string that looks like a number (“2”). In JavaScript, 2 + “2” is “22”. Since one of these is a string, it casts/treats the other as a string too and puts them together or concatenates them. This can be very useful when you need to construct a message for the user, but can cause weird errors if you don’t what type a variable holds.
Embedded vs. External vs. Inline Styles
99 times out of 100 external stylesheets are the way to go, but embedded sheets come in handy if you don’t have access to the site’s main styles or if you need to make specific changes to one page that you don’t want to make everywhere. Inline styles should be avoided as much as possible because they are difficult to override and work against the cascade requiring each element to be updated by hand. That said, it can come in handy when you’re in a jam and need to make updates to a handful of elements, don’t have access to the main style sheet and can’t use a style element.
Two Kinds of Web Components
There are two kinds of web components: autonomous (name your own element) and customized built in elements (supercharge an existing element). Note: Safari does not support customized built in elements, but all other browsers do. Custom elements require a dash in their name and some JavaScript. Custom built in elements need the is attribute and some text
Disabling Zoom on Mobile is Bad
Don’t disable zoom on mobile:
Bad:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> Code language: HTML, XML (xml)Good:
<meta name="viewport" content="width=device-width, initial-scale=1"> Code language: HTML, XML (xml)Disabling zoom can cause a host of accessibility problems. Plus if you’re on a website and you try to zoom and can’t do it, is your response, “Oh wow, I love this developer and his choices”? That’s not my response. Don’t be that developer. Let the user interact with your site the way they want to.
Practice. Practice. Practice
Practice. That’s how you get to Carnegie Hall and web development/zombie killing greatness. The more you build the better at this you’ll be.
(If you don’t have a shady cousin who needs a new site for their latest get rich quick scheme or an elderly Aunt in need of an online showcase for her collection of doilies, or if you simply don’t know where to start, I’ve got a book that can help. https://undead.institute/2022/05/22/forty-three-post-apocalyptic-website-project-ideas/)
Start Testing Usability Now
You don’t have to wait till a site is built to test for usability. You can test usability of a sketch or mock-up by just asking people what they’d click on (even if clicking isn’t possible). Usability test early and often. If you wait till the end you’ll only be able to band-aid any significant problems you find. If you catch it early it’s more likely you can save them from a living death after the apocalypse.
Pseudo Elements
Pseudo elements are like elements but aren’t quite. The most common pseudo elements are ::before and ::after which allow you to insert content into an element. ::before is put into the element right after the opening tag and ::after is put in right before the closing tag. (Note: elements without closing tags e.g. img, input, br, hr, etc cannot have ::before and ::after because there’s no place to put them). Other pseudo elements are ::first-letter, ::first-line, and ::selection which select the first letter of content in an element, the first line of content in an element and the content you’ve highlighted with your keyboard and/or mouse, respectively.
Object-fit
Allows you to treat an inline image as a background image, making it easy to contain or cover the image and allow you to change the aspect ratio without squashing or stretching the image. Learn more at https://developer.mozilla.org/en-US/ docs/Web/CSS/object-fit
Select Input by Type
Use attribute selectors to select and style inputs of various types differently.
input[type="text"]
input[type="search"]
input[type="color"]Code language: CSS (css)Responsive Videos
Video is one of the hardest thing to make responsive. But this article gives you a number of ways to make sure videos look great at any screen width https://css-tricks.com/fluid-width-video/
Rounding Out Your Elements
You can create a fully round object (to throw at zombies) using border-radius: 50% however, if you want to make a pill shape set it to an arbitrarily high number like 100em or 1000px.
Relatively Positioning Absolute Elements
You can localize where an absolutely positioned element is placed by setting a position: relative on the parent element. Instead of letting a zombie wander all over, you lock him in a cell so he can only shuffle around within a defined area.
<div id=“zombie-dad”>
<div id=“undead-daughter”></div>
</div>
<div class=“zombie-dad”>
<div id=“undead-son”></div>
</div>Code language: HTML, XML (xml)#undead-son { position: absolute;}
#undead-daughter { position: absolute;}
#zombie-dad { position: relative;}"Code language: CSS (css)Complex Animations
To more easily animate complex transforms separate out two or more kinds of transforms e.g. a rotate and a scale by adding a wrapper element and performing one transform on the wrapper and one on the child. Generally the first transform on your list should on the parent and the second one on the child. You can also use the new translate, rotate and scale properties. They should work for most needs, however, they have a prescribed order (translate, rotate, then scale) which may not fit your needs and there’s no way to do skew or 3D transforms with the single properties. Lastly you also can’t break up translating x and y directions the way you could with two elements.
Targeting by Mouse Type
Coarse pointer media query lets you differentiate between a coarse pointer (touch screens and similar) and a fine pointer (mouse, pen/tablet etc). It’s a really simple way to provide fallbacks for hover animations and other things that don’t work on touch screens.
@media (pointer: fine) { /* Mouse */ }
@media (pointer: coarse) { /* touchscreen */ }Code language: CSS (css)The ol and ul Type Attribute
On ol/ul elements the type attribute let’s you change what type of numbering/bullets used. With ol set the type to “i” for lowercase Roman numerals or “I” for uppercase ones. “A” sets capital letters while “a” uses lowercase ones. On ul change the type with disc (default), circle or square. You can also use the start attribute to start the numbers at a different place or the Boolean attribute reversed to reverse the order and have the numbers/letters count down.
Shorthand Properties Gotcha
Shorthand properties overwrite any value that isn’t set in the shorthand. For instance, if I set a background-image and then use background: no-repeat to prevent the image from tiling you’ve actually canceled the background image because the background short hand reset it to its default value.
Promise Low. Deliver High.
It is far better for both your short term and long term career to promise low and deliver high rather than to promise high and deliver low. And even if you promise high and deliver high, you’ll be killing yourself just to meet the client’s minimal expectations.
Performant Animated Moves
When animating, use CSS transforms to move items around and scale them rather than changing padding/margin or width/height. Transforms will dramatically increase performance and prevent browsers from doing costly repaints.
Link Pseudo-Classes
If you want to avoid zombie attacks, the link pseudo-classes should be in this order: :link, :visited, :focus, :hover, and then :active. If you order them differently, the specificity/placement of one will override the functionality of another.
filter: drop-shadow() vs box-shadow
While you’ve likely heard of box-shadow you may not have heard about the drop-shadow filter. box-shadow does a very nice shadow, but it’s always a box.
<code>box-shadow: 1px 1px 10px #000; </code>Code language: HTML, XML (xml)On the other hand the filter: drop-shadow() will do an exact drop shadow of the element so if you’ve rounded corners or have an SVG with some transparency or whatever drop-shadow() will give you a drop shadow of your exact element and, when available, you’ll get hardware acceleration to boot.
filter: drop-shadow( 1px 1px 10px #000);Code language: SQL (Structured Query Language) (sql)More Ways to Respond
Media queries don’t stop at device width or height. They can also handle things like screen density, animation preferences (like prefers reduced animation) and much, much more
The Current HTML Standard
HTML5 was a major release for the HTML language. It was initially released in October 2014. It brought a wide variety of new functionality and smoother syntax to HTML. HTML4, the previous major standard, was released in April of 1998 and had only minor revisions during those 16 years. The current release is the HTML Living Standard.
Should You Open it in a new Tab? Probably Not
Use target="_blank" very, very sparingly. You should really only use it to prevent users from losing their place in a site or when they need to reference material while looking at the current page. It can annoy users if every link opens in a new tab when they have thirty-seven tabs open just for your site, and it also short-circuits the back button so that they can’t go back (they’re in a new window with no history, so there’s nothing to go back to in this window/tab).
Less HTML is Better
Use as little HTML code as possible to achieve your goals. The less code you write the easier it is to maintain and the faster it downloads to your visitor.
Lowercase Filenames Save You Headaches
Always use lowercase for filenames. While you don’t have to do this, Linux based servers treat uppercase letters and lower case letters as different. Meaning zombie.html and Zombie.html would be treated as completely different files. Windows servers ignore case. If you ever need to switch from windows to Linux (or you’re handing a site off to a client or similar) a lot of headaches and random errors where files can’t be found can be avoided if you just use lowercase consistently everywhere.
Same Company. Different Browser.
Browsers from the same company can look different on different platforms chrome for windows vs. chrome for OSX vs chrome for iOS vs chrome for android can all act differently (and this isn’t just because Chrome on iOS is a clone of Safari)
Easily Find Images Missing Alternative Text
Use an attribute selector to find images without alternative text.
[alt=""] {
outline: 5px solid blue;
}Code language: CSS (css)When in doubt, Flexbox
Flexbox is by far the easiest and most flexible solution for quick layout issues. Floating, positioning and tables have a lot of draw backs in our responsive world and lack the complexity for any but the most rudimentary layouts. Grid is far more powerful than Flexbox and excels at placing items in specific places. But for anything simple like lining things up or simple reordering of items Flexbox can do it in a few lines of code without any complex mental calculations.
The Direct Descendant Combinator
Direct descendant selector combinator > prevents grandchildren from being selected for instance with this HTML
<div class="zombie">
<p><a href="https://example.zom">hello zombie</a></p>
<a href="https://example2.zom">goodbye zombie</a>
</div>Code language: HTML, XML (xml)The following CSS will only select the “goodbye zombie” link
.zombie > a { color: red; }Code language: CSS (css)People Skills are as Important as Tech Skills
While working on and improving your technical and design skills is important, it’s also important to work on your people skills, particularly if you would say you’re not good with people. Avoiding it lets it stagnate and makes it harder than ever for you to get along with and benefit from the relationships that website-work (and all work, really) requires.
You’ve Got a Blind Spot Where Your Site’s Concerned
No matter who you are or how good you are at building websites You cannot judge whether your own website is usable. You have too much knowledge of how it works. You cannot come to the site with the eyes of someone who’s never seen it before.
Well Formed Code Works in All Browsers
Validate your work. Just because the browser you’re testing your code with works doesn’t mean it’ll work in every browser always. W3C offers both an HTML Validator and a CSS Validator
Block and Inline Elements
A block level element should not go inside an inline level/phrase element. There are exceptions, but generally a block level element can contain either block or inline elements, but an inline element can only hold other inline elements. The major exception is the a tag, that, since HTML5, is an inline element that is allowed to contain block elements
Choose Your Characters Carefully
When using any content management system (CMS) be careful with apostrophes. While most fields should handle them properly every once in a while you might find a field that breaks when you use an apostrophe. This is most likely because the content management system isn’t properly processing the content. Most CMSs use strings to pull in whatever you typed in the field. In computer languages though an apostrophe or single quote often signals the end of a string. The CMS is reading in the apostrophe as the closing apostrophe of the content and will then try to execute the remaining content as code. Often this just results in an error, but it can also be a source of attack if the field is public facing. A savvy person could add code after the apostrophe and access things they shouldn’t.
Turning the Current Color
Before CSS Custom Properties, CSS had a variable of sorts called currentColor that can still be used today. It corresponds to the current element or its parent’s foreground color. This becomes handy when you want to set border or drop shadow colors on the current element or even more useful when you can set the color on a parent and have it cascade through the children. It’s also a way to reduce duplicate code. You can set the colors for a class so that they cascade through, then use an id or additional class on that element to set the text color and watch different colors cascade through with a minimal amount of additional code.
Reset Your CSS for Better Compatibility
A CSS reset is a group of CSS rules that try to remove and/or reduce the differences between browsers. Each browser has its own default margin and padding etc. The reset attempts to make all those default settings consistent across browsers. There are many CSS Resets available, but I like normalize.css https://necolas.github.io/normalize.css/
Em Units are Your Friend
Use ems for (almost) everything. Em is a proportional unit that begins as equal to the default font size. If the user ups (or lowers) their font size, ems will scale up or down accordingly. This makes them great for margin and padding as well as for your breakpoints in Responsive Design. About the only thing you wouldn’t want to use them for is widths of elements. Use percentages for those so that they can properly respond to different screen sizes.
Changing the Look and Feel of Selected Text
You can change the look of a selection with the ::selection pseudo element. For instance,
::selection {
background-color: pink;
}Code language: CSS (css)changes the background color of the selection to pink. There are limits on what changes you can make using the selection pseudo element though, you can only change: color, background-color, text-decoration and text-shadow every other vendor-neutral property will be ignored.
Undercommunicate at Your Peril
When implementing someone else’s design. It’s often best to over communicate so that you both are happy with the results. You know what happens when you assume? You make zombies out of people and the apocalypse gets worse. Thanks for that… razzafrackin’ assumer… *grumble* *grumble*
Don’t Forget the Semi-colon
Always add a semi-colon whether it’s the end of a css declaration or a JavaScript line. While it may not technically be needed in every location, having it ensures that when you add something after it, that thing will always work. The time you save not having to debug why something’s not working is far greater than the time it takes to add a semi-colon. Let a minifier worry about removing stuff that isn’t necessary.
Open Details by Default
Add an “open” attribute (it does not need a value) to make a details element open by default.
<details open>
<summary>Zombie Hunting Season</summary>
Open by default!
</details>Code language: HTML, XML (xml)Normal Flow vs. Flexbox/Grid
When normal flow gives you the layout you want use it. If most of a section you’re laying out follows normal flow let it. Wrap the section you need a different layout for in a div and use Flexbox or grid just on that section. There’s no need to fight with Flexbox or grid to get back to a normal flow. Flexbox and grid can be used surgically to change layout where you want it changed. And they can be used in combination.