I've created a site using the Zurb Foundation 3 grid. Each page has a large h1
:
body {_x000D_
font-size: 100%_x000D_
}_x000D_
_x000D_
/* Headers */_x000D_
_x000D_
h1 {_x000D_
font-size: 6.2em;_x000D_
font-weight: 500;_x000D_
}
_x000D_
<div class="row">_x000D_
<div class="twelve columns text-center">_x000D_
<h1> LARGE HEADER TAGLINE </h1>_x000D_
</div>_x000D_
<!-- End Tagline -->_x000D_
</div>_x000D_
<!-- End Row -->
_x000D_
When I resize the browser to mobile size the large font doesn't adjust and causes the browser to include a horizontal scroll to accommodate for the large text.
I've noticed that on the Zurb Foundation 3 Typography example page, the headers adapt to the browser as it is compressed and expanded.
Am I missing something really obvious? How do I achieve this?
This question is related to
css
responsive-design
font-size
zurb-foundation
em
You can make the font size responsive if defining it in vw (viewport width). However, not all browsers support it. The solution is to use JavaScript to change the base font size depending on the browser width and set all font sizes in %.
Here is an article describing how to make responsive fontsizes: http://wpsalt.com/responsive-font-size-in-wordpress-theme/
I saw a great article from CSS-Tricks. It works just fine:
body {
font-size: calc([minimum size] + ([maximum size] - [minimum size]) * ((100vw -
[minimum viewport width]) / ([maximum viewport width] - [minimum viewport width])));
}
For example:
body {
font-size: calc(14px + (26 - 14) * ((100vw - 300px) / (1600 - 300)));
}
We can apply the same equation to the line-height
property to make it change with the browser as well.
body {
font-size: calc(14px + (26 - 14) * ((100vw - 300px) / (1600 - 300)));
line-height: calc(1.3em + (1.5 - 1.2) * ((100vw - 300px)/(1600 - 300)));
}
This is partly implemented in foundation 5.
In file _type.scss they have two sets of header variables:
// We use these to control header font sizes
// for medium screens and above
$h1-font-size: rem-calc(44) !default;
$h2-font-size: rem-calc(37) !default;
$h3-font-size: rem-calc(27) !default;
$h4-font-size: rem-calc(23) !default;
$h5-font-size: rem-calc(18) !default;
$h6-font-size: 1rem !default;
// We use these to control header size reduction on small screens
$h1-font-reduction: rem-calc(10) !default;
$h2-font-reduction: rem-calc(10) !default;
$h3-font-reduction: rem-calc(5) !default;
$h4-font-reduction: rem-calc(5) !default;
$h5-font-reduction: 0 !default;
$h6-font-reduction: 0 !default;
For medium up, they generate sizes based on the first set of variables:
@media #{$medium-up} {
h1,h2,h3,h4,h5,h6 { line-height: $header-line-height; }
h1 { font-size: $h1-font-size; }
h2 { font-size: $h2-font-size; }
h3 { font-size: $h3-font-size; }
h4 { font-size: $h4-font-size; }
h5 { font-size: $h5-font-size; }
h6 { font-size: $h6-font-size; }
}
And for default-i.e small screens, they use a second set of variables to generates CSS:
h1 { font-size: $h1-font-size - $h1-font-reduction; }
h2 { font-size: $h2-font-size - $h2-font-reduction; }
h3 { font-size: $h3-font-size - $h3-font-reduction; }
h4 { font-size: $h4-font-size - $h4-font-reduction; }
h5 { font-size: $h5-font-size - $h5-font-reduction; }
h6 { font-size: $h6-font-size - $h6-font-reduction; }
You can use these variables and override in your custom scss file to set font sizes for respective screen sizes.
jQuery's "FitText" is probably the best responsive header solution. Check it out at GitHub: https://github.com/davatron5000/FitText.js
We can use calc() from css
p{
font-size: calc(48px + (56 - 48) * ((100vw - 300px) / (1600 - 300))) !important;
}
The mathematical formula is calc(minsize + (maxsize - minsize) * (100vm - minviewportwidth) / (maxwidthviewoport - minviewportwidth)))
I've been playing around with ways to overcome this issue, and believe I have found a solution:
If you can write your application for Internet Explorer 9 (and later) and all other modern browsers that support CSS calc(), rem units, and vmin units. You can use this to achieve scalable text without media queries:
body {
font-size: calc(0.75em + 1vmin);
}
Here it is in action: http://codepen.io/csuwldcat/pen/qOqVNO
The text size can be set with a vw
unit, which means the "viewport width". That way the text size will follow the size of the browser window:
https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_responsive_text
For my personal project I used vw and @meida. It works perfectly.
.mText {
font-size: 6vw;
}
@media only screen and (max-width: 1024px) {
.mText {
font-size: 10vw;
}
}
.sText {
font-size: 4vw;
}
@media only screen and (max-width: 1024px) {
.sText {
font-size: 7vw;
}
}
A responsive font size can also be done with this JavaScript code called FlowType:
FlowType - Responsive web typography at its finest: font-size based on element width.
Or this JavaScript code called FitText:
FitText - Makes font-sizes flexible. Use this plugin on your responsive design for ratio-based resizing of your headlines.
Try including this on your style sheet:
html {
font-size: min(max(16px, 4vw), 22px);
}
More info at https://css-tricks.com/simplified-fluid-typography/
There are several ways to achieve this.
Use a media query, but it requires font sizes for several breakpoints:
body
{
font-size: 22px;
}
h1
{
font-size: 44px;
}
@media (min-width: 768)
{
body
{
font-size: 17px;
}
h1
{
font-size: 24px;
}
}
Use dimensions in % or em. Just change the base font size, and everything will change. Unlike the previous one, you could just change the body font and not h1 every time or let the base font size be the default of the device and the rest all in em
:
CSS 3 supports new dimensions that are relative to the view port. But this doesn't work on Android:
3.2vmax = Bigger of 3.2vw or 3.2vh
body
{
font-size: 3.2vw;
}
See CSS-Tricks ... and also look at Can I Use...
Here is something that worked for me. I only tested it on an iPhone.
Whether you have h1
, h2
, or p
tags put this around your text:
<h1><font size="5">The Text you want to make responsive</font></h1>
This renders a 22pt text on a desktop and it is still readable on the iPhone.
<font size="5"></font>
There's another approach to responsive font sizes - using rem units.
html {
/* Base font size */
font-size: 16px;
}
h1 {
font-size: 1.5rem;
}
h2 {
font-size: 1.2rem;
}
Later in media queries, you can adjust all fonts sizes by changing the base font size:
@media screen and (max-width: 767px) {
html {
/* Reducing base font size will reduce all rem sizes */
font-size: 13px;
}
/* You can reduce font sizes manually as well */
h1 {
font-size: 1.2rem;
}
h2 {
font-size: 1.0rem;
}
}
To make this work in Internet Explorer 7 and Internet Explorer 8 you will have to add a fallback with px units:
h1 {
font-size: 18px;
font-size: 1.125rem;
}
If you're developing with Less, you can create a mixin that will do the math for you.
Rem units support - http://caniuse.com/#feat=rem
In actual original Sass (not scss) you could use the below mixins to automatically set the paragraph's and all headings' font-size
.
I like it because it is much more compact. And quicker to type. Other than that, it provides the same functionality. Anyway, if you still want to stick to the new syntax - scss, then feel free to convert my Sass content to scss here: [CONVERT SASS TO SCSS HERE]
Below I give you four Sass mixins. You will have to tweak their settings to your needs.
=font-h1p-style-generator-manual() // You don’t need to use this one. Those are only styles to make it pretty.
=media-query-base-font-size-change-generator-manual() // This mixin sets the base body size that will be used by the h1-h6 tags to recalculate their size in a media query.
=h1p-font-size-generator-auto($h1-fs: 3em, $h1-step-down: 0.3, $body-min-font-size: 1.2em, $p-same-as-hx: 6) // Here you will set the size of h1 and size jumps between h tags
=config-and-run-font-generator() // This one only calls the other ones
After you finish playing with settings just make a call on one mixin - which is: +config-and-run-font-generator(). See code below and comments for more information.
I guess you could do it automatically for a media query like it is done for header tags, but we all use different media queries, so it would not be appropriate for everyone. I use a mobile-first design approach, so this is how I would do that. Feel free to copy and use this code.
COPY AND PASTE THESE MIXINS TO YOUR FILE:
=font-h1p-style-generator-manual()
body
font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif // google fonts
font-size: 100%
line-height: 1.3em
%headers
line-height: 1em
font-weight: 700
p
line-height: 1.3em
font-weight: 300
@for $i from 1 through 6
h#{$i}
@extend %headers
=media-query-base-font-size-change-generator-manual()
body
font-size: 1.2em
@media screen and (min-width: 680px)
body
font-size: 1.4em
@media screen and (min-width: 1224px)
body
font-size: 1.6em
@media screen and (min-width: 1400px)
body
font-size: 1.8em
=h1p-font-size-generator-auto($h1-fs: 3em, $h1-step-down: 0.3, $body-min-font-size: 1.2em, $p-same-as-hx: 6)
$h1-fs: $h1-fs // Set first header element to this size
$h1-step-down: $h1-step-down // Decrement each time by 0.3
$p-same-as-hx: $p-same-as-hx // Set p font-sieze same as h(6)
$h1-fs: $h1-fs + $h1-step-down // Looping correction
@for $i from 1 through 6
h#{$i}
font-size: $h1-fs - ($h1-step-down * $i)
@if $i == $p-same-as-hx
p
font-size: $h1-fs - ($h1-step-down * $i)
// RUN ONLY THIS MIXIN. IT WILL TRIGGER THE REST
=config-and-run-font-generator()
+font-h1p-style-generator-manual() // Just a place holder for our font style
+media-query-base-font-size-change-generator-manual() // Just a placeholder for our media query font size
+h1p-font-size-generator-auto($h1-fs: 2em, $h1-step-down: 0.2, $p-same-as-hx: 5) // Set all parameters here
CONFIGURE ALL MIXINS TO YOUR NEEDS - PLAY WITH IT! :) AND THEN CALL IT ON THE TOP OF YOUR ACTUAL SASS CODE WITH:
+config-and-run-font-generator()
This would generate this output. You can customize parameters to generate different sets of results. However, because we all use different media queries, some mixins you will have to edit manually (style and media).
GENERATED CSS:
body {
font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 100%;
line-height: 1.3em;
word-wrap: break-word; }
h1, h2, h3, h4, h5, h6 {
line-height: 1em;
font-weight: 700; }
p {
line-height: 1.3em;
font-weight: 300; }
body {
font-size: 1.2em; }
@media screen and (min-width: 680px) {
body {
font-size: 1.4em; } }
@media screen and (min-width: 1224px) {
body {
font-size: 1.6em; } }
@media screen and (min-width: 1400px) {
body {
font-size: 1.8em; } }
h1 {
font-size: 2em; }
h2 {
font-size: 1.8em; }
h3 {
font-size: 1.6em; }
h4 {
font-size: 1.4em; }
h5 {
font-size: 1.2em; }
p {
font-size: 1.2em; }
h6 {
font-size: 1em;
}
One way to solve the problem of the text to look good on both desktop and mobile/tablet is in fixing the text size to physical units like physical centimeters or inches, which don't depend on the screen PPI (points per inch).
Based on this answer, below is the code I use at the end of the HTML document for a responsive font size:
<div id='testdiv' style='height: 1in; left: -100%; position: absolute; top: -100%; width: 1in;'></div>
<script type='text/javascript'>
var devicePixelRatio = window.devicePixelRatio || 1;
dpi_x = document.getElementById('testdiv').offsetWidth * devicePixelRatio;
dpi_y = document.getElementById('testdiv').offsetHeight * devicePixelRatio;
function setFontSizeForClass(className, fontSize) {
var elms = document.getElementsByClassName(className);
for(var i=0; i<elms.length; i++) {
elms[i].style.fontSize = String(fontSize * dpi_y / 96) + "px";
}
}
setFontSizeForClass('h1-font-size', 30);
setFontSizeForClass('action-font-size', 20);
setFontSizeForClass('guideline-font-size', 25);
// etc for your different classes
</script>
In the code above the items of a different class are assigned font sizes in physical units, as long as the browser/OS is configured correctly for the PPI of its screen.
A physical-unit font is always not too large and not too small, so long as the distance to the screen is usual (book-reading distance).
I have found this solution, and it works very well for me:
/* Fluid font size:
minimum font size at min. device width 300px = 14
maximum font size at max. device width 1600px = 26
*/
body {
font-size: calc(14px + (26 - 14) * ((100vw - 300px) / (1600 - 300)));
}
There are the following ways by which you can achieve this:
These units will autoresize depending upon the width and height of the screen.
After many conclusions I ended up with this combination:
@media only screen and (max-width: 730px) {
h2 {
font-size: 4.3vw;
}
}
Use this equation:
calc(42px + (60 - 42) * (100vw - 768px) / (1440 - 768));
For anything larger or smaller than 1440 and 768, you can either give it a static value, or apply the same approach.
The drawback with vw solution is that you cannot set a scale ratio, say a 5vw at screen resolution 1440 may end up being 60px font-size, your idea font size, but when you shrink the window width down to 768, it may ended up being 12px, not the minimal you want.
With this approach, you can set your upper boundary and lower boundary, and the font will scale itself in between.
I am afraid there isn't any easy solution with regards to font resizing. You can change the font size using a media query, but technically it will not resize smoothly. For an example, if you use:
@media only screen and (max-width: 320px){font-size: 3em;}
your font-size
will be 3em both for a 300 pixels and 200 pixels width. But you need lower font-size
for 200px width to make perfect responsive.
So, what is the real solution? There is only one way. You have to create a PNG image (with a transparent background) containing your text. After that you can easily make your image responsive (for example: width:35%; height:28px). By this way your text will be fully responsive with all devices.
Use CSS media
specifiers (that's what they [zurb] use) for responsive styling:
@media only screen and (max-width: 767px) {
h1 {
font-size: 3em;
}
h2 {
font-size: 2em;
}
}
I had just come up with an idea with which you only have to define the font size once per element, but it is still influenced by media queries.
First, I set the variable "--text-scale-unit" to "1vh" or "1vw", depending on the viewport using the media queries.
Then I use the variable using calc() and my multiplicator number for font-size:
/* Define a variable based on the orientation. */_x000D_
/* The value can be customized to fit your needs. */_x000D_
@media (orientation: landscape) {_x000D_
:root{_x000D_
--text-scale-unit: 1vh;_x000D_
}_x000D_
}_x000D_
@media (orientation: portrait) {_x000D_
:root {_x000D_
--text-scale-unit: 1vw;_x000D_
}_x000D_
}_x000D_
_x000D_
_x000D_
/* Use a variable with calc and multiplication. */_x000D_
.large {_x000D_
font-size: calc(var(--text-scale-unit) * 20);_x000D_
}_x000D_
.middle {_x000D_
font-size: calc(var(--text-scale-unit) * 10);_x000D_
}_x000D_
.small {_x000D_
font-size: calc(var(--text-scale-unit) * 5);_x000D_
}_x000D_
.extra-small {_x000D_
font-size: calc(var(--text-scale-unit) * 2);_x000D_
}
_x000D_
<span class="middle">_x000D_
Responsive_x000D_
</span>_x000D_
<span class="large">_x000D_
text_x000D_
</span>_x000D_
<span class="small">_x000D_
with one_x000D_
</span>_x000D_
<span class="extra-small">_x000D_
font-size tag._x000D_
</span>
_x000D_
In my example I only used the orientation of the viewport, but the principle should be possible with any media queries.
As with many frameworks, once you "go off the grid" and override the framework's default CSS, things will start to break left and right. Frameworks are inherently rigid. If you were to use Zurb's default H1 style along with their default grid classes, then the web page should display properly on mobile (i.e., responsive).
However, it appears you want very large 6.2em headings, which means the text will have to shrink in order to fit inside a mobile display in portrait mode. Your best bet is to use a responsive text jQuery plugin such as FlowType and FitText. If you want something light-weight, then you can check out my Scalable Text jQuery plugin:
http://thdoan.github.io/scalable-text/
Sample usage:
<script>
$(document).ready(function() {
$('.row .twelve h1').scaleText();
}
</script>
If you don't mind to use a jQuery solution you can try TextFill plugin
jQuery TextFill resizes text to fit into a container and makes font size as big as possible.
h1 { font-size: 2.25em; }
h2 { font-size: 1.875em; }
h3 { font-size: 1.5em; }
h4 { font-size: 1.125em; }
h5 { font-size: 0.875em; }
h6 { font-size: 0.75em; }
If you are using a build tool then try Rucksack.
Otherwise, you can use CSS variables (custom properties) to easily control the minimum and maximum font sizes like so (demo):
* {
/* Calculation */
--diff: calc(var(--max-size) - var(--min-size));
--responsive: calc((var(--min-size) * 1px) + var(--diff) * ((100vw - 420px) / (1200 - 420))); /* Ranges from 421px to 1199px */
}
h1 {
--max-size: 50;
--min-size: 25;
font-size: var(--responsive);
}
h2 {
--max-size: 40;
--min-size: 20;
font-size: var(--responsive);
}
The "vw" solution has a problem when going to very small screens. You can set the base size and go up from there with calc():
font-size: calc(16px + 0.4vw);
I use these CSS classes, and they make my text fluid on any screen size:
.h1-fluid {
font-size: calc(1rem + 3vw);
line-height: calc(1.4rem + 4.8vw);
}
.h2-fluid {
font-size: calc(1rem + 2vw);
line-height: calc(1.4rem + 2.4vw);
}
.h3-fluid {
font-size: calc(1rem + 1vw);
line-height: calc(1.4rem + 1.2vw);
}
.p-fluid {
font-size: calc(1rem + 0.5vw);
line-height: calc(1.4rem + 0.6vw);
}
You can use the viewport value instead of ems, pxs, or pts:
1vw = 1% of viewport width
1vh = 1% of viewport height
1vmin = 1vw or 1vh, whichever is smaller
1vmax = 1vw or 1vh, whichever is larger
h1 {
font-size: 5.9vw;
}
h2 {
font-size: 3.0vh;
}
p {
font-size: 2vmin;
}
From CSS-Tricks: Viewport Sized Typography
I can say my method has the best approach to solve your problem
h1{
font-size : clamp(2rem, 10vw, 5rem);
}
here clamp
has 3 arguments.
first one is the minimum allowed font-size.
third one is the maximum allowed font-size.
second argument is font-size that you wish to always have. Its unit must be relative(vw, vh, ch) and not absolute(i.e not px, mm, pt). relative unit will make it change its size w.r.t the changing screen sizes.
Consider an example : consider there is a large fontawesome icon that you want to resize dynamically (responsive icon)
fa-random-icon{
font-size: clamp( 15rem, 80vw, 80vh)
}
i.e.
if in a particular mobile screen size if 80vw < 15rem then font-size is 15rem.
if screen is too wide then if 80vw > 80vh then font-size is 80vh.
Those methods above suggested by people always have a bit uncertain result... like when we use
vw
only, the font size might sometimes be too big or too small (unbounded).
using
media
queries are too old school.
Source: Stackoverflow.com