I'm trying to add some text resize functionality using this code:
$('#text-resize a').click(function(){
var currentValue = $('#page-body').css('fontSize');
var currentSize = parseFloat(currentValue, 10);
var fontUnit = currentValue.slice(-2);
var newSize = currentSize;
if ($(this).attr('rel') == 'decrease'){
if (currentSize > 13){
var newSize = currentSize / 1.2;
}
}
else if ($(this).attr('rel') == 'increase'){
if (currentSize < 19){
var newSize = currentSize * 1.2;
}
}
else {
newSize = 1;
fontUnit = 'em';
}
newSize += fontUnit;
$('#page-body').css('fontSize', newSize);
return false;
});
I know it's not the cleanest code, but my problem is that at some point (either getting or setting the font size for #page-body decimal points are being lost.
For example, I start with a value of 16px (from my CSS file) and when I increase it gets calculated to 19.2px. If I increase again, an alert of the currentValue (I have left out the alert) says it's 19px.
Can anyone tell me why decimal places are being ignored and how to prevent that?
If it helps, my starting CSS includes:
body { font-size: 16px; }
#page-body { font-size: 1em; }
Thanks
A font size can only be a whole number of pixels, so when you set the font-size the browser casts the invalid font size to something it can use. The next time you get it, it's an integer number.
Since you're setting the font size on an element identified by ID, you should store the size in a variable and only set (never get) the element css font size.
For example, see http://jsfiddle.net/Qfzpb/
Sub-pixel rendering is inconsistent between browsers.
Font size can be a <length>, and a <length> is a <number> (with or without a decimal point) immediately followed by a unit identifier (e.g., px, em, etc.).
http://www.w3.org/TR/CSS21/fonts.html#font-size-props
CSS 3 says " UAs should support reasonably useful ranges and precisions. " Open-to-interpretation wording as 'reasonable' and 'useful':
http://dev.w3.org/csswg/css3-values/#numeric-types
$('#page-body').css('fontSize')
This may return different values(depending on the used browser).
Usually (in modern browsers) jQuery gets the value by using getComputedStyle() .
The returned value here is the value used by the browser, not the value the style-property is set to.
You may use this instead:
var currentValue = document.getElementById('page-body').style.fontSize
||
$('#page-body').css('fontSize');
See the fiddle to determine the differences: http://jsfiddle.net/doktormolle/DMWhh/
Related
Lets say I add a text box of length of 50px, And I want to count the exact number of characters (including whitespace) that perfectly fits inside that text box, I mean no character should be allowed to be typed inside the textbox that require the sliding of whole line toward left; I mean, in another other-words, we need to disallow the typist to further insert any letter as the line reaches up to the length of the text box. Can we anyhow solve this by JavaScrip? Thanks for the help in advance, any help would be appreciated.
The whole logic is flawed as it would depend also on the size of the text inside the input. I'd put instead a limit of chars to be entered that don't go beyond. Using maxlength input attribute.
Anyways if you really wanna go this route, which I think is an overkill and not needed, then you can:
Make use of CanvasRenderingContext2D.measureText, docs here
In order to do that you'd have to create a hidden canvas element where to mimic your input text.
After that you will need to check on input if the text goes beyond the input width and avoid any further keystrokes but still allow for deletion.
Find attached an example snippet, not optimised, of what I am talking about.
const form = document.querySelector('#form'),
input = form.querySelector('input')
const createAppendCanvas = form => {
const canvas = document.createElement('Canvas')
form.appendChild(canvas)
}
createAppendCanvas(form)
const getTextMetrics = inputText => {
const canvas = document.querySelector('canvas'),
textWidth = Math.ceil(canvas.getContext('2d').measureText(inputText).width) + 10
return textWidth
}
const disableTyping = (event, input) => {
const inputText = event.target.value,
inputWidth = input.clientWidth
if (getTextMetrics(inputText) >= inputWidth) {
event.preventDefault()
return false
}
}
input.addEventListener('keypress', event => disableTyping(event, input))
input {
width: 50px;
}
canvas {
display: none;
}
<form id="form">
<input type="text" />
</form>
As #mel-macaluso rightly points out, this is a very big rabbit hole to go down, and the standard practice is to use the maxlength attribute to limit the number of characters.
*Edit: You can also set the width of the input using em, which is proportional to the font size. (The name em was originally a reference to the width of the capital M in the typeface and size being used, which was often the same as the point size ref) A combination of width in em and maxlength will give a very rough approximation of what you may be trying to achieve.
However if you really want to be able to limit input based text length, this would serve as a very simplistic example of how you might get started.
Edit: I recommend #mel-macaluso's answer: he added an example using CanvasRenderingContext2D.measureText(), which I suspect is much more efficient than getBoundingClientRect.
First some disclaimers:
This example doesn't take into account clipboard actions. That's a pretty big problem, and you'd be talking a lot more code to try to account for it (way beyond the scope of what can reasonably be done here).
It's also rather resource intensive. The process doing a getBoundingClientRect, forces the browser to reflow the document contents an extra time. Depending on the size of the page this can be a big deal, and it's not something to be done lightly.
var inp = document.getElementById('test');
// get font for input
var style = getComputedStyle(inp);
var maxWidth = inp.getBoundingClientRect().width;
var sizeTest = document.createElement('span');
// set font for span to match input
sizeTest.style.font = style.font;
inp.addEventListener('keydown', function(e){
if(e.ctrlKey || e.altKey) return;
if(e.key && e.key.length===1) {
sizeTest.textContent = inp.value;
document.body.append(sizeTest);
var w = sizeTest.getBoundingClientRect().width;
sizeTest.remove();
console.log(maxWidth, w, e.key, e.code);
if(w>maxWidth) e.preventDefault();
}
})
<input id='test'/>
So why is it so complex to do something like this? Fonts are tricky things. You have variable width (proportional) fonts, kerning, ligatures, etc. It's very complex, and browsers don't provide access to most of this information.
So if you want to know how long a segment of text is, you generally have to put it in a span with the same font settings and then request the bounding dimensions.
Here's neat solution using nested spans (with a contenteditable inner span) as a proxy input.
// Identifiers and dynamic styling
const innerSpan = document.querySelector("span.inner"),
outerSpan = document.querySelector("span.outer");
/* Threshold should be at least one character-width less than outerSpan.
(This formula was pretty close for my few tests;
for more precision and less flexibility, you can hard-code a value.) */
const estMaxCharWidth = innerSpan.offsetHeight / 1.7,
thresholdWidth = outerSpan.offsetWidth - estMaxCharWidth;
innerSpan.style.minWidth = `${Math.floor(thresholdWidth)-3}px`; // defaults to 0
innerSpan.style.minHeight = `${Math.floor(outerSpan.offsetHeight)-2}px`
// Listeners
innerSpan.addEventListener("focus", customOutline);
innerSpan.addEventListener("keydown", checkKeyAndWidth);
innerSpan.addEventListener("blur", removeOutlineAndHandleText);
// Functions
function checkKeyAndWidth(e){
// Runs when user presses a key, Conditionally prevents input
if(e.code == "Enter" || e.keyCode == 13){
e.preventDefault(); // Don't insert a new line
e.target.blur(); // (In production, set the focus to another element)
}
else{
// Some keys besides Enter are important, More could be added
const whitelistCodes = ["Backspace", "Tab", "Escape", "ArrowLeft", "ArrowRight", "Insert", "Delete"];
const whitelistKeyCodes = [8,9,27,37,39,45,46];
// If the inner span is wide enough, stop accepting characters
let acceptingCharacters = e.target.offsetWidth <= thresholdWidth;
if(!acceptingCharacters && !whitelistCodes.includes(e.code) && !whitelistKeyCodes.includes(e.keyCode) && !whitelistKeyCodes.includes(e.which)){
// Unauthorized incoming keystroke
e.preventDefault();
}
}
}
function customOutline(){
// Runs when span gets focus, Needed for accessibility due to CSS settings
outerSpan.style.borderColor = "DeepSkyBlue";
}
function removeOutlineAndHandleText(){
// Runs when focus is lost
outerSpan.style.borderColor = "Gray";
if(innerSpan.length < 1){ innerSpan.innerHTML = " "; } // force content
/* Since this is not a real input element, now might be the time to do something with the entered text */
}
.outer{
display: inline-block;
position: relative;
width: 100px; /* Defaults to 0 */
padding: 0;
border: 1px solid gray;
}
.inner{
display: inline-block;
position: relative;
top: 0;
height: 100%;
margin: 0;
outline: none; /* Don't do this without calling customOutline on focus */
}
<!-- requires that browser supports `contenteditable` -->
<span class="outer">
<!-- space character in innerSpan may improve cross-browser rendering -->
<span class="inner" contenteditable="true"> </span>
</span>
$myWindow.on('resize', function(){
var $width = $myWindow.width();
if ($width > 870) {
console.log('hey im 870');
$('#the-team-wrapper .flex-content').empty();
ajax_results.done(function(data) {
// console.log(data.job_titles[3]);
var employee_job_titles;
function job_titles_display(jobtitle,ind){
if (jobtitle.job_titles[ind].length>1) {
var my_array = [];
for (var i = 0; i < jobtitle.job_titles[ind].length; i++){
my_array.push(jobtitle.job_titles[ind][i][0]['title']);
employee_job_titles = my_array.join(' | ');
}
}else {
var employee_job_titles;
employee_job_titles = jobtitle.job_titles[ind][0]['title'];
}
return employee_job_titles;
}
for (var i = 0; i < data.employee_info.length; i++) {
if(i%2 == 0){
$('#the-team-wrapper .flex-content').append('<div class="profile-parent"><div class="employee-profile-pic flex-item" data-id="'+data.employee_info[i]['id']+'"></div><div class="employee-bio-wrapper flex-item"><h2 data-id="'+data.employee_info[i]['id']+'">'+data.employee_info[i]['firstname']+" "+data.employee_info[i]['lastname']+'</h2><h3 data-id="'+data.employee_info[i]['id']+'">'+job_titles_display(data,i)+
'</h3><p class="employee-bio-text employee-bio-text-not-active">'+data.employee_info[i]['bio']+'</p></div><button type="button" class="bio-prev-butt-left">View '+data.employee_info[i]['firstname']+'\'s'+' Bio</button><div class="hide-bio-close-button-left">x</div></div>');
}else {
$('#the-team-wrapper .flex-content').append('<div class="profile-parent"><div class="employee-bio-wrapper flex-item"><h2 data-id="'+data.employee_info[i]['id']+'">'+data.employee_info[i]['firstname']+" "+data.employee_info[i]['lastname']+'</h2><h3 data-id="'+data.employee_info[i]['id']+'">'+job_titles_display(data,i)+'</h3 data-id="'+data.employee_info[i]['id']+
'"><p class="employee-bio-text employee-bio-text-not-active">'+data.employee_info[i]['bio']+'</p></div><div class="employee-profile-pic flex-item" data-id="'+data.employee_info[i]['id']+'"></div><button type="button" class="bio-prev-butt-right">View '+data.employee_info[i]['firstname']+'\'s'+' Bio</button><div class="hide-bio-close-button-right">x</div></div>');
}
var profile_pic_path = data.employee_info[i]['profile_pic'].split('\\').join('\\\\');
$("#the-team-wrapper .flex-content-wrapper .flex-content .employee-profile-pic:eq("+i+")").css({'background': 'url(_employee_pics/'+profile_pic_path+')','background-repeat': 'no-repeat','background-position': 'center', 'background-size': 'cover'});
}
});
}
I have this code, and it should fire when width is greater than 870, but instead it fires when width is greater than 970 on Opera, and when width is about 890 on Chrome. How can I fix this and get consistent results across browsers. Thanks in advance.
Are you using a CSS reset to neutralize the browser's default margin or padding on the <body> element?
Different browsers add different amounts of either padding or margin to the <body> of the page, which could explain why the function is triggered at different points in different browsers.
The problem is, the resize event fires at different times and rates depending on browser, CPU load, and how fast you actually do the resizing.
Test the following code in your browsers. When I do this in a clean browser at a reasonable rate of coverage the difference usually comes in within around 2px of the target.
(BTW, you'll see I am caching the jQuery selectors into variables. Not strictly necessary for this test, but you might be surprised to find out how many bugs I've fixed because coders have invoked uncached jQuery selectors willy-nilly in loops and other repetitive places throughout their code).
var $window = $(window);
$window.on('resize',function(){
var w = $window.width();
if (w > 1000) {
console.log( w );
} else {
console.log('nope: ' + w)
}
});
I'm trying to cycle through numbered questions based on the exact percentage of what what the user has scrolled. My goal is to get this to work responsively.
I've created a sample fiddle so that you see what I'm trying to do...
$(document).ready(
$(window).scroll(function(){
var progress = $(this).scrollTop() / $(document).height();
//calculate the percentage of the total window that the user has scrolled
var questNum = progress * 4;
//multiply that by the total number of questions, to get the corresponding question number
if (questNum < 1) {
$('#question').text('Hello?');
}
else if (questNum < 2) {
$('#question').text("It's me...");
}
else if (questNum < 3) {
$('#question').text('I was wondering if after all these years...');
}
else if (questNum < 4) {
$('#question').text('You'd like to meet.');
}
else{
$('#question').text('*ring ring*');
};
});
);
*{
height: 500px;
font-family: sans-serif;
font-size: 1em;
font-weight: 100;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<span id="question" style="position: fixed">...</span>
</div>
In theory it seems like it should work, but I'm so lost. Thanks!
Some things to correct or change:
$(document).ready needs a function as its argument, so add function() { ... };
Single quotes need to be escaped with a backslash when they occur in a single-quoted string: 'It\'s me...' and 'You\'d like to meet.'
As you don't know on which window size your code will run, setting 500px as window height will only have the desired effect on some devices. Instead, set the height dynamically:
$('body').height($(document).height() + slackSpace);
... where slackSpace should be the number of pixels you want to have available for scrolling.
The space you leave for scrolling (slackSpace) should be greater when you have more questions, so it should be made dependent on the number of questions. You would need to decide how many pixels scrolling would need to be done before switching to the next question. You could therefore define slackSpace as follows:
var slackSpace = 5 * scrollPerQuestion;
...where the 5 would be the number of questions. That number should better be managed dynamically (cf. next point).
It will be easier to manage if you put your questions in an array. You then don't need those if .. else if ... else if ..., but can just pick the question text by its number:
var questions = [
'Hello?',
'It\'s me...',
'I was wondering if after all these years...',
'You\'d like to meet.',
'*ring ring*'
];
// ... once you have the questNum value:
$('#question').text(questions[questNum]);
This way you also have access to the number of questions: questions.length.
The calculation of the progress is not correct. The two parts measure a different aspect: the scroll top gives the top of the (visible) content, while the document height corresponds to the bottom offset of all content. The difference between the two will be at least the window height, so you'll never get a progress of 100% like that. It will probably even make some questions unreachable. Instead use this:
var progress = $(window).scrollTop() / slackSpace;
... where slackSpace is the value defined in the previous point.
Some browsers retain the previous scroll position when you come back to a page or refresh it. So you'll want to scroll the page to the top whenever the page loads.
The document has a default margin of some pixels at each side. This badly influences the calculation of the progress. To make things easier, set that margin to zero and apply some spacing to the question element itself so that the text still appears at a nice distance of the window borders (also give the question element a class name instead of an inline style):
body {
margin: 0px;
}
.question {
position: fixed;
padding: 10px;
}
Here is the code applying all these ideas:
$(document).ready(function() {
var questions = [
'Hello?',
'It\'s me...',
'I was wondering if after all these years...',
'You\'d like to meet.',
'*ring ring*'
];
// How many pixels to scroll before going to next question
var scrollPerQuestion = 50;
// Total space needed to scroll through all questions
var slackSpace = questions.length * scrollPerQuestion;
// Set appropriate document height for scrolling all questions:
$('body').height($(document).height() + slackSpace);
$(window).scroll(function(){
// Calculate the percentage of the total window that the user has scrolled
var progress = $(window).scrollTop() / slackSpace;
// Convert progress into question number
var questNum = Math.floor(progress * questions.length);
// Make sure the question number does not pass the maximum
var questNum = Math.min(questNum, questions.length);
// Display corresponding question
$('#question').text(questions[questNum]);
});
// Scroll to top on page load
$(window).scrollTop(0).trigger('scroll');
});
body {
font-family: sans-serif;
font-size: 1em;
font-weight: 100;
margin: 0px;
}
.question {
position: fixed;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<span id="question" class="question">...</span>
</div>
... it will do the job in the snippet.
I've modified your code on
$(document).ready(function(){
and
$('#question').text('You\'d like to meet.');
Try this instead. It should work:
$(document).ready(function(){ //$(document).ready(
$(window).scroll(function(){
var progress = $(this).scrollTop() / $(document).height();
//calculate the percentage of the total window that the user has scrolled
var questNum = progress * 4;
//multiply that by the total number of questions, to get the corresponding question number
if (questNum < 1) {
$('#question').text('Hello?');
}
else if (questNum < 2) {
$('#question').text("It's me...");
}
else if (questNum < 3) {
$('#question').text('I was wondering if after all these years...');
}
else if (questNum < 4) {
$('#question').text('You\'d like to meet.');// $('#question').text('You'd like to meet.');
}
else{
$('#question').text('*ring ring*');
}
});
});//);
I am looking for a easy way to add a line of code to a plugin of mine, to convert a couple of pixel values into em values, because the layout of my project needs to be in ems. Is there an easy way to do this, because I don't want to add a third-party plugin to the site.
Won't post the code here, as it has nothing to do with the plugin it self.
Example: 13px -> ??em
I think your question is very important. Since the classes of display resolutions are rapidly increasing, using em positioning to support wide range of screen resolutions is a really appealing approach. But no matter how hard you try to keep everything in em -- sometimes you get a pixel value maybe from JQuery drag and drop or from another library, and you would want to convert this value to em before sending it back to server for persistence. That way next time user looks at the page, item would be in correct position -- regardless of screen resolution of the device they are using.
JQuery plugins are not very scary when you can review the code, specially if they are short and sweet like this plugin to convert pixel values to em as you want. In fact it is so short I will paste the whole thing here. For copyright notice see the link.
$.fn.toEm = function(settings){
settings = jQuery.extend({
scope: 'body'
}, settings);
var that = parseInt(this[0],10),
scopeTest = jQuery('<div style="display: none; font-size: 1em; margin: 0; padding:0; height: auto; line-height: 1; border:0;"> </div>').appendTo(settings.scope),
scopeVal = scopeTest.height();
scopeTest.remove();
return (that / scopeVal).toFixed(8) + 'em';
};
$.fn.toPx = function(settings){
settings = jQuery.extend({
scope: 'body'
}, settings);
var that = parseFloat(this[0]),
scopeTest = jQuery('<div style="display: none; font-size: 1em; margin: 0; padding:0; height: auto; line-height: 1; border:0;"> </div>').appendTo(settings.scope),
scopeVal = scopeTest.height();
scopeTest.remove();
return Math.round(that * scopeVal) + 'px';
};
Usage Example: $(myPixelValue).toEm(); or $(myEmValue).toPx();.
I just tested this in my application, it works great. So I thought I share.
The following seems to do as you require, though it's based on the font-size of the parent, and of the element itself, being returned in px:
function px2em(elem) {
var W = window,
D = document;
if (!elem || elem.parentNode.tagName.toLowerCase() == 'body') {
return false;
}
else {
var parentFontSize = parseInt(W.getComputedStyle(elem.parentNode, null).fontSize, 10),
elemFontSize = parseInt(W.getComputedStyle(elem, null).fontSize, 10);
var pxInEms = Math.floor((elemFontSize / parentFontSize) * 100) / 100;
elem.style.fontSize = pxInEms + 'em';
}
}
JS Fiddle proof of concept.
Notes:
The function returns false, if the element you're trying to convert to em is the body, though that's because I couldn't work out whether it was sensible to set the value to 1em or simply leave it alone.
It uses window.getComputedStyle(), so it's not going to work with IE, without some adjustments.
References:
Math.floor().
parentNode.
parseInt().
tagName.
toLowerCase().
window.getComputedStyle().
Pixels and ems are fundamentally different types of unit. You can't simply convert between them.
For instance, a user with a default font size of 16px on a site where top-level headings are styled at 200% font size, 1em may be equal to 32px. Move the heading elsewhere in the document, it could be 64px or 16px. Give the same document to a different user, it might be 30/60/15px. Start talking about a different element, and it can change again.
The closest you can come to what you want is to convert from pixels to ems+document+context+settings. But if somebody has asked you to lay out your project with ems, they will probably not be pleased that you are trying to do it in pixels then "converting".
Usually when you want to convert px to em, the conversion happens on the element itself. getComputedStyle returns value in px which break their responsiveness. The code below can be used to help with this issue:
/**
* Get the equivalent EM value on a given element with a given pixel value.
*
* Normally the number of pixel specified should come from the element itself (e.g. element.style.height) since EM is
* relative.
*
* #param {Object} element - The HTML element.
* #param {Number} pixelValue - The number of pixel to convert in EM on this specific element.
*
* #returns {Boolean|Number} The EM value, or false if unable to convert.
*/
window.getEmValueFromElement = function (element, pixelValue) {
if (element.parentNode) {
var parentFontSize = parseFloat(window.getComputedStyle(element.parentNode).fontSize);
var elementFontSize = parseFloat(window.getComputedStyle(element).fontSize);
var pixelValueOfOneEm = (elementFontSize / parentFontSize) * elementFontSize;
return (pixelValue / pixelValueOfOneEm);
}
return false;
};
Using it would be as simple as:
var element = document.getElementById('someDiv');
var computedHeightInEm = window.getEmValueFromElement(element, element.offsetHeight);
Old question, but for reference, here is something I cobbled together, scope and suffix are optional. Pass it a rem or em value as string, eg. '4em' [ you can use spaces and upper/lowercase ] and it will return the px value. Unless you give it a scope, which would be the target element for finding the local EM value, it will default to body, effectively giving you the rem value. Lastly, the optional suffix parameter [ boolean ] will add 'px' to the returned value such that 48 becomes 48px for example.
ex: emRemToPx( '3em', '#content' )
return 48 on a font-size 16px / 100% document
/**
* emRemToPx.js | #whatsnewsisyphus
* To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty.
* see CC0 Public Domain Dedication <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
var emRemToPx = function( value, scope, suffix ) {
if (!scope || value.toLowerCase().indexOf("rem") >= 0) {
scope = 'body';
}
if (suffix === true) {
suffix = 'px';
} else {
suffix = null;
}
var multiplier = parseFloat(value);
var scopeTest = $('<div style="display: none; font-size: 1em; margin: 0; padding:0; height: auto; line-height: 1; border:0;"> </div>').appendTo(scope);
var scopeVal = scopeTest.height();
scopeTest.remove();
return Math.round(multiplier * scopeVal) + suffix;
};
I've packaged this functionality into a library, complete with parameter type checking: px-to-em
Given this HTML:
<p id="message" style="font-size: 16px;">Hello World!</p>
You can expect these outputs:
pxToEm(16, message) === 1
pxToEm(24, message) === 1.5
pxToEm(32, message) === 2
Since the OP requested a way to do this without a library, I've copied the source code of px-to-em to a live demo:
function pxToEm (px, element) {
element = element === null || element === undefined ? document.documentElement : element;
var temporaryElement = document.createElement('div');
temporaryElement.style.setProperty('position', 'absolute', 'important');
temporaryElement.style.setProperty('visibility', 'hidden', 'important');
temporaryElement.style.setProperty('font-size', '1em', 'important');
element.appendChild(temporaryElement);
var baseFontSize = parseFloat(getComputedStyle(temporaryElement).fontSize);
temporaryElement.parentNode.removeChild(temporaryElement);
return px / baseFontSize;
}
console.log(pxToEm(16, message), 'Should be 1');
console.log(pxToEm(24, message), 'Should be 1.5');
console.log(pxToEm(32, message), 'Should be 2');
<p id="message" style="font-size: 16px;">Hello World!</p>
I learned from this answer that with getComputedStyle we can reliably obtain the divisor px value with the decimal point, which improves the accuracy of the calculation. I found that the answer by Aras could be off by over 0.5px, which caused rounding errors for us.
Try using this:
parseInt(myPixelValue) / parseFloat($("body").css("font-size"));
Ems don't equal pixels in anyway. They are a relative measurement.
<span style="font-size: 1em;">This is 1em font size, which means the text is the same size as the parent</span>
<span style="font-size: 1.5em;">This is 1.5em font size, which means the text is 150% the size as the parent</span>
The base size is determined by the user-agent (browser).
This is related to this question.
The answer was given with the script below to reset the font size back to the default:
function resetToDefaultFontSize() {
var p = document.getElementsByTagName('div');
for(i=0;i<p.length;i++) {
p[i].style.fontSize = "12px";
}
}
This works fine for a page that only has one font size of 12 px. How can the script be modified to allow up to three different font sizes on the same page?
Try fontSize = "inherit";
First, I would set my body font-size to 75% using CSS. This will set the overall font to 12px. Once this has been done, you can use:
fontSize = '1em';
So my JavaScript would look like:
function resetToDefaultFontSize() {
var body = document.getElementsByTagName('body')[0];
body.style.fontSize = '1em';
}
If you use this technique, you need to make sure all other font-sizes on the page are using the em unit.