angularfontsresponsive-designfrontendtailwind-css

Tailwind overrides base font-size defined in the html tag on the custom media queries


Description of the problem

 theme: {
        extend: {
          screens: {
            xs: "48rem", // 480px
            sm: "64rem", // 640px
            md: "76.8rem", // 768px
            lg: "102.4rem", // 1024px
            xl: "128rem", // 1280px
            "2xl": "135rem", // 1350px
            "3xl": "153.6rem", // 1536px
          },
          spacing: {
            "sp-xs": "var(--sp-xs)",
            "sp-sm": "var(--sp-sm)",
            "sp-md": "var(--sp-md)",
            "sp-lg": "var(--sp-lg)",
            "sp-xl": "var(--sp-xl)",
            "sp-2xl": "var(--sp-2xl)",
            "sp-3xl": "var(--sp-3xl)",
            "sp-4xl": "var(--sp-4xl)",
            "sp-5xl": "var(--sp-5xl)",
            "sp-6xl": "var(--sp-6xl)",

This is my tailwind.config.js in my angular application. Everything in the configuration is working as intended except for the custom media queries.

html {
  font-size: 62.5%;
}

@media (min-width: 480px) {
  html {
    font-size: 10px;
  }
}

In the root file I override default font-size of the page to 62.5% which is 10px for most of users considering that by default browser font-size is 16px.

This font-size is applied everywhere in my application correctly. Meaning that tailwind interprets any rems that I used be it in variable or in the class of html tag as custom value.

Example: class="flex size-[4.8rem]" is 48px and it is correct.

But when it comes to the screens section of the tailwind.config.js it calculates the values based on the initial default font-size value which is 16px.

Meaning that the screen breakpoint

xs: "48rem" should be 10 * 48 = 480 px but it is 16 * 48 = 768px.

Tailwind recognizes custom breakpoints that I used, but it calculates their pixels based on wrong font-size which is not an issue for me but will be hard for other developers understand what is going on and this is not intuitive at all.

What I tried

  1. I tried defining base font-size in the tailwind.config.js and it didn't work
  2. Redefining font-size in the media query which can be seen from the tailwind.config.js that I pasted above.

None of these helped.

Versions


Solution

  • This has nothing to do with Tailwind but instead how media query works. The rem unit in a media query is based on the initial value. In other words, it will not be affected by the font-size declaration on root element (the font-size:10px; or font-size:62.5% won't affect it).

    As per spec:

    Relative length units in media queries are based on the initial value, which means that units are never based on results of declarations. Note: For example, in HTML, the em unit is relative to the initial value of font-size, defined by the user agent or the user’s preferences, not any styling on the page. Note that this will also take into account additional restrictions the user might apply, such as minimum font sizes.

    As you can see in the below example:

    html {
      font-size: 62.5%;
    }
    
    
    .test-query {
      /* 500px */
      width: 50rem;
      height: 50rem;
      outline: 1px solid red;
    
      &::after {
        content: "Screen width is below 50rem (800px)";
      }
    }
    
    /* 800px */
    @media (min-width: 50rem) {
      .test-query {
        outline: 1px solid blue;
    
        &::after {
          content: "Screen width is over 50rem (800px)";
        }
      }
    }
    <div class="test-query"></div>


    That being said, I don't think the media query based on the initial rem setting is unintuitive. In the end, it is querying the media width, not the font's width. However, if you still need a set of breakpoints to be 62.5% of the default Tailwind breakpoints, define them explicitly in tailwind.config. (Optionally, you can add a seperate set of breakpoints to not break existing layouts, though I find it less intuitive and maintainable.)

    tailwind.config = {
      theme: {
        extend: {
          screens: {
            xs: "18.75rem", // 300px
            sm: "25rem", // 400px
            md: "30rem", // 480px
            lg: "40rem", // 640px
            xl: "50rem", // 800px
            "2xl": "52.5rem", // 843.75px
            "3xl": "60rem", // 960px
          }
        }
      }
    }
    html {
      font-size: 62.5%;
    }
    <script src="https://cdn.tailwindcss.com"></script>
    
    <div class="bg-red-500 sm:bg-blue-500 size-[5rem] text-sm">box</div>