Jump to content

How do you handle responsive font sizes, paddings etc?


bernhard
 Share

Recommended Posts

Hey Frontend Gurus,

I'm curious: How do you handle font/headline sizes? In px? rem? percent or vw/vh? I'm not so much into frontend and we have had some discussion design/dev in our latest project... So I wonder what is the best way for frontend font-sizes/paddings/margins in 2022?

@szabesz pointed me to https://getbootstrap.com/docs/5.2/getting-started/rfs/ in a related topic. The textformatter solves the problem of fixed font sizes breaking at custom positions. But maybe it would better to adjust headline fontsize dynamically instead of using two or three breakpoints?

Thx for your help ? 

Link to comment
Share on other sites

I am using a SASS mixin which renders REM out of given PX values. 

So when designing my layouts you typically have px based font sizes.
Then when developing the website I want to make use of rem instead of px. Calculating each value can be time consuming and it might be confusing cause rem is relative to the base font size. 

@function calculateRem($size) {
  $remSize: $size / 16px;
  @return #{$remSize}rem;
}

@mixin fontSize($size) {
  font-size: calculateRem($size);
}

@mixin lineHeight($size) {
  line-height: calculateRem($size);
}

This however is not responsive in the way that the font size adjusts to the viewport. 

I like to have control over my font sizes so I hard code - for example headlines - fitting the four big breakpoints: large desktop, desktop, tablet, mobile. 
Yes it is a bit of work...

For big, prominent title headlines (over background images for example) I often use vw or vh as font height. That makes the fontsize fluid but it can give you some weird "inbetween" values. So you have also have to make small adjustments based on breakpoints to make sure it looks good everywhere.

1 hour ago, bernhard said:

 

@szabesz pointed me to https://getbootstrap.com/docs/5.2/getting-started/rfs/ in a related topic. The textformatter solves the problem of fixed font sizes breaking at custom positions. But maybe it would better to adjust headline fontsize dynamically instead of using two or three breakpoints?

This however looks promising. It seems to combine REM and VW. I recently upgraded to Bootstrap 5 and totally overlooked this new feature (by the way I am still thinking about switching to UIKit3 but for other reasons but this is another point for bootstrap).

  • Like 1
Link to comment
Share on other sites

Typography is not a simple topic but I'll try to explain how I use it.

But first, the difference between EM/REM. Generally, an EM got it roots in print where it refers to the width of the upper-case M. When css came about, they changed it to refer to a relationship of the parent element. By default, one EM generally is 16 pixels in the browser world. The REM (Root EM) is in relation to the root (usually the HTML definition if no ::root{} is defined) font size as you have defined in CSS.

Some inconsistency -- You can use both EM and REM in margin/padding definitions. However, when using EM as the unit in a margin definition it looks only at the current element; It does not refer back up to a parent. This is not the case with REMs. The REM declaration is always looking at the root.

// EM
html { font-size: 16px; }
article { font-size: 20px; }
p { 
	font-size: 1.1em; 
	margin-bottom: 1em;
}

<article>
  This is 20px.
  <p>This is 1.1 x 20px. The bottom margin is 1.1em regardless of parent font size setting.</p>
</article>


// REM
html { 
	font-size: 18px;
}
article { font-size: 20px; }
p { 
	font-size: 1.1rem; 
	margin-bottom: 1rem;
}

<article>
  This is 20px.
  <p>This is 1.1 x 18px. The bottom margin is 1 x 18px.</p>
</article>

The viewport width/height (VW/VH) allows for a 'fluid' scaling. However, the drawback is that smaller devices will not zoom in or out should the font size scale too small. Also, on very wide screens this scaling would likely make the text way too big, to the point of interfering with other content.

My method:

I define my base font size as 16px (usually the browser default). I also include variables to make future changes very simple. I put my font size break points at the top of my css file (usually after ::ROOT{} ) so that I don't have to go hunting should I need to change something.

To avoid the confusion between parent references, I define all font sizes, margins, paddings, widths, etc. in REMs, except for the base ::root{} definition which is in pixels.

:root {
  --fs-norm: 1rem; // defaults to browser's font-size definition
  --fs-big: 2rem;
  --fs-hdg: clamp(3.5rem, 10vw + 1rem, 14rem); // This sets the min and max font-sizes and scales in between
}

@media (min-width: 40rem) {
  :root {
    --fs-norm: 1.125rem;
    --fs-big: 3rem;
  }
}
body {
  font-size: var(--fs-norm);
  line-height: 1.6;
}
h1 {
  font-size: var(--fs-hdg);
  text-transform: uppercase;
}

I hope this helps. Like I said, this isn't a simple topic where you can say, "Use x because...".

ps. Not a front-end guru so others may have a better reply.

  • Like 3
  • Thanks 2
Link to comment
Share on other sites

57 minutes ago, Stefanowitsch said:

but this is another point for bootstrap

Quote

Using RFS 
The mixins are included in Bootstrap and are available once you include Bootstrap’s scss. RFS can also be installed standalone if needed.

So I guess it should be possible to use UIkit + https://github.com/twbs/rfs/tree/v9.0.6#installation ? ? Maybe @gebeer could show how that could be added to the postcss workflow of RockFrontendTailwind?

If you need another plus for UIkit be sure to check out their JavaScript framework: https://github.com/uikit/uikit-site/blob/feature/js-utils/docs/pages/javascript-utilities.md It's really great because you can add custom JS very easily and manipulate all the great UIkit components or use helpers like addClass() or util.each(array, () => { ... }); etc! Another plus might be the great integration of RockFrontend and some additional components that I put there: https://github.com/baumrock/RockFrontend/tree/main/uikit

@rick thx!

  • Like 1
Link to comment
Share on other sites

1 hour ago, bernhard said:

If you need another plus for UIkit be sure to check out their JavaScript framework: https://github.com/uikit/uikit-site/blob/feature/js-utils/docs/pages/javascript-utilities.md It's really great because you can add custom JS very easily and manipulate all the great UIkit components or use helpers like addClass() or util.each(array, () => { ... }); etc! Another plus might be the great integration of RockFrontend and some additional components that I put there: https://github.com/baumrock/RockFrontend/tree/main/uikit

I am really impressed what UIkit is able to do out of the box. But the main bummer for me is that the grid system is so weird (for someone who is using bootstrap since 10+ years..). Why a classic 12-column grid is not supported in UIkit3 is beyond my comprehension. The 12-col grid is the basis of every project I worked on in the past and am working on in the future. But I am drifting away from the topic, sorry ?


 

Link to comment
Share on other sites

For me it was the opposite ? Bootstrap always needed those weird row-wrappers which is totally strange to me. Maybe I didn't understand it correctly but defining the rows via row wrapper in the markup?? How should that work if I need eg 1 item per row on mobile and 3 items per row on desktop? In UIkit that's as simple as this:

<div class="uk-grid-width-1-1 uk-grid-width-1-3@m" uk-grid>
  <div>foo</div>
  <div>bar</div>
  <div>baz</div>
  <div>foo</div>
  <div>bar</div>
  <div>baz</div>
</div>

12-column-grid? Did you see this? https://github.com/uikit/uikit/issues/217#issuecomment-31829807 ? 

  • Like 1
Link to comment
Share on other sites

13 minutes ago, bernhard said:

For me it was the opposite ? Bootstrap always needed those weird row-wrappers which is totally strange to me. Maybe I didn't understand it correctly but defining the rows via row wrapper in the markup?? How should that work if I need eg 1 item per row on mobile and 3 items per row on desktop? In UIkit that's as simple as this:

<div class="uk-grid-width-1-1 uk-grid-width-1-3@m" uk-grid>
  <div>foo</div>
  <div>bar</div>
  <div>baz</div>
  <div>foo</div>
  <div>bar</div>
  <div>baz</div>
</div>

12-column-grid? Did you see this? https://github.com/uikit/uikit/issues/217#issuecomment-31829807 ? 

Basically you can add as much cols inside a row wrapper as you like in bootstrap. You then define the width of each col via class names.

I compared both frameworks and this should clear it up it:

Bootstrap class names:

container -> defines the max width of the content. UIKit equivalent would be uk-container.

row -> wrapper for the columns. UIkit equivalent would be uk-grid.

col-x -> the column with the specified width. UIkit equivalent would be uk-width-x-x

So the bootstrap variant of your code example would look like this:

<div class="container">
  <div class="row">
    <div class="col">foo</div>
    <div class="col">bar</div>
    <div class="col">baz</div>
    <div class="col">foo</div>
    <div class="col">bar</div>
    <div class="col">baz</div>
  </div>
</div>
  • Like 1
Link to comment
Share on other sites

Usually I set the font size in the html or body tags, and then use rem for pretty much everything else. I use em in the rare occasions that the size of an element should definitely dependent on the size of the parent, but usually I want the flexibility to control them independently of each other with rem. When you use em on everything, it's very easy to overlook small differences between the text inside elements and you end up having the same kind of text set in 11.5px and 12px in different places, for instance.

As for the base size itself, it depends a lot on the layout. Some layouts account for large screens, and divide into multiple columns. On those cases the base font can usually stay the same though any screen size, and can be set in pixels or em. On more static layouts I normally want the font to grow a bit with the screen width, but not too much (I mean, not proportionally. I want it to grow less and less as the screen becomes larger). For that I use a calc() to create a relation between the vw and the pixels. For instance:

font-size: calc(8px + .7vw);

And I usually want to define a minimum and a maximum sizes. This can be done with media queries, or simply by using the clamp function:

font-size: clamp(15px, calc(8px + .7vw), 20px);

This defines that the font grows with the screen width but never becomes smaller than 15px or larger than 20px.

Edited by diogo
Oh, I had to interrupt writing my text and meanwhile the discussion switched from setting font sizes to uikit grids :D
  • Like 3
  • Thanks 2
Link to comment
Share on other sites

4 hours ago, bernhard said:

How do you handle font/headline sizes?

I am used to use rem, the reason => web accessibility => a pixel is not responsive and with some algebra (lol) for fluid typo, the concept is called Poly Fluid Sizing and using tailwindcss utilities?

Rule them all with this linear equation definition, which result the font-size :  Linear equation definition

Take a look at this sample: https://codepen.io/neil/pen/agzZVg
And give a read to :  https://www.smashingmagazine.com/2017/05/fluid-responsive-typography-css-poly-fluid-sizing/

✌️

 

Edit: for the rest, everything with a tailwind.config.js, it's so cool:

Edited by flydev ??
tailwindcss everywhere
  • Like 2
  • Thanks 1
Link to comment
Share on other sites

@flydev ?? Can that be used in a way to make sure text fits within a box that is static and pixel-sized?

Scenario: I develop HTML-based "slides" for monitors in a building, used for marketing purposes (ex: fast-food restaurant screens) which has a known, defined size (1920x1080). Because of that, I don't worry too much about responsiveness of containers. What would be awesome, however, is making sure text is sized to forcibly fit within a contained-size container without overflow -- and an unknown amount of text.

I've not found many good solutions to this. I also haven't dived into Tailwind, so am unfamiliar with what it provides in that area, if anything.

Link to comment
Share on other sites

I don't really bother because I use the pocketgrid css, which works with free to choose unlimited columns and free to choose unlimited breakpoints and blocks. I resize a website from wide screen to mobile screen and simply set breakpoints only where they are needed to resize a font, picture, margin, padding, etc, etc to make it look good. Contrary to something like Bootstrap would be very difficult because Bootstrap and the likes work with a limited set predefined breakpoints.

  • Like 1
Link to comment
Share on other sites

6 hours ago, BrendonKoz said:

Scenario: I develop HTML-based "slides" for monitors in a building, used for marketing purposes (ex: fast-food restaurant screens) which has a known, defined size (1920x1080). Because of that, I don't worry too much about responsiveness of containers. What would be awesome, however, is making sure text is sized to forcibly fit within a contained-size container without overflow -- and an unknown amount of text.

I've not found many good solutions to this. I also haven't dived into Tailwind, so am unfamiliar with what it provides in that area, if anything.

I don't think there is a pure CSS solution for this. You might want to have a look at https://github.com/rikschennink/fitty. Used it in a project and is working great.

Link to comment
Share on other sites

14 hours ago, bernhard said:

So I guess it should be possible to use UIkit + https://github.com/twbs/rfs/tree/v9.0.6#installation ? ? Maybe @gebeer could show how that could be added to the postcss workflow of RockFrontendTailwind?

You could use it with your RockFrontend UIKit setup because that is based on LESS. But you would have to introduce npm based packages into RockFrontend

Unfortunately, they don't provide a pure CSS version of RFS. So I can't integrate it with RockFrontendTailwind since that purposefully uses pure CSS in a PostCSS based build pipeline.

12 hours ago, flydev ?? said:

I am used to use rem, the reason => web accessibility => a pixel is not responsive and with some algebra (lol) for fluid typo, the concept is called Poly Fluid Sizing and using tailwindcss utilities?

Rule them all with this linear equation definition, which result the font-size :  Linear equation definition

Take a look at this sample: https://codepen.io/neil/pen/agzZVg
And give a read to :  https://www.smashingmagazine.com/2017/05/fluid-responsive-typography-css-poly-fluid-sizing/

 

Thank you for the links. How would a living Tailwind implementation look like, defining the calculated poly fluid sized font sizes in tailwind.config.js?

 

15 hours ago, rick said:

Typography is not a simple topic but I'll try to explain how I use it.

But first, the difference between EM/REM. Generally, an EM got it roots in print where it refers to the width of the upper-case M. When css came about, they changed it to refer to a relationship of the parent element. By default, one EM generally is 16 pixels in the browser world. The REM (Root EM) is in relation to the root (usually the HTML definition if no ::root{} is defined) font size as you have defined in CSS.

Some inconsistency -- You can use both EM and REM in margin/padding definitions. However, when using EM as the unit in a margin definition it looks only at the current element; It does not refer back up to a parent. This is not the case with REMs. The REM declaration is always looking at the root.

// EM
html { font-size: 16px; }
article { font-size: 20px; }
p { 
	font-size: 1.1em; 
	margin-bottom: 1em;
}

<article>
  This is 20px.
  <p>This is 1.1 x 20px. The bottom margin is 1.1em regardless of parent font size setting.</p>
</article>


// REM
html { 
	font-size: 18px;
}
article { font-size: 20px; }
p { 
	font-size: 1.1rem; 
	margin-bottom: 1rem;
}

<article>
  This is 20px.
  <p>This is 1.1 x 18px. The bottom margin is 1 x 18px.</p>
</article>

The viewport width/height (VW/VH) allows for a 'fluid' scaling. However, the drawback is that smaller devices will not zoom in or out should the font size scale too small. Also, on very wide screens this scaling would likely make the text way too big, to the point of interfering with other content.

My method:

I define my base font size as 16px (usually the browser default). I also include variables to make future changes very simple. I put my font size break points at the top of my css file (usually after ::ROOT{} ) so that I don't have to go hunting should I need to change something.

To avoid the confusion between parent references, I define all font sizes, margins, paddings, widths, etc. in REMs, except for the base ::root{} definition which is in pixels.

:root {
  --fs-norm: 1rem; // defaults to browser's font-size definition
  --fs-big: 2rem;
  --fs-hdg: clamp(3.5rem, 10vw + 1rem, 14rem); // This sets the min and max font-sizes and scales in between
}

@media (min-width: 40rem) {
  :root {
    --fs-norm: 1.125rem;
    --fs-big: 3rem;
  }
}
body {
  font-size: var(--fs-norm);
  line-height: 1.6;
}
h1 {
  font-size: var(--fs-hdg);
  text-transform: uppercase;
}

I hope this helps. Like I said, this isn't a simple topic where you can say, "Use x because...".

ps. Not a front-end guru so others may have a better reply.

I like that pure CSS approach. Well thought out.

Personally, I also base font sizes, paddings and margins on rem in most cases. 

 

  • Like 1
Link to comment
Share on other sites

On 10/4/2022 at 3:49 PM, psy said:

@BrendonKoz

Container queries have been on the CSS agenda for a long time. At present the @container rule has limited browser support but it's definitely on its way. See https://caniuse.com/?search=%40container

I'm familiar with (a little bit about) container queries, but I haven't seen anything that would offer up automatic negotiation to forcibly size an unknown amount of text into a statically sized container without overflow. Thanks though! Lots of nice things coming to us via CSS, for sure.

On 10/4/2022 at 10:05 PM, gebeer said:

I don't think there is a pure CSS solution for this. You might want to have a look at https://github.com/rikschennink/fitty. Used it in a project and is working great.

I haven't seen anything either, though since Tailwind seems to take advantage of CSS and JS, I wasn't sure if they might've solved this too. ? I've used fitty for a headline in one of the aforementioned slides already, though (at the time) it did have a few limitations. I see it's still getting updates, I'll have to look it over again. Thanks!!!

I realize I kind of sidetracked the conversation on a bit of a tangent. Sorry! Overall this is a great topic though, Bernard!

  • Like 2
Link to comment
Share on other sites

Hey @BrendonKoz no worries we are in DevTalk ? 

And I have had such a great idea yesterday, I almost can't believe it myself ? It solves all those weird scaling issues and makes it possible to scale any css rule that has a numeric value, like font-size, border, padding/margin, border-radius etc...

It's so great and mighty that I have to do a video about that!! And it even comes with a helper to write values in PX that will automatically be converted to REM units ?

Sneak Peak:

/* default viewport settings: min=400, max=1440 */
/* all min/max values will be fluid in between! */
.fluid-box {
  /* font size 20px@400 30px@1440 */
  /* px will be converted to REM automatically! */
  font-size: rfGrow(20pxrem, 30pxrem);
  /* border-width 2px@400 10px@1440 (PX-->REM) */
  border: rfGrow(2pxrem, 10pxrem) solid red;
  /* border-radius 5px@400 20px@1440 (PX) */
  border-radius: rfGrow(5px, 20px);
}

Want to customize min and max width setting? Easy ?

$rockfrontend->growMin('800');
$rockfrontend->growMax('1200');

Here is a demo with slightly different values:

194649513-b4dc63d9-670c-4b22-a54a-cc459e

I'm loving it ?

  • Like 1
Link to comment
Share on other sites

Quote

And I have had such a great idea yesterday, I almost can't believe it myself ? It solves all those weird scaling issues and makes it possible to scale any css rule that has a numeric value, like font-size, border, padding/margin, border-radius etc...

Hi,

Will the scaling also work for images and html5 videos ? Hope to see more of this $rockfrontend growMin .... growMax ....

Link to comment
Share on other sites

On 10/8/2022 at 3:56 PM, pwired said:

Will the scaling also work for images and html5 videos ? Hope to see more of this $rockfrontend growMin .... growMax ....

Sure, RockFrontend just injects a CSS variable "rf-grow" to the root element and updates it on window resize. Then you can use regular (and easy to read and understand) CSS to define min/max values with fluid behaviour:

https://github.com/baumrock/RockFrontend/blob/bcec0efcfba2036b26997ac7f2648300e978ee82/RockFrontend.js#L29-L48

<video style="width: calc(200px + 300px * var(--rf-grow))">...</video>

That means: Min width = 200px, Max width = 500px, fluid in between ?

That's all the magic!

That's outdated as of 11/2022 - now RockFrontend does everything with CSS only (and some math / calc) 😎

  • Like 1
Link to comment
Share on other sites

  • 5 weeks later...

I am late to this party, just watched the video and I think it is great that a css based solution is possible. I started looking into this process to replace what I have used for many years to achieve this - not so much because of the issue of mobile versus desktop, but for the sake of container readability, which was why this library was created so long ago.

https://simplefocus.com/flowtype

If you look at how old this github repo is (2013) and the update to the readme pointing to css-tricks, you may think it is not worth the review, but there are a few things to consider and tuning metrics that really will effect the factors you take into account.

The things that you will want to be able to easily tweak at the design phase revolve around the aspect of the webfont you are working with. Definitely not a one size fits all solution and if in particular you are looking at handling text in columns.

https://simplefocus.com/flowtype/demo

Perhaps you might find their font ratio math interesting - or another cat to skin. I do think that legibility - 45 to 75 characters - is a valuable CX guideline:

http://webtypography.net/2.1.2

I look forward to playing around with the rfGrow feature.

  • Like 1
Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...