mdgriffith / elm-ui

What if you never had to write CSS again?
https://package.elm-lang.org/packages/mdgriffith/elm-ui/latest/
BSD 3-Clause "New" or "Revised" License
1.35k stars 110 forks source link

em font size #303

Open dullbananas opened 3 years ago

pravdomil commented 3 years ago

Hi @dullbananas, can you be more descriptive, what is your motivation behind creating this issue?

dullbananas commented 3 years ago

@pravdomil using em for font size allows the user to adjust it

pravdomil commented 3 years ago

have not heard about such a thing

ghost commented 3 years ago

The em method of font sizing is where the font size is created as proportional to the font size of the parent element. Consider the following:

<div style="font-size: 24pt;">
  <p style="font-size: 1em;">
    Ways that you can render font size in HTML:
    <ul style="font-size: 0.75em">
      <li>Points</li>
      <li>Pixels</li>
      <li>Em</li>
      <li>Rem</li>
    </ul>
  </p>
</div>

The font size of the p tag is 24pt and the font size of the list elements is 18pt because it's 0.75x the parent element's font size. Basically, it's CSS's way of parameterizing font size so that the relative sizing stays the same within an element and all you have to change is the top-level element.

The thing is, the em method is only necessary in CSS because CSS doesn't have anything to do with the generation of the document. And therefore you can't pass around values the way you can in a programming language. em is a context binding it uses to hack around this. But Elm just IS the thing that generates your page, and it's a full blown programming language. So you can implement the behavior yourself by having the font size of each of your elements be a parameter passed into the function which renders the element or which builds & updates its state:

viewMyThing : MyState -> Float -> Element msg
viewMyThing state parentFontSize =
  row
    [ Font.size (round (state.fontRatio * parentFontSize)) ]
    [ -- render rest of state
    ]

Also, I find em problematic in principle in regards to elm-ui since elm-ui strives as much as possible to have no unexpected layout behavior: WYSIWYG. But with em the behavior of viewing elements is dependent on context and variables which are outside the scope of not only the element but sometimes the source code itself! Such as when I compile my Elm program to a main.js and set up my own index.html (which is often necessary for things like JS interop and WebSockets):

<body>
  <!-- THE LAYOUT CHANGES BASED ON WHAT THE FONT SIZE ATTRIBUTE OF THE #app IS -->
  <div style="font-size: 24pt;" id="app">
    <script>
      var elmApp = Elm.Main.init({
      node: document.getElementById("app"),
        flags: null,
      });
    </script>
  </div>
</body>

I think pretty much the only use case is if you are replacing one part of a bigger front-end which already extensively uses em. I suspect you could probably work around this using ports and DOM introspection on the JS side though.

TL;DR - em is hack that CSS (probably begrudgingly) supports to allow parametric sizing and it exists only because CSS isn't involved in document generation. But Elm just IS the thing that generates your page and it's a full programming language, so go nuts!

madidier commented 9 months ago

There's a good article here on why em/rem units matter. It's an accessibility issue.

TL;DR: In general, 16px is the default font size in most web browsers, but a user may decide to change that in their OS and/or browser settings for accessibility reasons. Using px units for font-size means the user's preferences (and needs) won't be respected.

Regarding the issue of em units being dependent on the parent node's font-size, there's a simple workaround: use rem units instead. As long as no CSS overrides the root element's font-size, they will be relative to the user's preferred font size and independent of the element's insertion point in the DOM.

It is possible to come up with a workaround for elm-ui based on code like this one to detect the user's font size, but I'd rather use the simpler and more robust option of specifying font sizes using rem units.

If you want to see a couple of examples of websites that do this correctly, there's Wikipedia and MDN.

Unfortunately, many popular websites don't respect the user agent's font-size. I don't think that's a good argument against supporting relative units.

PS: I found out archive.org ran their own test and found out that 3% of their users used a non-default font size.

ricardo-rp commented 8 months ago

Just like @madidier said, it's an accessibility issue. I know many older folk who use larger font-sizes so they can read what's on their phones. I think a way to use rem or just rem as default unit would be very good.