elm-css
elm-css copied to clipboard
No hash collision handling
So, if I read the following right, in the rare occurance that you get a hash collision (two different pieces of text giving the same hash) the behaviour of elm-css would be... wonky? Might be worth adding a counter to every classname, just in case.
https://github.com/rtfeldman/elm-css/blob/1026935356eaecee09c1fd14e4da90df3532f08a/src/Html/Styled/Internal.elm#L59
A counter? Can you clarify what you mean by that? 🤔
Well. .hashString
could, in theory, result in the same hash for { display: inline-block; }
and { display: block; }
(probably not, but two different pieces of text could result in the same hash). Adding a counter to the end of classnames, like s0m3hash01
and s0m3hash02
would avoid this in the cases where it is an issue.
Of course, me being me, I forgot this is Elm and so it's not as straight forward as I made it sound due to pureness.
A reasonable alternative to a counter that I've used for problems like this in the past is to add the length of the original string. Not perfect but considerably less likely to collide. You can take it further by doing something like a product of {count of certain letters in the string}
The main problem I see with the counter approach is duplication.
Suppose I write this:
viewListItem item =
li [ css [ backgroundColor aliceblue ] ] [ text item.caption ]
view model =
ul [] (List.map viewListItem model.items)
With the counter approach, I'm now getting N redundant class definitions outputted to my <style>
and I'm probably not realizing it. That would be a nasty perf surprise I think.
The length approach doesn't have that problem, of course.
I'm curious about doing something like what Atomic CSS does - that is, using shorthand string concatenation instead of hashing, e.g.
button
[ css [ backgroundColor (hex "f00"), color (rgb 250 250 12), padding (px 20) ] ]
[ text "Hi!" ]
would compile to:
<button class="Bgc(#f00)C(rgb(250_250_12)P(20px)">Hi!</button>
Besides removing the possibility for collisions, one upside of this approach would be that this would presumably run faster than computing a hash would.
One downside would be that when doing server-side rendering, this would generate significantly larger classnames for the browser to download and parse.
I can think of a few more negatives.
- Longer class names clutters the browsers html debug view (minor inconvenience, admittedly )
- Code size for the final
.js
file would increase (I'm assuming this would take a relative largecase...of
statement to translate into shorthand strings).
I think @eeue56 suggestion is a good one. Appending the length of the CSS string, that is.
Adding the length of a string is basically adding a very weak second hash algorithm. Isn't this the same as concatenating two hash algorithm results or using one but with longer result values?
It's a essentially a very weak salt. It's probably worth doing some maths to see how helpful it is for sure.