LeaVerou / css-almanac

Repo for planning & voting on which stats to study
https://projects.verou.me/mavoice/?repo=leaverou/css-almanac&labels=proposed%20stat
34 stars 3 forks source link

<length> stats #11

Open LeaVerou opened 4 years ago

LeaVerou commented 4 years ago

When it comes to CSS units usage, I'd love to see some numbers on unitless 0 values, e.g. 0 vs 0px/em/rem/ numbers comparison.

(by @catalinred)

LeaVerou commented 4 years ago

I suppose we can look for /(?<![\d.-])0(%|cm|mm|Q|in|pc|pt|px|ex|ch|r?em|lh|vw|vh|vmin|vmax)?\b/ in values, potentially after removing url() calls for better accuracy. It's a bit naïve, but I can't think of obvious (common) failure cases, can someone else?

LeaVerou commented 4 years ago

The JS I just pushed calculates:

Sample output (from the Smashing Magazine CSS):

{
    "0": 834,
    "byProperty": {
        "line-height": {
            "0": 5,
            "total": 61,
            "<number>": 30,
            "em": 15,
            "px": 6,
            "vw": 3,
            "%": 2
        },
        "margin": {
            "0": 223,
            "total": 398,
            "em": 154,
            "vw": 9,
            "px": 6,
            "rem": 3,
            "vh": 2,
            "<number>": 1
        },
        "height": {
            "0": 7,
            "total": 103,
            "px": 41,
            "%": 29,
            "em": 22,
            "vh": 2,
            "vw": 2
        },
        "font-size": {
            "total": 335,
            "em": 253,
            "vw": 50,
            "px": 15,
            "rem": 10,
            "%": 5,
            "vh": 2
        },
        "outline-width": {
            "0": 1,
            "total": 1
        },
        "letter-spacing": {
            "0": 7,
            "total": 74,
            "px": 66,
            "em": 1
        },
        "bottom": {
            "0": 7,
            "total": 17,
            "px": 5,
            "em": 4,
            "vw": 1
        },
        "outline": {
            "0": 3,
            "total": 9,
            "px": 5,
            "em": 1
        },
        "max-width": {
            "total": 122,
            "%": 65,
            "px": 30,
            "em": 15,
            "vw": 9,
            "ch": 2,
            "rem": 1
        },
        "padding": {
            "0": 211,
            "total": 635,
            "em": 335,
            "px": 48,
            "vw": 19,
            "rem": 15,
            "vh": 5,
            "%": 2
        },
        "top": {
            "0": 18,
            "total": 86,
            "%": 24,
            "em": 22,
            "px": 15,
            "vw": 4,
            "rem": 3
        },
        "width": {
            "0": 7,
            "total": 285,
            "%": 167,
            "px": 58,
            "em": 28,
            "vw": 18,
            "rem": 3,
            "vh": 3,
            "ch": 1
        },
        "transform-origin": {
            "0": 13,
            "total": 62,
            "%": 49
        },
        "padding-left": {
            "0": 25,
            "total": 91,
            "em": 41,
            "px": 11,
            "rem": 8,
            "vw": 4,
            "%": 2
        },
        "flex": {
            "0": 9,
            "total": 24,
            "<number>": 14,
            "px": 1
        },
        "padding-right": {
            "0": 2,
            "total": 30,
            "em": 16,
            "px": 8,
            "rem": 4
        },
        "flex-basis": {
            "0": 4,
            "total": 85,
            "%": 73,
            "px": 6,
            "em": 2
        },
        "margin-left": {
            "0": 33,
            "total": 113,
            "%": 38,
            "em": 35,
            "px": 5,
            "vw": 2
        },
        "margin-right": {
            "0": 28,
            "total": 95,
            "em": 49,
            "px": 8,
            "%": 7,
            "vw": 3
        },
        "margin-top": {
            "0": 43,
            "total": 167,
            "em": 94,
            "px": 9,
            "vw": 9,
            "rem": 5,
            "vh": 4,
            "<number>": 2,
            "%": 1
        },
        "padding-top": {
            "0": 13,
            "total": 71,
            "em": 38,
            "%": 7,
            "vw": 5,
            "px": 5,
            "vh": 2,
            "rem": 1
        },
        "min-height": {
            "0": 2,
            "total": 19,
            "px": 7,
            "vh": 4,
            "rem": 2,
            "vw": 2,
            "%": 1,
            "em": 1
        },
        "border": {
            "0": 7,
            "total": 41,
            "px": 29,
            "<number>": 5
        },
        "border-top": {
            "total": 4,
            "px": 3,
            "em": 1
        },
        "margin-bottom": {
            "0": 44,
            "total": 165,
            "em": 102,
            "vw": 11,
            "px": 7,
            "vh": 1
        },
        "border-bottom": {
            "0": 2,
            "total": 24,
            "px": 22
        },
        "grid-row-gap": {
            "total": 4,
            "em": 2,
            "vw": 2
        },
        "padding-bottom": {
            "0": 6,
            "total": 50,
            "em": 30,
            "px": 11,
            "rem": 2,
            "%": 1
        },
        "column-gap": {
            "0": 1,
            "total": 4,
            "px": 2,
            "em": 1
        },
        "background-position": {
            "0": 2,
            "total": 80,
            "%": 56,
            "em": 20,
            "vw": 1,
            "px": 1
        },
        "tab-size": {
            "<number>": 2,
            "total": 2
        },
        "border-radius": {
            "0": 41,
            "total": 161,
            "px": 106,
            "%": 9,
            "em": 5
        },
        "left": {
            "0": 20,
            "total": 59,
            "%": 18,
            "em": 12,
            "px": 5,
            "vw": 3,
            "rem": 1
        },
        "background-size": {
            "total": 146,
            "%": 76,
            "px": 48,
            "em": 22
        },
        "scroll-margin-top": {
            "rem": 1,
            "total": 1
        },
        "border-left": {
            "total": 9,
            "px": 8,
            "em": 1
        },
        "min-width": {
            "0": 3,
            "total": 18,
            "px": 12,
            "%": 2,
            "em": 1
        },
        "border-right": {
            "total": 7,
            "px": 5,
            "<number>": 2
        },
        "max-height": {
            "0": 3,
            "total": 13,
            "em": 4,
            "px": 4,
            "vh": 1,
            "%": 1
        },
        "right": {
            "0": 21,
            "total": 40,
            "em": 7,
            "px": 6,
            "vw": 3,
            "%": 3
        },
        "border-color": {
            "<number>": 2,
            "total": 2
        },
        "text-indent": {
            "0": 1,
            "total": 2,
            "%": 1
        },
        "border-bottom-right-radius": {
            "0": 4,
            "total": 4
        },
        "border-bottom-left-radius": {
            "0": 5,
            "total": 5
        },
        "border-left-width": {
            "0": 2,
            "total": 2
        },
        "border-width": {
            "0": 2,
            "total": 8,
            "px": 6
        },
        "vertical-align": {
            "em": 1,
            "total": 1
        },
        "border-top-left-radius": {
            "0": 4,
            "total": 4
        },
        "text-decoration-thickness": {
            "em": 1,
            "total": 1
        },
        "outline-offset": {
            "em": 1,
            "total": 1
        },
        "border-right-width": {
            "0": 2,
            "total": 2
        },
        "columns": {
            "<number>": 1,
            "total": 1
        },
        "grid-gap": {
            "0": 1,
            "total": 4,
            "em": 3
        },
        "border-top-right-radius": {
            "0": 2,
            "total": 2
        }
    },
    "total": 3750,
    "em": 1340,
    "%": 639,
    "px": 630,
    "vw": 160,
    "<number>": 59,
    "rem": 59,
    "vh": 26,
    "ch": 3
}
rviscomi commented 3 years ago

@catalinred @LeaVerou could you give some guidance on how you'd like to aggregate these stats? Some examples:

LeaVerou commented 3 years ago
catalinred commented 3 years ago

Tab Atkins: Unitless 0 are a legacy mistake. This will cause footguns in the future. 2017

Based on the above, when it comes to unitless 0, I'd like to see a total comparison (pie/bar chart) between all the possible 0s: 0/0px/0em/0rem/etc in order to see how this practice has spread over the time.

Besides the total comparison, I agree the % of pages that use a unitless 0 is very helpful too.

LeaVerou commented 3 years ago

Oh interesting, I'd need to adjust the JS for that. Or just split it altogether into a separate 0-measuring query (since the "0" key is out of place anyway in this one).

LeaVerou commented 3 years ago

The problem is, unitless 0 can be either a <number> or a <length> and is disambiguated based on context. So we can't just match zeroes and draw conclusions, because some of these zeroes will be intended as <number>s. Note that the same property can have both, e.g. border-image accepts either <number> or <length>, and there might also be shorthands that accept both at once.

We could only take into account properties that only accept length(s), but a) it would be painful to compile the list and b) we may miss a lot of usage. What do you think @catalinred @rviscomi?

rviscomi commented 3 years ago

Perhaps it's ok to have that ambiguity in the results and describe why it exists in the write-up.

rviscomi commented 3 years ago

@LeaVerou please take a look at this first pass for "most frequently used properties with unit" query: https://docs.google.com/spreadsheets/d/1sMWXWjMujqfAREYxNbG_t1fOJKYCA6ASLwtz4pBQVTw/edit#gid=1200981062. Lots of garbage units in there. Should your JS or my SQL be filtering these units? Adapted from your earlier regex, maybe this could work: /(%|cm|mm|Q|in|pc|pt|px|ex|ch|r?em|lh|vw|vh|vmin|vmax)/.

catalinred commented 3 years ago

We could only take into account properties that only accept length(s), but a) it would be painful to compile the list and b) we may miss a lot of usage.

I agree. Do you think, in this case, using a list of most popular properties would do it? e.g. Microsoft's archived CSS properties usage

Also, do we have a similar list of CSS properties usage for this year's chapter? If I'm not mistaken, we didn't have one in last year's chapter and I think it would be great to have it.

LeaVerou commented 3 years ago

Ok, so I just pushed several fixes:

rviscomi commented 3 years ago

@LeaVerou I'm getting "ReferenceError: removeFunctionCalls is not defined" errors in BigQuery when I run your updated code. Is removeFunctionCalls a new function in css-utils.js? If so can you push those changes to the branch in the Almanac repo?

LeaVerou commented 3 years ago

Whoops. Just pushed an updated css-utils!