Toggling between greyscale and colour is nice, but often you want the colour to be visible by default, and greying something out when you hover over it incorrectly gives the impression something is disabled. It’s the opposite you want. In these circumstances, when there’s a collection of items, I find that it’s a nice effect to show the collection in colour to begin with, and when you hover over an item, the other items get slightly greyed out.
A good hover style reminds me of how fast and responsive our computers can be, if we let them. For example, I add a thicker underline when you hover over a link on this site, and it appears/disappears almost instantly as I move my cursor around. It feels snappy; it makes me smile.
Sigh. We managed to raise a generation for which an instant interaction on a 1000+MHz multi-core gpu-accelerated 1000+MB/s io system feels snappy and that’s special. Good job, goob job.
you could add a negative margin to offset the border, or an always-on transparent border that only changes colour when you hover – but those can interfere with other CSS rules
The worst part of CSS is its globalness. You can’t have two paddings sourced from different subsystems, can’t name a border so you could address it specifically (e.g. as in el:border(myhover) {background: <gradient>}). CSS is so poor and antipattern and nobody bats an eye. You write an article like this and already see all these fragile hacks advices coming in, normalized by years of stockholming through even most basic layouts.
As someone who experienced the rise of JavaScript, CSS and modern frontend frameworks, your comment gives me a chuckle because I'm pretty sure using JavaScript for hover effects pre-dates the ability to do that reliably using CSS.
I remember using Flash for hover effects. People complain we are in a cycle reinventing the wheel but I rather like the current wheel over the old one.
More like progress is figuring out the common patterns and offering shortcuts for them. The querySelector api for example was born from jquery's popularity.
Really? I always thought jQuery was just a shorthand for it cause it’s too long to type. And they really walked the DOM to look for an element? What an ugly runtime it was, ugh.
I don’t see anything bad here, tbh (ignoring my acute allergy to react—alikes). The problem is not how they write. DX is a good thing. Interactivity too. The problem is what happens at runtime: fetch html, fetch script, fetch data multiple times. It should be fetch html which contains a script which contains all the necessary data and creates elements and sets handlers.
It's ironic because I'm sure this lament has been voiced in one way or another with every generation of developers.
Anyway, your comment feels like a straw man; I don't know anyone who actually believes what you're claiming, nor is this sentiment anywhere on HN. The closest things are discussions about whether your website should work with JS disabled whenever a too-clever website is linked.
Nah they're right. There's developers, in major corporations right now, who literally have no idea that you can just put HTML in a container and who are so drunk on node.js that they LITERALLY DO NOT UNDERSTAND what something like nginx, traefik, or Caddy is for.
I can't really knock it when no one is ever going to ask them to do anything else. HTML might as well be assembly. It's starting to feel pretty vestigial at this point, it's all just different colored divs and aria labels. Elements on the screen as a human would perceive them stopped mapping to single elements ages ago.
For some "systems developers" this is literally how they create a program:
This is good argument, but also it's apples to oranges. You list GTK/Unity/informs where, I suppose, you refer to their GUI editors that output xml etc, and code just ties everything up, but you can drive all three with code only, and again end up placing every component by hand. Replace your prntln with " ImGui::Text("hello, world");" and you have GUI window on the screen.
But global-ness is what you want from design directives. You want all your buttons to look the same, your links consistent. You want to define your base fonts once and then not have to worry about it for the rest of the build. You want to have your vertical rhythm (line spacing) repeated on most pages. You want most pages to have the same background and foreground colours. CSS syntax gives you all that for free.
Giving multiple elements the same border definitions is easy:
When I look at the hoops you have to leap through to get the same behaviour using any of the frameworks, my mind reels. Build steps, runtime libraries, repeated syntaxes in the mark-up...
I accept that managing things like the shared border example can get fiddly. SASS made it easier; some flavour of react-plus-css-helper-library thing can make it easier, kinda, if you squint. But it's actually _very_ simple to write the basic core idea in plain CSS. Personally, I feel that the discipline required to manage larger CSS codebases isn't that different than the discipline required to write good JS or TS; we just have a habit of pretending we shouldn't need to do that and wishing someone else would (via a library, or changing the standards). I don't know why we're happy doing it in JS or TS, but not CSS.
Or as COMEFROM. The proper way for modularity is to import subtrees of declarations and have them applied explicitly.
// elem.css
elem {
use border-bg from “./bbg.css”;
}
// html
<div>
import elem from “./elem.css”
<elem/> // has it
</div>
<elem/> // doesn’t
I don’t want aspect-oriented/comefrom globalness. It is an antipattern and dead tech in which you have to runtime-debug an element to learn its properties in each case, cause there’s no single place to treewalk your logic from.
Your example is solving a different problem from mine. We can’t compare.
I was arguing that global declarations are useful. Your example is intentionally differentiatiating similar elements, and placing the specialisation inline with the DOM declaration.
So far these seem more like style preferences. I can’t infer the “anti-patterns” you’re concerned about, nor how your version solves them. Could you expand some?
Personally, I much prefer keeping the layout and style code out of my JS/behavior code. It makes both easier to read.
Ok, I see. I'm still not sold. Static analysis can't prove it looks right, so you need to runtime check it anyway. By that point, you may as well runtime debug.
Lisp (and I think SmallTalk) give us a rich history of developing against the runtime. I don't see why we should avoid it in the browser. The dev tools are very good, and have been fairly good since the '00s.
In my current team, we type check our CSS-in-JS (CSS-in-TS I suppose). It doesn't add much value. It can't tell you if the style rules are compatible with each other, if they'll conflict, if the cascade will force an effect you didn't intend the current snippet to produce. I am sure you're going to tell me that CSS is bad because it allows that kind of problem... but that's how visual design works! Every element contributes to the whole. Designers work from the outside in, and also from the inside out, rebalancing and refactoring as they go. CSS is a fairly good analog of that.
> Outline is a line outside of the element's border. Unlike other areas of the box, outlines don't take up space, so they don't affect the layout of the document in any way.
If you s/border/outline in the dev console on the image you get what you want.
It's already been mentioned that instead of box-shadow perhaps outline is a better choice for the image frame.
For the icons, I don't understand why the author believes that they need to have two copies of the icon inside the SVG. You can style every property of every element using CSS. If your icon is a single path element, it should remain a path element and be styled something like this:
The social icons are neat, but using filter would be shorter than manually setting normal and hover styles, at the cost of having inconsistent gray colors:
Toggling between greyscale and colour is nice, but often you want the colour to be visible by default, and greying something out when you hover over it incorrectly gives the impression something is disabled. It’s the opposite you want. In these circumstances, when there’s a collection of items, I find that it’s a nice effect to show the collection in colour to begin with, and when you hover over an item, the other items get slightly greyed out.
A good hover style reminds me of how fast and responsive our computers can be, if we let them. For example, I add a thicker underline when you hover over a link on this site, and it appears/disappears almost instantly as I move my cursor around. It feels snappy; it makes me smile.
Sigh. We managed to raise a generation for which an instant interaction on a 1000+MHz multi-core gpu-accelerated 1000+MB/s io system feels snappy and that’s special. Good job, goob job.
you could add a negative margin to offset the border, or an always-on transparent border that only changes colour when you hover – but those can interfere with other CSS rules
The worst part of CSS is its globalness. You can’t have two paddings sourced from different subsystems, can’t name a border so you could address it specifically (e.g. as in el:border(myhover) {background: <gradient>}). CSS is so poor and antipattern and nobody bats an eye. You write an article like this and already see all these fragile hacks advices coming in, normalized by years of stockholming through even most basic layouts.
We managed to raise a generation who think it's acceptable for JavaScript to be required in order to render a single page.
For some "web developers", this is literally how they create a page:
As someone who experienced the rise of JavaScript, CSS and modern frontend frameworks, your comment gives me a chuckle because I'm pretty sure using JavaScript for hover effects pre-dates the ability to do that reliably using CSS.
Yes, but it was called DHTML back then!
Added: And it was not a deliberate choice but kind of a necessity.
I remember using Flash for hover effects. People complain we are in a cycle reinventing the wheel but I rather like the current wheel over the old one.
Isn't this just pointing out that progress = functional -> declarative?
More like progress is figuring out the common patterns and offering shortcuts for them. The querySelector api for example was born from jquery's popularity.
And it makes sense for those shortcuts, in general, to migrate 'up' the stack, JS -> CSS, JS+CSS -> HTML.
Really? I always thought jQuery was just a shorthand for it cause it’s too long to type. And they really walked the DOM to look for an element? What an ugly runtime it was, ugh.
https://stackoverflow.com/questions/39979816/how-was-jquery-...
I don’t see anything bad here, tbh (ignoring my acute allergy to react—alikes). The problem is not how they write. DX is a good thing. Interactivity too. The problem is what happens at runtime: fetch html, fetch script, fetch data multiple times. It should be fetch html which contains a script which contains all the necessary data and creates elements and sets handlers.
It's ironic because I'm sure this lament has been voiced in one way or another with every generation of developers.
Anyway, your comment feels like a straw man; I don't know anyone who actually believes what you're claiming, nor is this sentiment anywhere on HN. The closest things are discussions about whether your website should work with JS disabled whenever a too-clever website is linked.
Having worked in enterprise web development...
Nah they're right. There's developers, in major corporations right now, who literally have no idea that you can just put HTML in a container and who are so drunk on node.js that they LITERALLY DO NOT UNDERSTAND what something like nginx, traefik, or Caddy is for.
These people are building healthcare systems.
"The future is now, old man!"
I can't really knock it when no one is ever going to ask them to do anything else. HTML might as well be assembly. It's starting to feel pretty vestigial at this point, it's all just different colored divs and aria labels. Elements on the screen as a human would perceive them stopped mapping to single elements ages ago.
For some "systems developers" this is literally how they create a program:
GTK/Unity/WinForms, everyone has their working level of abstraction.This is good argument, but also it's apples to oranges. You list GTK/Unity/informs where, I suppose, you refer to their GUI editors that output xml etc, and code just ties everything up, but you can drive all three with code only, and again end up placing every component by hand. Replace your prntln with " ImGui::Text("hello, world");" and you have GUI window on the screen.
> The worst part of CSS is its globalness.
But global-ness is what you want from design directives. You want all your buttons to look the same, your links consistent. You want to define your base fonts once and then not have to worry about it for the rest of the build. You want to have your vertical rhythm (line spacing) repeated on most pages. You want most pages to have the same background and foreground colours. CSS syntax gives you all that for free.
Giving multiple elements the same border definitions is easy:
When I look at the hoops you have to leap through to get the same behaviour using any of the frameworks, my mind reels. Build steps, runtime libraries, repeated syntaxes in the mark-up...I accept that managing things like the shared border example can get fiddly. SASS made it easier; some flavour of react-plus-css-helper-library thing can make it easier, kinda, if you squint. But it's actually _very_ simple to write the basic core idea in plain CSS. Personally, I feel that the discipline required to manage larger CSS codebases isn't that different than the discipline required to write good JS or TS; we just have a habit of pretending we shouldn't need to do that and wishing someone else would (via a library, or changing the standards). I don't know why we're happy doing it in JS or TS, but not CSS.
That’s as easy as
Or as COMEFROM. The proper way for modularity is to import subtrees of declarations and have them applied explicitly. I don’t want aspect-oriented/comefrom globalness. It is an antipattern and dead tech in which you have to runtime-debug an element to learn its properties in each case, cause there’s no single place to treewalk your logic from.Your example is solving a different problem from mine. We can’t compare.
I was arguing that global declarations are useful. Your example is intentionally differentiatiating similar elements, and placing the specialisation inline with the DOM declaration.
So far these seem more like style preferences. I can’t infer the “anti-patterns” you’re concerned about, nor how your version solves them. Could you expand some?
Personally, I much prefer keeping the layout and style code out of my JS/behavior code. It makes both easier to read.
A line of code somewhere affects an element. That’s aspect.
A line of code affects an element if written locally. That’s lexical scoping.
You can only runtime-check with aspect. You can statically infer with lexical scoping, cause all effects are specified in that scope.
My second example is solving the same problem, adding a common border and background to an element declaration.
My first example is solving the same problem too, adding a common behavior to a set of functions.
Ok, I see. I'm still not sold. Static analysis can't prove it looks right, so you need to runtime check it anyway. By that point, you may as well runtime debug.
Lisp (and I think SmallTalk) give us a rich history of developing against the runtime. I don't see why we should avoid it in the browser. The dev tools are very good, and have been fairly good since the '00s.
In my current team, we type check our CSS-in-JS (CSS-in-TS I suppose). It doesn't add much value. It can't tell you if the style rules are compatible with each other, if they'll conflict, if the cascade will force an effect you didn't intend the current snippet to produce. I am sure you're going to tell me that CSS is bad because it allows that kind of problem... but that's how visual design works! Every element contributes to the whole. Designers work from the outside in, and also from the inside out, rebalancing and refactoring as they go. CSS is a fairly good analog of that.
Aren't you describing https://developer.mozilla.org/en-US/docs/Web/CSS/outline?
> Outline is a line outside of the element's border. Unlike other areas of the box, outlines don't take up space, so they don't affect the layout of the document in any way.
If you s/border/outline in the dev console on the image you get what you want.
It's already been mentioned that instead of box-shadow perhaps outline is a better choice for the image frame.
For the icons, I don't understand why the author believes that they need to have two copies of the icon inside the SVG. You can style every property of every element using CSS. If your icon is a single path element, it should remain a path element and be styled something like this:
Of course it's possible that I'm missing something, but if all you want is changing color on hover, duplicating the item and using a mask is overkill.The social icons are neat, but using filter would be shorter than manually setting normal and hover styles, at the cost of having inconsistent gray colors:
Use outline instead:
Nearly identical to border, but without affecting layout at all.That’s why do you use `border-color: transparent` instead
Always nice to see CSS on here, but we figured this out 15yrs ago. Are the kids rediscovering hover styles?
I really miss hover effects on mobile, wish there was a way for this !
like so