Live data from Hacker News

CSS: The bad bits and how to avoid them

joeforshaw.com

91–100 of 109 posts

Re: CSS: The bad bits and how to avoid them

#91
Using CSS-in-JS to enforce component-local CSS (and also allow easy dynamic updating of styles, by making a “getStyles” type function) is the best thing to happen to styling for a long time in my opinion. Recently I’ve been using the “styled components” pattern (using the Emotion library) and despite being initially sceptical, have found it really nice to work with.

So much more logical to write and maintain than plain CSS for a site of any reasonable complexity. You can still apply global styles where they make sense (e.g. styling all body text) and making use of JavaScript patterns for reusing common chunks of styling feels much more robust than the CSS equivalent.

As someone who can do CSS but doesn’t do so that often, I can confirm that it’s getting better with things like Flexbox and Grid, but it is still full of maddening quirks! I do have a lot of respect for people who are CSS experts.

Re: CSS: The bad bits and how to avoid them

#92
For z-indexes, we're using a slightly an approach that I find a bit clearer:

  $some-element-z-index: 1 + max(
    $other-element-z-index,
    $should-be-below-z-index
  );
This way the relationship between elements that should be below or above is more explicit.

In my head, it works a bit like a spreadsheet. You update the z-index value of an element somewhere below, and all the z-indexes that depend on it update their value too.

Re: CSS: The bad bits and how to avoid them

#93
post #12

I tend to write CSS for projects by hand without a pre-processor, borrowing from previous projects only when called for. One of the things I've been doing recently that helps debugging a lot is to group the attributes within a css class into three, separated by a line. 1) Things that control where the item shows up. 2) Things that control the overall appearance of the item, like size and background. 3) Things that co…

That sounds a lot like the 'concentric order'. Can sort like that automatically: https://github.com/Siilwyn/css-declaration-sorter/blob/maste...

Re: CSS: The bad bits and how to avoid them

#94
post #8

Just wondering how much more complains and valid critique against css is still required to get real alternative. https://ishoudinireadyyet.com

I hope never enough, CSS is a fantastic language. Also, houdini won't replace CSS, it's actually the opening up of the CSS engine: https://developers.google.com/web/updates/2016/05/houdini

Safari is so bad.

Re: CSS: The bad bits and how to avoid them

#95

Using CSS-in-JS to enforce component-local CSS (and also allow easy dynamic updating of styles, by making a “getStyles” type function) is the best thing to happen to styling for a long time in my opinion. Recently I’ve been using the “styled components” pattern (using the Emotion library) and despite being initially sceptical, have found it really nice to work with. So much more logical to write and maintain than pla…

As someone just dipping my toes into some Preact, I’m still a but confused about the styled components pattern. If you already have, say, a menu component in an es6 class, with its own methods and helpers and render func - how do you convert that to a styled component. All of the examples I’ve found just spin up new buttons pre-wrapped in Styled, etc

That’s my only real sticking point here.

Re: CSS: The bad bits and how to avoid them

#96

Earlier quoted context omitted.

There is not a single time I had though to myself "This should have been an ID instead of a class"; but there are hundreds of times where I have though to myself "This should have been a class instead of an ID".

In terms of pure CSS it doesn't matter, but for JavaScript that manipulates the DOM (e.g. jQuery), it does. Specifically, `getElementById` is more than 50% faster than `getElementsByClassName`. https://jsperf.com/id-vs-class-hn/1

That micro benchmark is comparing getElementById which is a map lookup (assuming the id is unique in the document) vs getElementsByClassName which is creating an iterator that would scan the document as you loop over it, except that the page is not looping over it or calling .length, so it's not really scanning anything at all.

Essentially it's benchmarking a handful of branches inside getElementById that do the map lookup for an Element [1] against the handful of branches inside getElementsByClassName that do the map lookup for a NodeList [2]. They both look pretty similar to me in branch and map lookup count, so I'm not sure where the difference is, but it's not something that would impact real content since on a real page getElementsByClassName's cost is related to typical behavior being O(N) instead of O(1) like getElementById. Browsers have a ton of caching around it though, so getElementsByClassName can look like O(1) in micro benchmarks.

You could could alter the benchmark to do getElementsByClassName("my-class")[0] to test the scanning but browsers cache that too, so you'd need to actually modify the document between each run of the benchmark somehow (ex. adding or removing an element) to invalidate the cache.

Typical content that uses getElementById will be faster than content that uses getElementsByClassName, but it's hard to show that in a benchmark. :)

[1] https://cs.chromium.org/chromium/src/third_party/WebKit/Sour...

[2] https://cs.chromium.org/chromium/src/third_party/WebKit/Sour...

Re: CSS: The bad bits and how to avoid them

#97

I have been writing a lot of CSS (well SCSS) lately and this seems like a good time as any (though I admit somewhat off topic) about a question I have regarding the newer Combination & Multiple selectors https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduct... and Attribute Selectors https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduct... This stems from the fact that I have inherited the task of re-wr…

Generally you would want to avoid descendant and child selectors. With rules like ul > li > a .selector .selector1 li a The system will check ALL anchor tags and move left until it has completely matched the rule. This makes the above selectors extremely expensive (perfomance-wise) and can cause slow page-loads. Tag selectors and universal selectors are generally a bad idea for this same reason. And using inheritance…

The good news is all modern browsers use a Bloom Filter to quickly skip over elements that wouldn't match the descendant or child selector relationship.

You could probably construct situations with very deep selector relationships and thousands of matching elements where the ancestor walking adds up but the other costs of computing style often end up being more important than the selector matching in many scenarios. Not that you shouldn't aim for simpler selectors of course.

(Usually the problems with expensive selectors come from side effects of dynamic changes to the document. ex. Some selectors will make the browser recompute hundreds of elements when only changing something small because the browser isn't tracking that relationship in a precise way.)

Re: CSS: The bad bits and how to avoid them

#98
post #13
post #6

There's nothing wrong with styling on an id. You could put the style right in the HTML tag, or on the page where it's used, but with dynamic pages (and static stylesheets) both options will cost you bandwidth. And they split up your styles into separate places. So putting the style on the id is the right thing to do, and I don't understand why the author is against it. If I need my footer to look a certain way, then…

Sure, the author is describing good practice, not best practice. If you have a choice, use class, then if you need to modify a specific use of the class, use id. I would still use .footer instead of #footer. Of course you should consider as well.

You can have many classes!!

  


  .footer.special.enterprise {
    background-color: blue;
  }

Re: CSS: The bad bits and how to avoid them

#99
post #6

There's nothing wrong with styling on an id. You could put the style right in the HTML tag, or on the page where it's used, but with dynamic pages (and static stylesheets) both options will cost you bandwidth. And they split up your styles into separate places. So putting the style on the id is the right thing to do, and I don't understand why the author is against it. If I need my footer to look a certain way, then…

In the classic days of web dev it was best practice (and still is in my opinion) to separate style (CSS) from functionality (JavaScript). So you had classes for CSS and id's for JS. So if you change the id you don't have to update your CSS. If you have a "singleton" it's better to use the element's name instead of id in the CSS. for example body instead of #body for the same reason (separate from JS). And if you want to have different types of body, add a class to the special body. id's will for example create global JS variables, so if you are styling using #id you will create a bunch of unnecessary global JS variables.

Re: CSS: The bad bits and how to avoid them

#100
post #74

I'd add one thing: avoid multiple classes on a single element; use mixins to avoid duplication. I tend to do so even for classes that have some toggle state, i.e. .some-class-active.

does this have a performance benefit or are you recommending it for the code clarity?

It'll increase your parse and network transfer time (gzip might help there though) in exchange for reduced selector matching and style computation time. How much that matters probably depends on your content, how big the document is, how much CSS you have and how many classes you're using.

If you're talking about the difference of:

.a { ... } .b { ... } .ab { ... }

It's probably not going to matter a lot. It's two map lookups vs one, and some associated overhead. Probably better to optimize elsewhere. :)

Post reply on HN