Hacker News new | past | comments | ask | show | jobs | submit login
Defensive CSS (defensivecss.dev)
377 points by jacobr on July 6, 2022 | hide | past | favorite | 70 comments



Ok, the first thing I looked at is "long content" https://defensivecss.dev/tip/long-content/ and here they recommend to just clip it. Because who cares about content right? Who cares if the partial content you display is useless, as long as it looks good. And that's the kind of tip everyone here is applauding. I would like to say webdesign is in a sorry state nowawadays, except it was also that way 20 years ago. Maybe this "who cares about the content" attitude is inherent to web designers? Sorry if I sound blasé or cynical, but one gets tired after long enough of this.


But that's only one of the tips, the rest of the tips are about adapting to arbitrary screen size and content without visually breaking?

Sometimes you just have to clip user-generated content, though, because you can't tell the user to "make sure the label succinct enough to fit in this menu." The user will do as they please, and the layout must adapt or break. What alternative is there?

Sure, you could limit the length of the user-generated label ahead of time. But that'll only work for one combination of font-face and root font-size. The user-agent can override the font-face and the root font-size, potentially causing your layout to break. So, once again, you're left with two options: clip the text, or let your layout break (text wrapping where it shouldn't, overflowing text, etc). At least with `text-overflow: ellipsis` if the user-generated label _doesn't_ overflow, it doesn't get clipped.


Clipping shouldn't be done at the design level.

This is an application logic concern.

If the application did not impose a character limit, or imposed a large one, the design must accommodate this freedom.


But what about user-agents that override font-face and font-size? Those are important accessibility features for people with poor vision or dyslexia.

Without knowing the rendered width of the text string, you can't limit the text ahead of time. Or are you saying that all designs that can't accommodate text-wrapping should be avoided?


If the user has large text because they can’t read easily, how is clipping it short going to help them read it?


Usually when the layout breaks, functionality is lost: buttons can't be clicked on, text can't be read, content is obscured to the right, etc. If none of these things are happening, I'd agree not clipping is fine.


Do you have any data to back up that "usually"? IME more often than not the only reason why content is clipped is because of looks not because of functionality. This also applies to the example in the article.

The HTML default is to flow elements to make space for larger conent. You need to go out of your way to break that.


Or using a page translation service.


A data point may be used in several places in your UI. Why should it be clipped at the application level, if the same string is shown in a headline or list abbreviated and in another place in full?


This is the kind of stuff that gets boiled out of your blood after one day of practical front-end dev work.. Either that or you dedicate the rest of your life to creating a framework to ensure that your, infrequently updated and even less frequently visited, blog to aligns to a vertical grid.


One uncommon place where clipping is justified at the design level: lazy-loading of finite but known-size lists, with a real and correct scrollbar. I’ll use Fastmail’s webmail (on which I worked a few years back) as an example. I could load a list of a hundred thousand emails, and each message in the list is, under my configuration, 88px tall (containing four lines of text—approximately, sender and date, subject, and two lines of preview, with truncation on each), so the list container is made to be 8,800,000 pixels high¹, and I can use its scrollbar to immediately jump to any place, and it will figure out which messages to fetch and render based on the scroll position.

If the subject line were wrapped, which would be nice at times, you’d lose this ability: you’d have to guess the approximate height of each element, and your scroll positions will be imprecise and you’ll have to make messy adjustments from time to time. Overall it generally won’t be too bad so long as there’s not too much variation in them, but it’s definitely still inferior.

You can then read the full subject line and other truncated fields either by opening the email, or by hovering, as the full text is set as the tooltip. And here’s a general tip for others: if you do ever automatically truncate overflowing text, you should set the element’s tooltip to the full text.

—⁂—

¹ Browser do have limits on how large you can make containers, and handle excess in different ways. IE had the lowest threshold of failure at around ten million pixels, beyond which point it would ignore values; the workaround I implemented in https://github.com/fastmail/overture/commit/8d01c74d8c5d4ae0... came as a direct result of a customer reporting that scrolling was broken in IE in their mailbox with a couple of hundred thousand emails. Firefox breaks a little after 2²⁴ pixels, also ignoring values, so it’s still covered in https://github.com/fastmail/overture/blob/0c9828a5b77ad14383... (note the IE stuff is gone because IE is dead! :-) ). WebKit-heritage browsers accept larger values, but clamp them to about 2²⁵ pixels. In all cases, the clamping solution means you can’t access the emails at the end of the list. C’est la vie.


It doesn’t strike me as a problem in a simple list widget as shown in the article. Presumably you can click on the list item to see the person’s full name. That’s just an example of “click or scroll here to see more of this content” which is literally an unavoidable design pattern on any given display.


Not a designer, but here's my take:

Clipping is a good approach to maintaining the interface widget. However, the content still needs to be exposed somehow, such as with a tooltip on hover. Similar to how all "3 days ago" "dates" should show the actual date/time when hovered.

The default interface should be clean and easy, not cluttered, with a more detailed level available on request.


I used to say there are two kinds of UI designers: the ones who care about the interface, and the ones who care about the user.

Then we renamed it UX, trying to make both words about the user, and while I have spent less time navigating the post-rename world than I did the pre-rename world, my understanding of both human nature and the tech news cycle tells me that basically nothing changed.

Just like calling it Software Engineering didn't stop people from YOLOing spaghetti code and gambling on musical chairs or an air of obliviousness to get them out of the blast radius.


For me the 'more' button doesn't work properly so that's a bummer.

But breaking designs with too much text can really lower the perceived quality and the readability and navigation. Often you would use a technique like that to preserve a 2d aligned grid/table/cell/matrix/cards like design, where the overall structure is really more about seeing things in context and in relation to each other. Having uniform spacing really helps there. If you break the 2d alignment the overall structure becomes wiggly and distracting.


What a odd one to single out and complain about it.


Seems very reasonable to me. The advice is very dubious, but presented as absolute truth with no nuance. That’s bad, and, applying it more generally, if there’s one thing from the first row of tips that’s bad, it’s unlikely to be the only one.

This sort of thing reduces confidence. I can also say from looking through a number of others that they often lack nuance, and present a solution to a possible problem, without contemplating why that problem arose, and whether the solution is actually the right solution. (e.g. image distortion and background repeat are both a bit weird when you think about them, and the solutions offered are blunt and often not very good with no suggestion on how they could be improved. And flexbox wrapping basically assumes that horizontal scrolling is bad and needs to be fixed, which it isn’t always, but somehow also misattributes the scrolling in the diagram, making it seem as though it’s the flex container that’s scrolling, when in fact it’s just overflowing and causing its parent scroll area, probably the document scroll area, to have a scrollbar, and that is more likely to be problematic if not managed deliberately; but it also completely neglects to mention the more likely problem with flex overflow, which is your items not triggering overflow, but instead being squished narrower than intended, and that is the thing that would actually be worth while describing the solution for—flex-basis and flex-shrink.)


"Not making content inaccessible" is one of most fundamental principles of front-end work. The famous "CSS is awesome" coffee mug shows the correct default when something is not working like expected: the content is still visible. Defensive CSS should be intended to fail gracefully, and clipping it doesn't do that. (i.e. when it breaks it'll look bad but the content should still be available.)

I read this bit and I feel like I'm taking crazy pills:

>In some scenarios, we might need to truncate a text that isn't important for the user, or doesn't affect the user experience.

If that's the case, then what is the text even for?

This is a text based medium, the text is the content, it's the reason the user is here, they're not here to admire the consistent vertical layout. The priorities are entirely backwards.


I disagree.

If I'm reading a list of names like in a contacts app (e.g the example), I find it much easier and a better experience to skim entries if they have equal height and spacing. Having the trailing characters of a long last name being replaced with ellipsis is completely worth it to get the speed of skimming the list.

If I actually need to interact with the person that has the long name I'm going to click their entry and get their full details anyway.


IMHO, I like the original better than the after too.

However, I did think this was a handy feature to point out, just probably not the best example.


Most of these are pure common sense if you are apt with CSS.

However, one problem mentioned here is vendor prefix grouping. I've never experienced this problem or seen a grouped prefix ignored by any browser. Autoprefixer doesn't even ungroup prefix rules. I even ran a grouped prefix through W3C validator and came away validated, though the article mentions it's not W3C compliant.


> Most of these are pure common sense if you are apt with CSS.

I see SO many designers/devs that absolutely do not think of these things. The minute the design is being used 'for real' it becomes messy real quick.


I ran in to this with ::-webkit-progress-bar and ::-webkit-progress-value. Also it turns out you can't animate them, so I had to put the animation on the progress element and manually inherit it on the tree of psuedoelements to get the animation I wanted working.


Input placeholder vendor prefixes had to be ungrouped last time I checked. Wouldn’t work when together is a couple browsers but I forget which.


Suggestion for the breadcrumb example on this page (and other examples like it): https://defensivecss.dev/tip/flexbox-wrapping/#breadcrumbs

Show the HTML and CSS for the example in plain text below the example - saves me from firing up the browser inspector tools, which aren't available if I'm browsing on my phone.


Previous discussion: https://news.ycombinator.com/item?id=29504784

Not the same exact link but same author. Looks like he turned his post into a full-blown site.


I will trust any CSS content from Ahmad Shadeed, I am continually impressed and I've been developing CSS my whole career.


Agreed. It's one of the few CSS related blogs I'm subscribed to via RSS.


His book Debugging CSS is highly recommended.


Seconded.


I figured I would share this CSS variable technique I learned here. Tying DOM events into becoming CSS variables can be very powerful.

https://dom-event-to-css-variable.glitch.me/

https://github.com/pseudosavant/dom-event-to-css-variable.js


Wow this is great. I could have really used some of these examples a few days ago.

CSS grid combined with media queries feels like cheating to me. Am I missing something big here, or is this all safe to use in 2022?


"Am I missing something big here, or is this all safe to use in 2022?"

CSS Grid has been safe for use for a few years now (if you're supporting modern browsers).

https://caniuse.com/mdn-css_properties_display_grid

The problem is that popular frameworks like Bootstrap and Bulma still don't support CSS Grid (they use flexbox only for layout).

It's ironic that developers have rightly complained how cumbersome CSS layout has been in the past. Now we have CSS Grid - and yet developers still aren't using it.


I think the "issue" is that CSS grid is already powerful and expressive enough so that you don't really need something like Bootstrap/Bulma to get in the way. They would simply rename stuff and be a useless middleman. I don't think even utility/functional CSS frameworks like Tailwind do much with CSS grid (not sure). It's that good.


This is my experience so far. Once I felt the total control over layouts at any size, I had zero fears about losing all the other benefits you get with css frameworks. I can figure out svg icons, modals, etc on my own. The #1 reason I used bootstrap up until now is to deal with complex layouts and breakpoints. Flexbox handles most other cases without much drama too.

I am currently running a 100% vanilla JS+CSS stack for a responsive web app. I have never felt this much power before. Everything is so immediate and obvious now.


CSS Grid is that amazing. I hadn't looked into it much for a while because I had already adopted flexbox, but grid is so much better for most scenarios I encounter.

CSS Grid + CSS Variables really take CSS to another level.


This is worth the price ;)

Aside from the Grid-centric lessons, the Grid v Flexbox is worth watching more than once.

https://cssgrid.io/


Media queries have been safe for over a decade. If you feel uneasy with grids and/or still want to support ancient Internet Explorer versions just use flexbox instead.


A good offence is the best defence, which is why I prefer offensive CSS.


That's a very !important statement right there.


Paraphrasing Ian Gillian from Deep Purple about stage monitor volume, "Make everything more !important than everything else."


As someone who is not very good at UX / frontend, and especially CSS, these kind of tips are very good.


This page needs one sentence at the top that explains what Defensive CSS is. “Future proof interfaces” is far too vague (or maybe I’m not smart!)

I went to the “Introduction To” article but it began reading like a cooking recipe story.

The page is otherwise very elegant.


It's crazy that there's so much extra cruft when it comes to crafting web interfaces when a CLI is most often the most powerful and easiest way to get a job done. Am I just taking crazy pills?


You’re not talking crazy pills, but the article is about CSS. That’s like saying, “I don’t understand why we have websites at all.” A very small subset of people know how to use a CLI. We’re talking about building visual interfaces for common consumption. Not tools only developers understand how to use :)


How do you write a CLI tool for viewing a photo album? Would Netflex be better suited as a CLI-only interface?


imv *jpg :)


Did you post this from a CLI?


The real crazy thing is that Delphi/VB got UIs right in the 90s and the JS folks keep reinventing everything.


I loved that era and it was great, but it didn’t handle resizing to fit different screen sizes well at all.

I’m still holding out for a similar interface builder that can handle responsive design.


Layout managers handle window resizing, which heavily overlap. Started using them in the 90s.


Did it, though? I don't think I've used a Delphi/VB-based application like... ever? I've made some myself back in the day and fiddled around with my friend's university assigments, but I can't think of any real world application using it. Maybe you have some examples?


What are examples of successful Delphi/VB UIs?


You know there may be a market out there for no code ui editors. At least for admin like uis. One that gets it right.


Reminds me of the classic CSS book (2005?) by Dan Cederholm: https://www.amazon.com/Bulletproof-Web-Design-flexibility-pr...


Really love the togglable examples. It's often hard to imagine how a change look and while in a perfect world I'd have time to make a mockup to test each version, well, it's hardly a perfect world so examples are appreciated!


the examples are certainly nice but it only takes a second to resize your browser when testing your own site


You don't even need to resize the whole browser window - you can use the responsive design mode of your browser's development tools to resize just the viewport of the website you are working on. And it can even emulate touch interfaces to test the relevant media queries.

And resizing the window is also something native application developers should embrace. Always roll my eyes when some game developer says they can only target 16:9 because they don't have other monitors - just make your window mode resizable and drag the corner.


Those negative examples don't work for me on Safari, I can't drag the frame small enough to trigger the bad examples - it seems not to allow it.

So tbh the content looks good for me in both bad and defensive cases


Hilariously they haven't always applied the defences they're promoting - in the "Scroll chaining" example the page will scroll if you over-scroll the example


I constantly struggle with CSS grids when compared to, say, just using Bootstrap. I know Bootstrap comes with a lot of baggage, but the syntactic sugar is just so useful.


I mentioned this above. But in case you don't see it.

https://cssgrid.io/


Thank you, that was really helpful.


Some really nice tips here.


CSS3 got approved in 2006 and now we are at the point where we have to treat the language like it's fighting against us. Quality work the consortium has done in the past 15 years, eh?


That’s not what the site is about at all.

It’s ”defensive” in the same sense as ”defensive programming”: handling possible future / edge cases gracefully.


the fact you can set a CSS version in your code, and have it not act as it did when that version was originally standardized, is exactly what being "defensive" is about. the code you wrote years ago doesn't work anymore because the browsers have decided to do things differently now.

and yet I can run applications from 30 years ago and it will still function as it once did. no hacks or code changes required.

you shouldn't have to "future proof" source code against an outside entity just coming in and breaking it all. especially when it's supposed to be an open standard.


Windows is full of hacks to allow that "I can run applications from 30 years ago" to happen.


I'm curious which css code from years ago won't work any more. Care to elaborate?


Not OP, but flexbox went very famously trough a few breaking changes throughout its early history: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexibl...

There were also some more subtle behavior changes a few years ago in the way webkit handled unprefixed flex-direction centering properties (align-items, justify-content) together with min-width/min-height attributes, switching from behaving closer to IE11 in this regard to basically emulating Blink. AFAIK neither behavior was really against-spec.

And if you really want to go all-in with some really deep philosophical questions, I can suggest you the following: Is it possible to center text in a select box? https://stackoverflow.com/questions/10813528/is-it-possible-...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: