Tag: Defense

In Defense of Tables and Floats in Modern Day Development

Twenty-plus years ago, tables were the main way web pages were created in HTML. It gave web builders consistent control of constructing pages with some “design.” No longer did sites only have to be top-to-bottom in a linear manner — they could be set up with columns that align left-to-right and top-to-bottom. Back then, it was seen as a huge breakthrough.

Tables, however, were never designed to lay out pages and, in fact, have all sorts of problems when used that way today. It was a convenient hack, but at the time, a very welcome one, particularly for those trying to achieve a super-specific layout that previous ways couldn’t handle.

Fast-forward to modern days and it’s now obvious that were tons of issues with the table layout approach. Accessibility is a big one.<table>, <th>, <tr> and <td> elements aren’t exactly accessible, especially when they’re nested several levels deep. Screen readers — the devices that read web content and serve as a measure of accessibility compliance — struggle to parse them into cohesive blocks of content. That’s not to say tables are bad; they simply were never intended as a layout mechanism.

Check out this table layout. Feel free to run it through VoiceOver or whatever screen reading software you have access to.

Yes, that example looks very much like a typical website layout, but it’s crafted solely with a table. You can see how quickly it becomes bloated and inaccessible the very moment we start using it for anything other than tabular data.

So after more than 20 years of being put through the ringer, you might think we should avoid tables altogether. If you’ve never shipped a table-based layout, you’ve undoubtedly heard war stories from those of us who have, and those stories are never kind. It’s like we’ve sort of made tables the “Internet Explorer of HTML elements.”

But that’s not totally fair because tables do indeed fill a purpose on the web and they are indeed accessible when they are used correctly.

Tables are designed to handle data that is semantically related and is best presented in a linear-like format. So, yes, we can use tables today in the year 2020, and that will likely continue to be true many years from now.

Here’s a table being used to display exactly what it’s intended to: tabular data!

With the push toward web standards in the early 2000s, tables were pushed aside as a layout solution in favor of other approaches, most notably the CSS float property. Designers and developers alike rejoiced because, for the first time, we had a true separation of concerns that let markup do the markup-y things it needs to do, and CSS to do the visual stuff it needs to do. That made code both cleaner and way easier to maintain and, as a result, we could actually focus on true standards, like accessibility, and even other practices, like SEO.

See (or rather hear) the difference in this example?

Many of us have worked with floats in the past. They were originally designed to allow content to flow around images that are floated either to the left or right, and still be in the document flow. Now that we’ve gotten newer layout features — again, like grid and flexbox — floats, too, have sort of fallen by the wayside, perhaps either because there are better ways to accomplish what they do, or because they also got the same bad rap as tables after being (ab)used for a long time.

But floats are still useful and relevant! In fact, we have to use them for the shape-outside property to work.

A legitimate float use case could be for wrapping content around a styled <blockquote>.

CSS features like grid, flexbox, and multicolumn layouts are among the wonderful tools we have to work with these days. With even more layout possibilities, cleaner and more accessible code, they will remain our go-to layout approaches for many years to come.

No hacks or extra code in this flexbox example of the same layout we’ve looked at throughout this article:

So, next time you find yourself considering tables or floats, reach for them with confidence! Well, when you know the situation aligns with their intended use. It’s not like I’m expecting you to walk away from this with a reinvigorated enthusiasm for tables and floats; only that, when used correctly, they are perfectly valid techniques, and even continue to be indispensable parts of our overall toolset.

The post In Defense of Tables and Floats in Modern Day Development appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.


, , , ,

In Defense of a Fussy Website

The other day I was doom-scrolling twitter, and I saw a delightful article titled “The Case for Fussy Breakfasts.” I love food and especially breakfast, and since the pandemic hit I’ve been using my breaks in between meetings (or sometimes on meetings, shh) to make a full bacon, poached egg, vegetable plate, so I really got into the article. This small joy of creating a bit of space for myself for the most important meal of the day has been meaningful to me — while everything else feels out of control, indulging in some ceremony has done a tiny part to offset the intensity of our collective situation.

It caused me to think of this “fussiness” as applied to other inconsequential joys. A walk. A bath. What about programming?

While we’re all laser-focused on shipping the newest feature with the hottest software and the best Lighthouse scores, I’ve been missing a bit of the joy on the web. Apps are currently conveying little care for UX, guidance, richness, and — well, for humans trying to communicate through a computer, we’re certainly bending a lot to… the computer.

I’m getting a little tired of the web being seen as a mere document reader, and though I do love me a healthy lighthouse score, some of these point matrixes seem to live and die more by our developer ego in this gamification than actually considering what we can do without incurring much weight. SVGs can be very small while still being impactful. Some effects are tiny bits of CSS. JS animations can be lazy-loaded. You can even dazzle with words, color, and layout if you’re willing to be a bit adventurous, no weight at all!

A few of my favorite developer sites lately have been Josh Comeau, Johnson Ogwuru and Cassie Evans. The small delights and touches, the little a-ha moments, make me STAY. I wander around the site, exploring, learning, feeling actually more connected to each of these humans rather than as if I’m glancing at a PDF of their resume. They flex their muscles, show me the pride they have in building things, and it intrigues me! These small bits are more than the fluff that many portray any “excess” as: they do the job that the web is intending. We are communicating using this tool- the computer- as an extension of ourselves.

Nuance can be challenging. It’s easy as programmers to get stuck in absolutes, and one of these of late has been that if you’re having any bit of fun, any bit of style, that must mean it’s “not useful.” Honestly, I’d make the case that the opposite is true. Emotions attach to the limbic system, making memories easier to recall. If your site is a flat bit of text, how will anyone remember it?

Don’t you want to build the site that teams in companies the world over remember and cite as an inspiration? I’ve been at four different companies where people have mentioned Stripe as a site they would aspire to be like. Stripe took chances. Stripe told stories. Stripe engaged the imagination of developers, spoke directly to us.

I’m sad acknowledging the irony that after thinking about how spot on Stripe was, most of those companies ignored much of what they learned while exploring it. Any creativity, risk, and intention was slowly, piece by piece, chipped away by the drumbeat of “usefulness,” missing the forest for the trees.

When a site is done with care and excitement you can tell. You feel it as you visit, the hum of intention. The craft, the cohesiveness, the attention to detail is obvious. And in turn, you meet them halfway. These are the sites with the low bounce rates, the best engagement metrics, the ones where they get questions like “can I contribute?” No gimmicks needed.

What if you don’t have the time? Of course, we all have to get things over the line. Perhaps a challenge: what small thing can you incorporate that someone might notice? Can you start with a single detail? I didn’t start with a poached egg in my breakfast, one day I made a goofy scrambled one. It went on from there. Can you challenge yourself to learn one small new technique? Can you outsource one graphic? Can you introduce a tiny easter egg? Say something just a little differently from the typical corporate lingo?

If something is meaningful to you, the audience you’ll gather will likely be the folks that find it meaningful, too.

The post In Defense of a Fussy Website appeared first on CSS-Tricks.


, ,

In Defense of the Ternary Statement

Some months ago I was on Hacker News (as one does) and I ran across a (now deleted) article about not using if statements. If you’re new to this idea (like I was), you’re in a for a real treat. Just search for “if statements” on Hacker News. You’ll get articles proposing that you might not need them, articles that refer to them as a code smell and even the quintessential “considered harmful.” Listen, you know a programming concept is legit when people start suggesting that using it is actually gonna hurt somebody.

And if that’s not enough for you, there is always the “Anti-If Campaign.” If you join, you get a nifty banner and your name on the website. IF you join. Oh the sweet, sweet irony.

The first time that I ran across this bizarre “if anathema” phenomenon, I thought it was interesting, but probably just more people mad on the internet. You are always one Google search away from finding someone who is mad about anything. Like this person who hates kittens. KITTENS.

Some time later, I was watching Linus Torvald’s TED interview. In that interview, he shows two slides. The first slide contains code that he deems is “bad taste.”

And the second is that same code, but in what Linus would consider, “good taste.”

I realize that Linus is a bit of a polarizing figure, and you might not agree with the “good taste” vs. “bad taste” phrasing. But I think we can universally agree that the second slide is just easier on the old eye balls. It’s concise, has fewer logical paths to follow, and contains no if statement. I want my code to look like that. It doesn’t have to be some genius algorithm (it never will be), but I think it can be clean, and remember what Billy Corgan of Smashing Pumpkins said about cleanliness…

Cleanliness is godliness. And god is empty. Just like me.

– Billy Corgan, “Zero”

So dark! But what an amazing album.

Aside from making your code look cluttered, if statements, or “branching logic,” requires your brain to hold and evaluate two separate paths at one time along with all of the things that might occur on those paths. If you nest if statements, the problem intensifies because you are creating and tracking a decision tree and your brain has to bounce around all over that tree like a drunk monkey. This kind of thing is what makes code hard to read. And remember, you should write your code thinking of the moron who comes after you that is going to have to maintain it. And that moron is probably you.

As my own favorite moron, I’ve been making a conscious effort lately to avoid writing if statements in my JavaScript. I don’t always succeed, but what I’ve noticed is that at the very least, it forces me to think about solving the problem from an entirely different angle. It makes me a better developer because it compels me to engage a part of my brain that is otherwise sitting on a beanbag eating peanut M&M’s while the if statement does all the work.

In the process of not writing if statements, I’ve discovered my love for the way JavaScript lets you compose conditional logic with ternary statements and logical operators. What I would like to propose to you now is that ternary has gotten a bad rap, and you can use it along with the && and || operators to write some pretty concise and readable code.

The much maligned ternary

When I first started as a programmer, people used to say, “Never use a ternary. They are too complex.” So I didn’t use them. Ever. I never used a ternary. I never even bothered to question whether or not those people were right.

I don’t think they were.

Ternaries are just one-line if statements. Suggesting that they are implicitly too complicated in any form is just… not true. I mean, I’m not the frostiest donut in the box, but I have no problems at all understanding a simple ternary. Is it possible that we are infantilizing ourselves here just a tad when we say to always avoid them. I think that a well-structured ternary beats an if statement every time.

Let’s take a simple example. Say we have an application where we want to test and see if the user is logged in. If they are, we send them to their profile page. Otherwise, we send them to the home page. Here is the standard if statement to do that…

if (isLogggedIn) {   navigateTo('profile'); } else {   navigateTo('unauthorized'); }

That’s a damn simple operation to split out over six lines. SIX LINES. Remember that every time you move through a line of code, you have to remember the code that came above it and how it affects the code below it.

Now the ternary version…

isLoggedIn ? navigateTo('profile') : navigateTo('unauthorized');

Your brain only has to evaluate one line here, not six. You don’t have to move between lines, remembering what was on the line before.

One of the drawbacks to the ternary, though, is that you cannot evaluate for only one condition. Working from the previous example, if you wanted to navigate to the profile page if the user was logged in, but take no action at all if they weren’t, this won’t work…

// !! Doesn't Compile !! logggedIn ? navigateTo('profile')

You would have to write out an actual if statement here. Or would you?

There is a trick that you can use in JavaScript when you only want to evaluate one side of the condition and you don’t want to use an if statement. You do this by leveraging the way JavaScript works with the || (or) and && (and) operators.

loggedIn && navigateTo('profile');

How does that work!?

What we’re doing here is asking JavaScript, “Are both of these things true?” If the first item is false, there is no reason for the JavaScript virtual machine to execute the second. We already know that both of them aren’t true because one of them is false. We’re exploiting the fact that JavaScript won’t bother to evaluate the second item if the first one is false. This is the equivalent of saying, “If the first condition is true, execute the second.”

Now what if we wanted to flip this around? What if we wanted to navigate to the profile page only if the user is not logged in? You could just slap a ! in front of the loggedIn variable, but there is another way.

loggedIn || navigateTo('profile');

What this says is, “Are either of these things true?” If the first one is false, it has to evaluate the second to know for sure. If the first one is true though, it will never execute the second because it already knows that one of them is true; therefore the whole statement is true.

Now, is that better than just doing this?

if (!loggedIn) navigateTo('profile');

No. In that form, it is not. But here’s the thing: once you know that you can use the && and || operators to evaluate equality outside of if statements, you can use them to vastly simplify your code.

Here is a more complex example. Say we have a login function where we pass a user object. That object may be null, so we need to check local storage to see if the user has a saved session there. If they do, and they are an admin user, then we direct them to a dashboard. Otherwise, we send them to a page that tells them they are unauthorized. Here is what that looks like as a straight-up if statement.

function login(user) {   if (!user) {     user = getFromLocalStorage('user');   }   if (user) {     if (user.loggedIn && user.isAdmin) {       navigateTo('dashboard');     }     else {       navigateTo('unauthorized');     }   }   else {     navigateTo('unauthorized');   } }

Ouch. This is complicated because we’re doing a lot of null condition checking on the user object. I don’t want this post to be too strawman-y, so let’s simplify this down since there is a lot of redundant code here that we would likely refactor into other functions.

function checkUser(user) {   if (!user) {     user = getFromLocalStorage('user');   }   return user; }  function checkAdmin(user) {   if (user.isLoggedIn && user.isAdmin) {     navigateTo('dashboard');   }   else {     navigateTo('unauthorized');   } }  function login(user) {   if (checkUser(user)) {     checkAdmin(user);   }   else {     navigateTo('unauthorized');   } }

The main login function is simpler, but that’s actually more code and not necessarily “cleaner” when you consider the whole and not just the login function.

I would like to propose that we can do all of this in two lines if we forgo the if statements, embrace the ternary, and use logical operators to determine equality.

function login(user) {   user = user || getFromLocalStorage('user');   user && (user.loggedIn && user.isAdmin) ? navigateTo('dashboard') : navigateTo('unauthorized') }

That’s it. All of that noise generated by if statements collapses down into two lines. If the second line feels a bit long and unreadable to you, wrap it so that the conditions are on their own line.

function login(user) {   user = user || getFromLocalStorage("user");   user && (user.loggedIn && user.isAdmin)     ? navigateTo("dashboard")     : navigateTo("unauthorized"); }

If you are worried that maybe the next person won’t know about how the && and || operators work in JavaScript, add some comments, a little white space and a happy tree. Unleash your inner Bob Ross.

function login(user) {   // if the user is null, check local storage to   // see if there is a saved user object there   user = user || getFromLocalStorage("user");      // Make sure the user is not null, and is also   // both logged in and an admin. Otherwise, DENIED. &#x1f332;   user && (user.loggedIn && user.isAdmin)     ? navigateTo("dashboard")     : navigateTo("unauthorized"); }

Other things you can do

While we’re at it, here are some other tricks you can play with JavaScript conditionals.


One of my favorite tricks (which I used above), is a one-liner to check if an item is null and then reassign it if it is. You do this with an || operator.

user = user || getFromLocalStorage('user');

And you can go on forever like this…

user = user || getFromLocalStorage('user') || await getFromDatabase('user') || new User();

This also works with the ternary…

user = user ? getFromLocalStorage('user') : new User();

Multiple conditions

You can provide multiple conditions to a ternary. For instance, if we want to log that the user has logged in and then navigate, we can do that without needing to abstract all of that into another function. Wrap it in some parentheses and provide a comma.

isLoggedIn ? (log('Logged In'), navigateTo('dashboard')) : navigateTo('unauthorized');

This also works with your && and || operators…

isLoggedIn && (log('Logged In'), navigateTo('dashboard'));

Nesting ternary expressions

You can nest your ternary expressions. In his excellent article on the ternary, Eric Elliot demonstrates that with the following example…

const withTernary = ({   conditionA, conditionB }) => (   (!conditionA)     ? valueC     : (conditionB)     ? valueA     : valueB );

The most interesting thing Eric is doing there is negating the first condition so that you don’t end up with the question marks and colons together, which makes it harder to read. I would take this a step further and add a little indentation. I also added the curly braces and an explicit return because seeing one parenthesis and then immediately another makes my brain start to anticipate a function invocation that is never coming.

const withTernary = ({ conditionA, conditionB }) => {   return (     (!conditionA)       ? valueC         : (conditionB)         ? valueA         : valueB   ) }

As a general rule, I think that you should consider not nesting ternaries or if statements. Any of the above articles on Hacker News will shame you into the same conclusion. Although I’m not here to shame you, only to suggest that perhaps (and just maybe) you will thank yourself later if you don’t.

That’s my pitch on the misunderstood ternary and logical operators. I think that they help you write clean, readable code and avoid if statements entirely. Now if only we could get Linus Torvalds to sign off on all this as being “good taste.” I could retire early and and live the rest of my life in peace.

The post In Defense of the Ternary Statement appeared first on CSS-Tricks.


, ,

In Defense of Utility-First CSS

A rather full-throated argument (or rather, response to arguments against) utility (atomic) CSS from Sarah Dayan. I wondered recently if redesigns were potentially a weakness of these types of systems (an awful lot of tearing down classes) which Sarah acknowledges and recommends more abstraction to help.

I also wonder about workflow. I sort of demand working in an environment which offers style injection, so working with CSS feels smooth. I also worry that having to change HTML every time I want to modify a design requires refreshing. I guess if you are in a hot module reloading situation, then it’s fine.

Also this seems like it can just go too far. At some point, altering a space-separated string to do everything you wanna do has ergonomic limitations.

Direct Link to ArticlePermalink

The post In Defense of Utility-First CSS appeared first on CSS-Tricks.