css responsive fluid html font size based on rem - html

I want to implement the example from css-tricks based on rems. This is what I got so far. However, the scaling does not work as intended, and the font size increases only tiny amounts. What is the mistake?
html {
font-size: 1rem;
}
#media screen and (min-width: 320px) {
html {
font-size: calc(1rem + 2 * ((100vw - 20rem) / 680));
}
}
#media screen and (min-width: 1000px) {
html {
font-size: 3rem;
}
}
I assume that 2 * ((100vw - 20rem) / 680) returns a px value. If that's true. How can I change it to return rem instead?
Edited to add some clarifications:
I want to use rem instead of px because this allows the user to overwrite the default font size in the browser.
The term 2 * ((100vw - 20rem) / 680) is between 0 and 2 (1 rem equals 16px on normal font size). This is what I want to achieve. I want to have font-size: 1rem + [0, 2]rem between 320 and 1000px viewport width. A linearly increasing rem function based on the viewport width.
Here is a link to a sandbox example.
Edit 2:
I think what I want to achieve is not possible. If the user increases the default font size by 50%, I want the scaling factor also increase by 50%: font-size: 1rem + [0, 2 * 1.5]rem.
The current problem is that the part 2 * ((100vw - 20rem) / 680)) needs to be rem based. This is not possible because there is no way in CSS to strip the unit. If I could strip the unit, I could do this: 2rem * strip-unit((100vw - 20rem) / 680))

If you want a responsive font size then you can use View Width too, no need to use calc or rem for that.
Just change this so you can try it out:
HTML {
font-size: 5vw;
}
View width goes from 0 to 100 so you know how much room you have to work with.
edit: I personally haven't found out how to scale on both axis yet but just the X-axis works good enough in most cases.

Here is a solution for fluid fonts I got from Creating a Fluid Type Scale with CSS Clamp
After some tweaking I ended up with the following Sass code to generate the clamp function.
/*
From https://www.aleksandrhovhannisyan.com/blog/fluid-type-scale-with-css-clamp/
Generates the css clamp function.
Focused on font-size, but may be used for margins and padding
Usage:
clamped(min-size-px, max-size-px, min-browser-width-px, max-browser-width-px)
font-size: clamped(26px, 36px, 600px, 1200px);
font-size: clamped(26px, 36px); //using width default values
Output:
font-size: clamp(1.63rem, 1.11vw + 1.28rem, 2.25rem);
*/
#use "sass:math";
#use "sass:map";
// Default min-mix browser width values for clamped function
$default-min-bp: 500px;
$default-max-bp: 1400px;
// Convert pixels to rems.
#function to-rems($px) {
$rems: math.div($px, 16px) * 1rem;
#return $rems;
}
//round a to number of decimal places.
#function rnd($number, $places: 0) {
$n: 1;
#if $places > 0 {
#for $i from 1 through $places {
$n: $n * 10;
}
}
#return math.div(math.round($number * $n), $n);
}
// Generate css for clamp
#function clamped($min-px, $max-px, $min-bp: $default-min-bp, $max-bp: $default-max-bp) {
$slope: math.div($max-px - $min-px, $max-bp - $min-bp);
$slope-vw: rnd($slope * 100, 2);
$intercept-rems: rnd(to-rems($min-px - $slope * $min-bp), 2);
$min-rems: rnd(to-rems($min-px), 2);
$max-rems: rnd(to-rems($max-px), 2);
#return clamp(#{$min-rems}, #{$slope-vw}vw + #{$intercept-rems}, #{$max-rems});
}

Related

How to fetch aspect ratio within HTML and CSS?

Responsive website depends on #media queries which takes value in terms of pixels or screen type.
Is there a way to set media query using aspect ratio of the screen that is being used? How?
Also how to fetch or calculate the aspect ratio of the current screen on which the web page is being displayed from HTML and CSS?
Sadly there's no such thing in CSS like sw or sh to get the screen width / height.
JS to the rescue!
Use JS's screen.width and screen.height
Use CSS aspect-ratio property
Calculate the aspect-ratio: sw/sh : 1
const set_AR = (el) => el.style.aspectRatio = screen.width / screen.height;
set_AR(document.querySelector("#emulator"));
#emulator {
--scale: 0.6;
max-width: calc(100vw * var(--scale));
max-height: calc(100vh * var(--scale));
background: #000;
}
<div id="emulator"></div>

How can i work with negative and percentage values in css calc? (Fluid Design)

I found this awesome css calc function from css-tricks
calc([minimum size] + ([maximum size] - [minimum size]) * ((100vw - [minimum viewport width]) / ([maximum viewport width] - [minimum viewport width])));
I try to use this calc function like this for margin-right
margin-right: calc(-20% + (0 - -20) * ((100vw - 320px) / (1600 - 320)));
I wanted to achieve the following:
-20% at 320px viewport width
0% at 1600px viewport width
The css calc function works perfectly with positive values, but apparently not with negative values. How do I change the calc function to work with percentages and negative values?
I tried this
margin-right: calc(-20% + (0% - -20%) * ((100vw - 320px) / (1600 - 320)));
but this is invalid.
Background
I am using this js function to calculate ranges
function _translateRange(
input,
inputMin,
inputMax,
outputMin,
outputMax
) {
let inputMinA = Math.min(inputMin, input);
let inputMaxA = Math.max(inputMax, input);
return (
outputMin +
((outputMax - outputMin) * (input - inputMinA)) /
(inputMaxA - inputMinA)
);
};
like this
translateRange(window.innerWidth, 320, 1400, -45%, 0%)
I want to convert this function to a css calc function. Why? Why do I not use the js function to calculate margin-right? Because I want to do without as much js as possible in my application.
Note: This flexibility is especially important for me because I also want to work with as few media queries as possible.
Edit
I restructured my css code. I configure my absolute element, so i can use positive px values at begin and end with 0. So in this way, the css calc function works as i aspected.

How to calculate font size in point(pt) for responsive view when window resized

I tried the css below
--max-font: 16;
--min-font: 12;
--responsive: calc((var(--min-font) * 1px) + (var(--max-font) - var(--min-font)) * ((100vw - 420px) / (1200 - 420)));
font-size: var(--responsive);
It displayed well on site view, but when printing the font goes small. How can i calculate it in point(pt) format for font size using this formula? Thanks.
First, work out the width of each unit of measurement relative to a third:
1px = 1/96th of 1 inch
1pt = 1/72nd of 1 inch
Then you can use this difference to work out their relation to one another:
1pt = (1px * 96) / 72
1pt = 1.3**px
That's how you can calculate the font size... but why not simply just replace px with pt in your code? That's much simpler than doing the calculation on the fly:
--max-font: 16;
--min-font: 12;
--responsive: calc((var(--min-font) * 1pt) + (var(--max-font) - var(--min-font)) * ((100vw - 420pt) / (1200 - 420)));
font-size: var(--responsive);

Foundation 6.2 Large Gutter Size

According to Foundation 6.2 documentation default grid gutter size for small is 20px and for medium is 30px, but did not mention for large. What is the default gutter size for large?
Looking at _grid.scss on the Foundation GitHub page:
/// The amount of space between columns at different screen sizes. To use just one size, set the variable to a number instead of a map.
/// #type Map | Length
/// #since 6.1.0
$grid-column-gutter: (
small: 20px,
medium: 30px,
) !default;
and _column.scss:
// Gutters
#if type-of($gutter) == 'map' {
#each $breakpoint, $value in $gutter {
$padding: rem-calc($value) / 2;
#include breakpoint($breakpoint) {
padding-left: $padding;
padding-right: $padding;
}
}
}
There is no large gutter defined as the docs say. So in this case large gutters would be the same as medium since Foundation uses mobile first.
You could add a custom large gutter by doing something like this:
$grid-column-gutter: (
small: 20px,
medium: 30px,
large: 50px
) !default;

How to set min-font-size in CSS

I want to set a minimum font size to every element in my HTML page.
For example if there are elements with font-size less then 12px, then they will change to 12px.
But if there are elements with font-size grater then 12px, they will not change.
Is there any way to do it with CSS?
In CSS3 there is a simple but brilliant hack for that:
font-size:calc(12px + 1.5vw);
This is because the static part of calc() defines the minimum. Even though the dynamic part might shrink to something near 0.
As of mid-December 2019, the CSS4 min/max-function is exactly what you want:
(tread with care, this is very new, older browsers (aka IE & msEdge) don't support it just yet)
(supported as of Chromium 79 & Firefox v75)
https://developer.mozilla.org/en-US/docs/Web/CSS/min
https://developer.mozilla.org/en-US/docs/Web/CSS/max
Example:
blockquote {
font-size: max(1em, 12px);
}
That way the font-size will be 1em (if 1em > 12px), but at least 12px.
Unfortunatly this awesome CSS3 feature isn't supported by any browsers yet, but I hope this will change soon!
Edit:
This used to be part of CSS3, but was then re-scheduled for CSS4.
As per December 11th 2019, support arrived in Chrome/Chromium 79 (including on Android, and in Android WebView), and as such also in Microsoft Chredge aka Anaheim including Opera 66 and Safari 11.1 (incl. iOS)
CSS has a clamp() function that holds the value between the upper and lower bound.
The clamp() function enables the selection of the middle value in the range of values between the defined minimum and maximum values.
It simply takes three dimensions:
Minimum value.
List item
Preferred value Maximum allowed value.
try with the code below, and check the window resize, which will change the font size you see in the console. i set maximum value 150px and minimum value 100px.
$(window).resize(function(){
console.log($('#element').css('font-size'));
});
console.log($('#element').css('font-size'));
h1{
font-size: 10vw; /* Browsers that do not support "MIN () - MAX ()" and "Clamp ()" functions will take this value.*/
font-size: max(100px, min(10vw, 150px)); /* Browsers that do not support the "clamp ()" function will take this value. */
font-size: clamp(100px, 10vw, 150px);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<center>
<h1 id="element">THIS IS TEXT</h1>
</center>
Looks like I'm a bit late but for others with this issue try this code
p { font-size: 3vmax; }
use whatever tag you prefer and size you prefer (replace the 3)
p { font-size: 3vmin; }
is used for a max size.
Use a media query. Example:
This is something im using the original size is 1.0vw but when it hits 1000 the letter gets too small so I scale it up
#media(max-width:600px){
body,input,textarea{
font-size:2.0vw !important;
}
}
This site I m working on is not responsive for >500px but you might need more. The pro,benefit for this solution is you keep font size scaling without having super mini letters and you can keep it js free.
.class {
font-size: clamp(minimum-size, prefered-size, maximum-size)
}
using this you could set it up so prefered and max values are 5vw but the minimum is 15px or something so it won't go over 5vw but if 5vw < 15px it will stick to 15px
CSS Solution:
.h2{
font-size: 2vw
}
#media (min-width: 700px) {
.h2{
/* Minimum font size */
font-size: 14px
}
}
#media (max-width: 1200px) {
.h2{
/* Maximum font size */
font-size: 24px
}
}
Just in case if some need scss mixin:
///
/// Viewport sized typography with minimum and maximum values
///
/// #author Eduardo Boucas (#eduardoboucas)
///
/// #param {Number} $responsive - Viewport-based size
/// #param {Number} $min - Minimum font size (px)
/// #param {Number} $max - Maximum font size (px)
/// (optional)
/// #param {Number} $fallback - Fallback for viewport-
/// based units (optional)
///
/// #example scss - 5vw font size (with 50px fallback),
/// minumum of 35px and maximum of 150px
/// #include responsive-font(5vw, 35px, 150px, 50px);
///
#mixin responsive-font($responsive, $min, $max: false, $fallback: false) {
$responsive-unitless: $responsive / ($responsive - $responsive + 1);
$dimension: if(unit($responsive) == 'vh', 'height', 'width');
$min-breakpoint: $min / $responsive-unitless * 100;
#media (max-#{$dimension}: #{$min-breakpoint}) {
font-size: $min;
}
#if $max {
$max-breakpoint: $max / $responsive-unitless * 100;
#media (min-#{$dimension}: #{$max-breakpoint}) {
font-size: $max;
}
}
#if $fallback {
font-size: $fallback;
}
font-size: $responsive;
}
A recent feature added to CSS is min() which chooses the minimum value of its parameters.
So in the following code, when the viewport is big (>1500px in this case), the font-size is capped to 30px.
However for any viewport smaller than 1500px, the other value is used: e.g. when viewport is 1000px, then the font-size will be 20px. This means it can be quite responsive.
p {
font-size: min(2vw, 30px);
}
Here's a Codepen with min() for container width and p text:
https://codepen.io/code0312/pen/dyWJLmB
But note, if you later manually set a font size greater than what you put here, that will still override this declaration.
No. While you can set a base font size on body using the font-size property, anything after that that specifies a smaller size will override the base rule for that element. In order to do what you are looking to do you will need to use Javascript.
You could iterate through the elements on the page and change the smaller fonts using something like this:
$("*").each( function () {
var $this = $(this);
if (parseInt($this.css("fontSize")) < 12) {
$this.css({ "font-size": "12px" });
}
});
Here is a Fiddle where you can see it done: http://jsfiddle.net/mifi79/LfdL8/2/
AFAIK it's not possible with plain CSS,
but you can do a pretty expensive jQuery operation like:
jsBin demo
$('*').css('fontSize', function(i, fs){
if(parseInt(fs, 10) < 12 ) return this.style.fontSize = "12px";
});
Instead of using the Global Selector * I'd suggest you (if possible) to be more specific with your selectors.
Judging by your above comment, you're OK doing this with jQuery — here goes:
// for every element in the body tag
$("*", "body").each(function() {
// parse out its computed font size, and see if it is less than 12
if ( parseInt($(this).css("font-size"), 10) < 12 )
// if so, then manually give it a CSS property of 12px
$(this).css("font-size", "12px")
});
A cleaner way to do this might be to have a "min-font" class in your CSS that sets font-size: 12px, and just add the class instead:
$("*", "body").each(function() {
if ( parseInt($(this).css("font-size"), 10) < 12 )
$(this).addClass("min-font")
});
The font-min-size and font-max-size CSS properties were removed from the CSS Fonts Module Level 4 specification (and never implemented in browsers AFAIK). And the CSS Working Group replaced the CSS examples with font-size: clamp(...) which doesn't have the greatest browser support yet so we'll have to wait for browsers to support it. See example in https://developer.mozilla.org/en-US/docs/Web/CSS/clamp#Examples.
It will work perfectly with 50px. Which will act as a static and thus as min-width.
font-size: calc(50px + 5vw);