How to implement fluid font size using pure CSS - html

I have text wrapped in <div>s, and would like to make the whole thing fluid including the font-size of the text, i.e. the text resizes itself in response to the size of the containing element.
I came across a Javasript + CSS solution, but just wondering if it is possible to do so with pure CSS?

While Jim has given you accurate information, it strays from the question asked slightly. Responsive design (#media queries) can alter the text according to screen size. From what I understand, you were asking if there is a pure CSS solution for fluid text size (continual resizing of text during window size changes).
Here is a link to css-tricks explanation of new font sizing techniques. Please be aware this is new and older browsers will most likely have some issues, and that even newer ones (Chrome + Safari) are still not bug-free.
h1 {
font-size: 5.9vw;
}
h2 {
font-size: 3.0vh;
}
p {
font-size: 2vmin;
}
Edit- added code

Yes, look at CSS 3 media queries. You can provide different style rules depending on the viewport width. This includes altering the font size.

Short Answer
You can't have fluid font sizes, but you will when viewport-percentage lengths are widely available.
Long Answer
You have to understand these two terms: responsive and fluid.
Responsive means you make your stylesheet respond differently to different window sizes. This is done by using CSS Media Queries. While responsive is one of the hippest words in web design, it mostly means hardcoding CSS for different absolute lengths until you drop dead of boredom.
Fluid means you work with relative length units such as percentages. When you work with relative length units, every size is calculated automagically.
Example
Let's say you have a <div> inside the document body and you want it to fill half of the window.
The responsive solution is this:
#media (max-width: 1px) {
body > div {
width: 0.5px;
}
}
#media (max-width: 2px) {
body > div {
width: 1px;
}
}
#media (max-width: 3px) {
body > div {
width: 1.5px;
}
}
#media (max-width: 4px) {
body > div {
width: 2px;
}
}
/* Repeat until you reach gigabytes and hit operating systems' file size limitations. */
And the fluid solution:
body > div {
width: 50%;
}
So?
What limits us today is that there is no wide support for viewport-relative length units. What you can do is drop the whole idea of "pure CSS fluid font sizes" and go responsive.

use calc with media query for a responsive and fluid font
#media screen and (min-width: 25em){
div {
font-size: calc( 16px + (24 - 16) * (100vw - 400px) / (800 - 400) );
}
}

Related

using #media queries for media compatibility

I don't believe I'm grasping how to create a responsive website. this is my code:
body{
width: 100%;
font-size: 16px;
background-color: grey;
}
h1{
color:black;
}
p{
color:black;
}
#media only screen and(min-width:320px)and(max-width:420px){
h1{
color:red;
}
p{
color: white;
}
}
my goal with this small css edit was to see if I understood how the media query worked and to change the h1 and p element colors when a screen size is in-between mobile size.
however, regardless of what size the screen is, there is no changes the elements. I'm slightly confused because I've seen videos of people using this as an example.
You have the right order of things, normals rules first and then mobile rules afterwards.
Let's say you have two buttons on the screen for a desktop and a phone. Because a mobile phone obviously does not have the width to spare you may want to show the buttons above and below each other instead of side-by-side.
I have a phone with a horizontal screen width of 375px. If the buttons are rendered as 250px then they blatantly won't render side-by-side on my phone without clipping and therefore looking messy to visitors.
Take this code in to consideration:
input[type='button'] {display: inline-block; width: calc(50% - 8px);}
#media (max-width: 1024px)
{
input[type='button'] {width: calc(100% - 8px);}
}
The button input elements are set to use (roughly) 50% width (compensating a bit for border and margin). Since they are inherently display: inline; I'm using display: inline-block to keep them rendering on the same line (no line breaks for outright block rendering) though allow setting the width hence inline-block.
The media queries do not negate something like display unless it's explicitly defined, again so all the input buttons are still rendered as inline-block. But now on a mobile screen these buttons will use up enough space that they'll push each other to separate lines.

Logo Height not responsive

The "rh" logo on my site is responsive vertically, ie fits perfectly to a tall thin window, but does not resize to a wide short window. Could anyone help me make the logo responsive to both width and height?
here is the website... (takes a bit to load up)
http://rhwebdesign.co.uk/
Here is my CSS:
img {
height: auto;
max-width: 100%;
vertical-align: middle;
}
To be very specific and address your questions about the logo, consider setting the max-height relative to the window's height.
You have:
img {
height: auto;
max-width: 100%;
vertical-align: middle;
}
.hero-logo img {
max-width: 100%;
min-height: 100%;
padding: 20px;
}
In order to scale the logo, add in to the latter block:
max-height: 100vh;
This sets the images maximum height to 100% of the viewport height, which appears to be what you desire here. Note that there is some text beneath it, which is not displayed, since it is text wrapped in an H5. These two lines are 68px tall (40px padding plus 28px for the text). So, you can adjust the above to:
max-height: calc(100vh - 68px);
It looks like in landscape mode (480x320), there is a script not calculating the size of margin correctly.
<div class="container hero-content" style="margin-top: -97.5px;">
have a look in main.js for this function:
heroContent.css({
"margin-top" : topContentMargin+"px"
});
Which is this:
topContentMargin = (heroHeight - contentHeight) / 2,
heroHeight = windowHeight,
contentHeight = heroContent.height(),
I haven't really looked into why it is calulating it incorrectly. My guess is that heroContent is too high for landscape mode because the image becomes 441px high with the media query max-width:100%. So it tries to add a negative margin to compensate.
My advice would be to remove the jQuery calculation of the hero content sizing and apply sizes using css and media queries only.
Edit:
You need to be more specific with your css. Learn some more about css specifity. You should include your largest media queries at the top, so the smaller ones will take precedence at the bottom. Makes things easier. Also IMHO, I wouldn't use queries for anything larger than iPad. ie. 1024px. Although you should always test on newer devices if possible.
You will need to specify the height of the video for each specific device size. I can't tell now, but maybe jquery was determining the section heights, so now the css is determining the video height.
So at the bottom of your style sheet, try this.
div#bgVideo.skrollable.skrollable-between video#video_background {
min-height:940px !important;
}
#media (max-width: 480px) {
.hero-logo img {
max-width:55%; /*looks nice at 480 */
padding:20px;
}
div#bgVideo.skrollable.skrollable-between video#video_background {
min-height:320px !important;
}
}
#media (max-width: 320px) {
div#bgVideo.skrollable.skrollable-between video#video_background {
min-height:480px !important;
}
}
But Richard, to be honest, you should be troubleshooting and testing the design yourself. How will you ever learn if you don't try. Remember, firebug is your best friend :)

Scale Up/Down all Elements, Images, Text when browser window width is changed

Is there a way to scale down/up all elements including texts, images, etc. depending on the browser width? It is like 'zooming out' using your browser just to avoid the browser horizontal scrollbar.
You can resize images and video with just this css rule.
img, video { max-width: 100%; }
For text, you can work with em's to adjust to the viewport and resolution. You should also set the font size on the html and body element
html {
font-size: 100%;
}
body {
font-size: 1em;
}
/* Adjust the font size here to upscale the font when you've resized the page to 700px */
#media screen and (max-width: 700px) {
html { font-size: 110%; }
}
If you're actually thinking about literally zooming in/out for certain viewports, just use media queries. Like this:
#media all and (max-width: 700px) and (min-width: 400px) {
/* some funky stuff */
}
EXTRA
To smoothen the transition between different viewports, use this css property on the html tag
transition: all 1s ease;
Yes, though it requires JavaScript and doesn't work with all browsers, only those which support CSS zoom (which I know at least Firefox does not). How I do it, is say the standard non-zoomed page width is 1024, I use jQuery with the line
$("html").css("zoom",window.innerWidth/1024);
every time the window is resized (using window.onresize). The site I'm using it on is still non-public so I can't show you the example, but it works pretty well.

Implementing a page from psd proportionally

When I get a psd(1750*2400),I found the images and font size were too big for lower resolution.Is it possible to make page fit in different resolution ? Thanks.
I usually divide this into 2. What I mean is that the dimension of the website, in this situation, is 875x1200. Thus for every spec, such as fonts, block width, image width should be divided into 2.
For example, the Header font size is 42px then you could apply 21px.
For images you can do this purely with CSS by specifying the width and height of your preference. The browser will resize the image (though if you don't choose the right aspect-ratio the image may look obviously expanded or compressed).
img {
height: 300px; //whatever height you want
width: 200px //whatever width you want
}
For a responsive layout you can use CSS3 media queries to achieve the best look on different resolutions.
Example for responsive layouts:
img {
height: 100%;
width:100%
}
#media screen and (max-width:64em) {
height: 70%;
width: 70%
}
As for the font-size, you may have to sacrifice pixel-perfection at times for the best look and decide for yourself whether the font looks appropriate for the display or not.
This too can be controlled by using media queries though:
#media screen and (max-width: 32em) {
font-size: 1.5em
}

Can I set font-size relative to page size?

Is there a way to make font-size relative to the size of the page? Applying percentage as unit refers to the standard font size (like 90% of 12px, not 90% of the page!). This is different from the behaviour of most of the other tags.
Any way to make the page 'scale up and down' also with fonts? Should I rely on em?
Thanks
See the new vh and vw CSS units. Browser support isn't great yet.
http://snook.ca/archives/html_and_css/vm-vh-units
It landed in WebKit recently:
https://bugs.webkit.org/show_bug.cgi?id=27160
In browsers that support it, 1 vh is 1% (1/100) of the viewport height, and 1 vw is 1% (1/100) of the viewport width. There are also vmin and vmax units, which represent the smaller of the two and the larger of the two, respectively.
No you cannot set the size of the font in a percentage relative to the size of the page.
Sizing in em is based on the size relative to how the font would normally render in 16 point.
If you'd like your page to scale up and down and keep some sort of scale to itself, the boxes and the font, then setting it out in em would be fine.
That method will allow for the scaling of fonts and boxes of the page to grow at a relative size to one another and hopefully not have things falling out of bounds and borders.
Try a jQuery plugin like FitText. It automatically sizes text to fit the width of the parent element.
Another jQuery plugin with the same goal is BigText (demo).
Heres a little script I made for exacly that (use it as a fallback when vw isnt supported)
https://gist.github.com/2475269
Another non-ideal answer is to use a series of css breakpoints like so:
h1 { font-size: 22px; color: orange; }
#media only screen and (max-width: 900px) {
h1 { font-size: 20px; color: blue; }
}
#media only screen and (max-width: 800px) {
h1 { font-size: 18px; color: green; }
}
#media only screen and (max-width: 700px) {
h1 { font-size: 12px; color: red; }
}
http://jsfiddle.net/8RKhp/
In my view, the range of apparent pixel densities seen by the viewer of a webpage is now massive, from an HTC One held at 12 inches from the face, where there are 5600 pixels/radians to perhaps a 50 inch plasma screen running at 480p, which is about 950 pixels/radians at 4 feet.
Or put it another way a 20px font is nearly 6x bigger in your field of view on that plasma screen than the latest handset.
The solution I cooked up was to set the body font size in absolute pixels as a multiple of the window.screenWidth but constrain it to a minimum an maximum number of units, then use em's for all font sizes after that. The em's+proper use of headings should mean accessibility is fine.
I add this function to the page (or it's JS) to set the size:
function setFontSize() {
pagesized = window.innerWidth / 30; // Proportionate font size to page
pagesized = Math.max(pagesized, 14); // Set size to be no less than 14 px
pagesized = Math.min(pagesized, 30); // & No greater than 30 px
document.body.style.fontSize = pagesized; // Set body default font size
}
To make this work the following is added to the body tag:
<body onresize="setFontSize()" onload="setFontSize()">
You then just use your CSS (or inline formatting) all based on % or em units and things should scale nicely within those bounds.
Or, in JQuery, you can do:
$(window).resize(function() {
pagesized = $(window).innerWidth() / 30; // Proportionate font size to page
pagesized = Math.max(pagesized, 14); // Set size to be no less than 14 px
pagesized = Math.min(pagesized, 30); // & No greater than 30 px
$('body').css('font-size', pagesized); // Set body default font size
});
At least for Firefox, 1em can be used to set the font size related to the font size of the parent. So if you set font-size of body to a value that is in ratio to the size of the page. All fonts under body that use 'em' as unit will be in relation to the page.
To do that, you must set the size of the body in relation to the page like height: 100% or width if you want to relate the size to the width.
Then, you will have to constantly synchronize the body height with the font size. This can be done with 'onResize'.
See more detail in the following link.
I recommend you use YUI reset to unify the font rendering across different browsers. Then check YUI Font Size. After this you can rely on your fonts to display correctly.
You can solve it like this:
jQuery(document).ready(function ($) {
// Dynamisches Skalieren von Schriften
fontSize = function(){
//ww = $(window).innerWidth();
ww = $('.mainhead').innerWidth(); // Width of the Motherelement
one = ww/100; // 1%
multiplcator = one*31;
$('.mainhead').css({'font-size': multiplcator+'px'});
}
fontSize();
$(window).resize(function() {
fontSize();
});
});
When you now set your Fontsize via css it wokes on all browsers like charm
.mainhead{
width:48%;
font: normal 2em Times, Verdana, sans-serif;
}
I know it's already been answered, but i need to share this for future comers, because it took me some precious minutes to figure this out.
So as mr #random said: em as a unit, will do the trick.
If you'd like your page to scale up and down and keep some sort of scale to itself, the boxes and the font, then setting it out in em would be fine.
That method will allow for the scaling of fonts and boxes of the page to grow at a relative size to one another and hopefully not have things falling out of bounds and borders.
Initialise your body with 1em as font-size that means 100%
body {
font-size: 1em;
}
Then set your element's font-size as a percentage of it's parent's
.your_element {
font-size:0.4em /* for example 40% if its parent font-size */
}
Now the magic of #media queries
#media all and (max-width: 767px) {
body {
font-size: 0.4em !important;
}
}
#media all and (min-width: 768px) and (max-width: 1023px) {
body {
font-size: 0.6em !important;
}
}
#media all and (min-width: 1024px) and (max-width: 1199px) {
body {
font-size: 0.8em !important;
}
}
#media all and (min-width: 1200px) and (max-width: 1599px) {
body {
font-size: 1em !important;
}
}
#media all and (min-width: 1600px) and (max-width: 1999px) {
body {
font-size: 1.2em !important;
}
}
#media all and (min-width: 2000px) and (max-width: 2999px) {
body {
font-size: 1.6em !important;
}
}
#media all and (min-width: 3000px) and (max-width: 3999px) {
body {
font-size: 1.8em !important;
}
}
#media all and (min-width: 4000px) {
body {
font-size: 2em !important;
}
}
And Bingo, have a nice day.
When you say "relative to the size of the page", what exactly do you mean with "size of the page"?
The browser window? Then your fonts would change size when the user resizes the window - definitely not what anyone would expect, and pretty bad for usability. People don't resize windows to see a larger or smaller representation of the whole site, they enlarge them to see a larger section of the site, and make windows smaller to see a specific small section and have space for other windows next to the browser.
If you mean the size of the screen, that's even worse since it would mean huge fonts on a 30" screen. But people don't buy 30" screens so they can see huge fonts, they buy them to see multiple windows side by side.
All in all, using em or something similay is the only sensible way to make a scaleable website, since it will scale relative to the default size, which is/should be relative to what the user can comfortably read.