change fontsize on resize inside a div with javascript - javascript

I am fairly new with javascript, but i'm trying to lurn.
I have an image with a div container over the image. The div container contains 2 inner div for a Title and some text. THe font size of the title is bigger than the text.
My screen innerwidth that I use to work and develop is 768.
I want to have the javascript change the fontsize on load and on resize based on proportion of the browser window... so if the browser window is 30% larger... the font should be 30% larger then defined in the css... This is the code I made.. but it's not working.
<head>
<style type="text/css">
#container{
position: absolute;
top:10%;
left: 10%;
background-color:#F30;
}
#boxtitle{
font-size:3em;
}
#boxtxt{
font-size:0.9em;
}
</style>
<script>
onresize=onload=function()
{
var innerW = window.innerWidth;
var boxtitle = document.getElementById("boxtitle").style.fontSize;
var boxtxt = document.getElementById("boxtxt").style.fontSize;
var ratio = innerW / 768;
boxtitle = boxtitle * ratio;
boxtxt = boxtxt * ratio;
}
</script>
</head>
<body>
<img src="main_pic3.jpg" width="100%" />
<div id="container">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td><div id="boxtitle">TITLE</div></td>
</tr>
<tr>
<td><div id="boxtxt">TXT</div></td>
</tr>
</table>
</div>
</body>

You are setting the value of your variables to the font sizes (you are not storing references to the DOM elements.) Also, try using parseInt to make sure you get any strings out of your numbers.
Try:
var innerW = parseInt(window.innerWidth),
boxtxt = parseInt(document.getElementById("boxtxt").style.fontSize),
ratio = innerW / 768;
document.getElementById("boxtxt").style.fontSize = (boxtxt * ratio) + 'px'; //etc.
One thing to note (I haven't tested it in other browsers) is that in Firefox for Mac, style.fontSize only returns a font-size that's inline to an element, and not the font-size on your stylesheet.
So, an option is this:
function getStyle(object,prop) {
if(getComputedStyle) {
return getComputedStyle(object)[prop];
} else if (object.currentStyle) {
return object.currentStyle[prop]; //IE
}
}
//implement it
getStyle(document.getElementById('someElement'),'fontSize'); //for example, outputs 12px
One thing I want to point out is that if you try to multiply an empty string by a number (for example, if you use style.fontSize where there are no inline styles and multiply that [which is now an empty string] by an integer, such as your screen width [which in this case is 768]), it will output 0, which would set your font-size to 0, thus making it disappear:
console.log(document.getElementById('download').style.fontSize * 768);
//outputs 0
Additionally, I noticed you are using resize along with your onload handler. I might suggest putting resize inside your onload handler instead, unless you know that you won't be putting other code inside your onload handler (because this would cause lots of stuff to happen every single time the window is resized.)
Another option for handling font size based on screen size are CSS media queries (I suggest a Google search for that.)

onresize=onload=function()
{
var innerW = window.innerWidth;
var boxtitle = document.getElementById("boxtitle").style.fontSize;
var boxtxt = document.getElementById("boxtxt").style.fontSize;
var ratio = innerW / 768;
boxtitle = boxtitle * ratio; //<--- try appending px example below up to you how you append it
document.getElementById("boxtitle").style.fontSize = '100px'
boxtxt = boxtxt * ratio; //<--- try appending px
}

first of all, you have to store original values, otherwise you will be getting different font sizes on every resize
then, you just have to append it
onresize=onload=function()
{
var ratio = window.innerWidth / 768;
document.getElementById("boxtitle").style.fontSize = 3*ratio + 'em';
document.getElementById("boxtxt").style.fontSize = 0.9*ratio + 'em';
}
another approach is to use viewport based metrics - http://snook.ca/archives/html_and_css/vm-vh-units

How about using percentage for font sizes instead so everything stay proportional also. You just have to bound top level with font size that is not in percentage like in the example. Otherwise, you will have a nightmare trying to maintain so many font sizes in Javascript.
Here's an example: http://jsfiddle.net/yL89q/
HTML:
<div id="container">
<h1>Title</h2>
<div class="description">Description</div>
</div>
CSS:
#container{
font-size: 13px;
}
.container h1{
font-size: 150%;
}
.container .description{
font-size: 100%;
}
JS:
onresize=onload=function(){
var innerW = window.innerWidth;
var ratio = innerW / 768;
var boxtitle = Math.round(13 * ratio);
document.getElementById("container").style.fontSize = boxtitle + 'px';
}

Related

I need to position image at the bottom of the background image and have them stay in place when window is resized

I have a background image and I have other images that need to stay at the bottom of the background image, even if the window resizes or there is a different screen size.
This is a ReactJS web app so any javascript or CSS will work.
CSS:
html {
background: url(imageInMemory.png) no-repeat center center fixed;
background-size: contain;
}
Javascript:
// I calculate the ratio for 'background-size: contain'
let A = window.innerWidth;
let B = window.innerHeight;
let W = naturalWidth; // Width of image, I have this hardcoded
let H = naturalHeight; // Height of image, I have this hardcoded
const ratio = Math.min((A/W), (B/H));// this is the ratio to which the image was scaled given the current window size.
// I position images on top of background images where they should be using this new ratio
<div style={{marginTop: ratio * H * .7}}>
<img src='otherImage'/>
</div>
This works on some window sizes, but sometimes the images will not be on top of the right area of the background Image.
I did a responsive layout for one image behind and a floating form resizing and repositioning all fields and texts.
I will not put all my code here, then i said to you create your own code inside a function named like "update_field_positions" running in events window resize and load.
For screens with more than 608px the height of my image is 882px
Then i define the reason of proportion: img_cadastro.clientHeight / 882
And use this value for resize and reposition all the items
I used css too:
#media screen and (max-width:608px) {
.img_cadastro {
width:100%;
height:auto;
}
and
#media screen and (min-width:608px) {
.img_cadastro {
width:608px;
height:882px;
}
A little piece of my working js code:
function update_field_positions() {
.... (some code) ....
var razao = img_cadastro.clientHeight / 882;
bloco_campos_ext.style.top = ((258 * razao) + compensador) + "px";
div_voucher.style.marginTop = ((57 * razao) + compensador_voucher) + "px";
div_voucher.style.marginLeft = ((120 * razao) + compensador) + "px";
nome_voucher.style.fontSize = (24 * razao) + "px";
cod_voucher.style.fontSize = (28 * razao) + "px";
resize_object(bloco_campos_ext, 357, 148, razao, false);
resize_object(bloco_campos_int, 357, 148, razao, false);
}
Use this css to your div:
position:fixed;
bottom:0;
For a responsive screen working when the windows is resized
Your codes of getting ratio and repositioning should be inside a function, you could create a function named update_field_positions for example: update_field_positions()
then your function must be called in 2 events, onload and window.resize
example:
function start() {
update_field_positions();
window.onresize = update_field_positions;
}
<body onLoad="start()">
Tou should use onload, for wait objects become ready before working with them to avoid errors and window.onresize to update values with a new window.innerWidth
The other problem is that the window can be resized to a smaller size than your image
And then you have to create some code to handle these situations:
if (window.innerWidth < naturalWidth) {...}

Proportionally scale website to fit browser window

What would be an elegant solution to proportionally scale and center an entire website to fit a browser window (and updating as it's re-sized)
Assume the base layout is 720x500px
Content should proportionally scale to fit, and then re-center.
Essentially, operating like this Flash plugin: http://site-old.greensock.com/autofitarea/ (though base size is known)
Site will contain several different types of elements in that 720x500 area... ideal solution would just scale the whole thing, not needing to style each individual element (in case it matters- images will be SVG and so scaling should have no negative affect on resolution)
Depending on the browsers you need to support (IE9+), you could achieve that with simple CSS transform.
See an example (using jQuery) in this jsfiddle
var $win = $(window);
var $lay = $('#layout');
var baseSize = {
w: 720,
h: 500
}
function updateScale() {
var ww = $win.width();
var wh = $win.height();
var newScale = 1;
// compare ratios
if(ww/wh < baseSize.w/baseSize.h) { // tall ratio
newScale = ww / baseSize.w;
} else { // wide ratio
newScale = wh / baseSize.h;
}
$lay.css('transform', 'scale(' + newScale + ',' + newScale + ')');
console.log(newScale);
}
$(window).resize(updateScale);
If you need backwards compatibility, you could size everything in your site with % or em, and use a similar javascript to control the scale. I think that would be very laborious though.
One solution I'm using is working with a container in which I put an iframe that's being resized to fit as much available screen as possible without losing it's ratio. It works well but it's not completely flexible: you need to set dimensions in your content page in % if you want it to work. But if you can manage your page this way, I think it does pretty much what you want.
It goes like this. You create a container html page that's basically only styles, the resize script and the iframe call. And you content goes into the iframe page.
<style>
html, body
{
border: 0px;margin: 0px;
padding:0px;
}
iframe
{
display: block;
border: 0px;
margin: 0px auto;
padding:0px;
}
</style>
<script>
$(document).ready(function(e){
onResizeFn();
});
$(window).resize(function(e){
onResizeFn();
});
// this stretches the content iframe always either to max height or max width
function onResizeFn(){
var screen_ratio = 0.70 // this is your 720x500 ratio
if((window.innerHeight/window.innerWidth) > screen_ratio){
var theWidth = window.innerWidth
var theHeight = (window.innerWidth*screen_ratio);
} else {
var theHeight = window.innerHeight;
var theWidth = (window.innerHeight/screen_ratio);
}
document.getElementById("your_iframe").width = theWidth + "px"
document.getElementById("your_iframe").height = theHeight + "px"
}
</script>
// And then you call your page here
<iframe id='your_iframe' src='your_content_page' scrolling='no' frameborder='0'"></iframe>

Setting width and height as a percentage in JavaScript

Here is my JavaScript code:
a.width = a.width ? a.width : 640;
a.height = a.height ? a.height : 360;
How can I make the 640px and 360px percentages instead? I want them both to be 70% of the windows size.
If the container of the element have sizing specified already, then you can simply use percentages in CSS. For instance:
.#my-el {
width: 70%;
height: 70%;
}
<div id="my-el"></div>
However, if you have to use JavaScript for some reason, you could do something like:
el.style.width = Math.round(document.documentElement.clientWidth * .70) + 'px';
You may have to use a more complex approach to determine the viewport size for cross-browser support however, but this question was already answered.
percentage is a relative value.
you need to have relative value like screenWidth (for suppose) 1240px so that you will get percentage of that value.
Example
var pixels = 100;
var screenWidth = window.screen.width;
var percentage = ( screenWidth - pixels ) / screenWidth ; // 0.92%
To set an element's width or height as a percentage, there are a couple of options available.
Firstly, you can set the element's dimensions as a percentage of its container like this:
element.width = "70%";
element.height = "70%";
Alternatively, you can set the dimensions as a percentage of the screen size instead like this:
element.width = "70vw";
element.height = "70vh";
These values stand for "viewport height" and "viewport width".
However, since both of these options use basic CSS values, it may be preferable to add a CSS class dynamically to the element instead of setting its style properties directly in JavaScript. For example:
element.classList.add("my-class");
Then, define the .my-class selector in a stylesheet like this:
.my-class {
width: 70%;
height: 70%;
}

Is it possible to get the width of the window in em units using javascript?

I'm looking for a reliable way to get the width of the window in em units using JavaScript. I was surprised to see that jQuery will only return a result in pixel measurements.
This seems to work:
$(window).width() / parseFloat($("body").css("font-size"));
Here's a solution that doesn't require jQuery, and doesn't require an explicit font-size declaration.
window.innerWidth / parseFloat(
getComputedStyle(
document.querySelector('body')
)['font-size']
)
For those who need it all put together, this code works for me:
<p>Window size: <span id="width_px"></span> pixels or <span id="width_ems"></span> ems</p>
<script>
window.onresize = function() {
document.getElementById("width_px").innerHTML = window.innerWidth;
document.getElementById("width_ems").innerHTML = window.innerWidth / parseFloat($("body").css("font-size"));
};
</script>
It's put together using the answer above added to the window-width test code found in the linked tutorial.
It's possible to calculate it, but em isn't a "simple" unit like px because it depends on a font selection (that is, a combination of typeface family, style (bold, italic, etc), and font size). Of course font size itself can be relative (e.g. if you give a font an em, ex, or percentage size then the computed px height for that font is derived from the parent element's size).
To get the em width of a page you could do the conversion like this (warning: psuedocode):
// For this to work reliably, size should be in px, pt, or mm.
function getWindowWidthInEm(fontFamily, style, size) {
var box = document.createElement("span");
box.innerText = "M";
box.style.fontFamily = fontFamily;
box.style.fontSize = size;
box.style.fontWeight = style is bold;
box.style.fontStyle = style is italic;
var body = document.getElementsByTagName("body")[0];
body.appendChild( box );
var emInPx = box.getComputedStyle().width;
body.removeChild( box );
var windowPx = window.width;
return windowx / emInPx;
}
Simple, since we know 1em = 16px
var window_width_em = 1/16 * window_width_px;

how to set font size based on container size? [duplicate]

This question already has answers here:
Font scaling based on size of container
(41 answers)
Closed 1 year ago.
I have a container that has a % width and height, so it scales depending on external factors. I would like the font inside the container to be a constant size relative to the size of containers. Is there any good way to do this using CSS? The font-size: x% would only scale the font according to the original font size (which would be 100%).
If you want to set the font-size as a percentage of the viewport width, use the vwunit:
#mydiv { font-size: 5vw; }
The other alternative is to use SVG embedded in the HTML. It will just be a few lines. The font-size attribute to the text element will be interpreted as "user units", for instance those the viewport is defined in terms of. So if you define viewport as 0 0 100 100, then a font-size of 1 will be one one-hundredth of the size of the svg element.
And no, there is no way to do this in CSS using calculations. The problem is that percentages used for font-size, including percentages inside a calculation, are interpreted in terms of the inherited font size, not the size of the container. CSS could use a unit called bw (box-width) for this purpose, so you could say div { font-size: 5bw; }, but I've never heard this proposed.
Another js alternative:
Working Example
fontsize = function () {
var fontSize = $("#container").width() * 0.10; // 10% of container width
$("#container h1").css('font-size', fontSize);
};
$(window).resize(fontsize);
$(document).ready(fontsize);
Or as stated in torazaburo's answer you could use svg. I put together a simple example as a proof of concept:
SVG Example
<div id="container">
<svg width="100%" height="100%" viewBox="0 0 13 15">
<text x="0" y="13">X</text>
</svg>
</div>
You may be able to do this with CSS3 using calculations, however it would most likely be safer to use JavaScript.
Here is an example: http://jsfiddle.net/8TrTU/
Using JS you can change the height of the text, then simply bind this same calculation to a resize event, during resize so it scales while the user is making adjustments, or however you are allowing resizing of your elements.
I used Fittext on some of my projects and it looks like a good solution to a problem like this.
FitText makes font-sizes flexible. Use this plugin on your fluid or responsive layout to achieve scalable headlines that fill the width of a parent element.
It cannot be accomplished with css font-size
Assuming that "external factors" you are referring to could be picked up by media queries, you could use them - adjustments will likely have to be limited to a set of predefined sizes.
Here is the function:
document.body.setScaledFont = function(f) {
var s = this.offsetWidth, fs = s * f;
this.style.fontSize = fs + '%';
return this
};
Then convert all your documents child element font sizes to em's or %.
Then add something like this to your code to set the base font size.
document.body.setScaledFont(0.35);
window.onresize = function() {
document.body.setScaledFont(0.35);
}
http://jsfiddle.net/0tpvccjt/
I had a similar issue but I had to consider other issues that #apaul34208 example did not tackle. In my case;
I have a container that changed size depending on the viewport using media queries
Text inside is dynamically generated
I want to scale up as well as down
Not the most elegant of examples but it does the trick for me. Consider using throttling the window resize (https://lodash.com/)
var TextFit = function(){
var container = $('.container');
container.each(function(){
var container_width = $(this).width(),
width_offset = parseInt($(this).data('width-offset')),
font_container = $(this).find('.font-container');
if ( width_offset > 0 ) {
container_width -= width_offset;
}
font_container.each(function(){
var font_container_width = $(this).width(),
font_size = parseFloat( $(this).css('font-size') );
var diff = Math.max(container_width, font_container_width) - Math.min(container_width, font_container_width);
var diff_percentage = Math.round( ( diff / Math.max(container_width, font_container_width) ) * 100 );
if (diff_percentage !== 0){
if ( container_width > font_container_width ) {
new_font_size = font_size + Math.round( ( font_size / 100 ) * diff_percentage );
} else if ( container_width < font_container_width ) {
new_font_size = font_size - Math.round( ( font_size / 100 ) * diff_percentage );
}
}
$(this).css('font-size', new_font_size + 'px');
});
});
}
$(function(){
TextFit();
$(window).resize(function(){
TextFit();
});
});
.container {
width:341px;
height:341px;
background-color:#000;
padding:20px;
}
.font-container {
font-size:131px;
text-align:center;
color:#fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="container" data-width-offset="10">
<span class="font-container">£5000</span>
</div>
https://jsfiddle.net/Merch80/b8hoctfb/7/
I've given a more detailed answer of using vw with respect to specific container sizing in this answer, so I won't just repeat my answer here.
In summary, however, it is essentially a matter of factoring (or controlling) what the container size is going to be with respect to viewport, and then working out the proper vw sizing based on that for the container, taking mind of what needs to happen if something is dynamically resized.
So if you wanted a 5vw size at a container at 100% of the viewport width, then one at 75% of the viewport width you would probably want to be (5vw * .75) = 3.75vw.
If you want to scale it depending on the element width, you can use this web component:
https://github.com/pomber/full-width-text
Check the demo here:
https://pomber.github.io/full-width-text/
The usage is like this:
<full-width-text>Lorem Ipsum</full-width-text>
You can also try this pure CSS method:
font-size: calc(100% - 0.3em);

Categories

Resources