I've read a fair bit about resizing fonts recently, most of it deriding using px as an unforgivable crime (ok, maybe not that bad, you get the idea) because it doesn't resize properly in older browsers.
I really want to have a standard that I use myself, in the past that has been px, simply because it's simple, easy to understand and fairly easy to achieve the exact font sizes that are specified in designs - but I'm now doubting using px.
I used em on a project recently because it needed text-resizing functionality which I made using jQuery. But I found it quite frustrating because of the way that em amplifies if you have two elements inside of each other both with an em size specified (hope that makes sense)
So I was wondering about using % for font resizing, I've seen a couple of big websites use this technique (namely, Yahoo) and from what I understand it seems to have all of the advantages of em without the incredibly annoying amplification thing.
So in short, I'm just wondering if there are any issues with using % for font-sizing in CSS? Would it be better than using PX in terms of font-resizing? And are there any noticeable draw backs?
Apologies if the blurb before the question is a little much :/ I'm still kind of getting used to the whole QA thing
In CSS3, use rem (root em). Sizing will not be affected by em size of the parent element.
The root font size is set by setting the font size on the :root pseudo-element, like so:
:root {
font-size: 16px;
}
try using this
body {
margin: 0px;
padding: 0px;
font-size: 62.5%;
}
body>#wrapper {
font-size:1em;
}
so, when you say something like 1em inside the "wrapper" you'll have a size very similar to 10px. here's a example table:
3em == 30px
.5em == 5px
8.5em == 85px
This will help you in the transition
P.d: of course, you need a wrapper tag after the body
The standard in web design as far as I have experienced it is to use a percent to set the font size in the body, then to use ems to change the font sizing after that. You could use percents outside the body tag with no adverse side effects, but I think many developers find ems easier to work with (anyone is free to check me on this).
The danger comes if you use ems to set the body font size; older browsers choke and incorrectly display the text, especially when zoomed.
There's a jQuery plugin called FitText. It resizes text based on percents. If the visitor for some reason has JavaScript disabled, it'll just display as normal, so set a reasonable PX or EM backup.
It depends on jQuery, so you'll need to include that in your page (if you don't have it already).
jquery.fittext.js for reference:
/*global jQuery */
/*!
* FitText.js 1.0
*
* Copyright 2011, Dave Rupert http://daverupert.com
* Released under the WTFPL license
* http://sam.zoy.org/wtfpl/
*
* Date: Thu May 05 14:23:00 2011 -0600
*/
(function( $ ){
$.fn.fitText = function( kompressor, options ) {
var settings = {
'minFontSize' : Number.NEGATIVE_INFINITY,
'maxFontSize' : Number.POSITIVE_INFINITY
};
return this.each(function(){
var $this = $(this); // store the object
var compressor = kompressor || 1; // set the compressor
if ( options ) {
$.extend( settings, options );
}
// Resizer() resizes items based on the object width divided by the compressor * 10
var resizer = function () {
$this.css('font-size', Math.max(Math.min($this.width() / (compressor*10), parseFloat(settings.maxFontSize)), parseFloat(settings.minFontSize)));
};
// Call once to set.
resizer();
// Call on resize. Opera debounces their resize by default.
$(window).resize(resizer);
});
};
})( jQuery );
Maybe will this make more sense of making a font-resize script.
I had made a script that did exactly what you desire, but I cant find it any more.
Pseudo-code:
var fontSize = 15; // (em) input
var fontResize = -1;// (em)input
fontSize = fontSize+fontResize; //current div
for(every inherent parent classname == 'classname-em')
document.classnameParentSize[numberofclass] = classnameChildSize[numberOfClass]/100*90;
So explained in words. The script needs to resize some fonts, when that is done it will also look for some parent divs to resize those fonts too, except they will be resized 10% less than its inherent. With some puzzling you will have the right conversion. Also try to avoid paddings and border widths.
Related
I am a noob web developer and made a big mistake.
I am creating a website for a college project, it needs to be responsive. I have tons of CSS written all in px units. But now for responsiveness, I want to convert all the px to rem. It would be a tiring task to do it one by one. Is there any tool that can help me?
I don't know of any tool that would automatically change all px to rems but you can make the changes quickly if you do something like this:
body {
font-size: 0.625rem;
{
Now 1 rem will be equal to 10 px, if you use Vscode you can enter a shortcut Ctrl + F and choose a Use Regular Expression option in Find input.
Then you can type (\d*)?(\d).?(\d*)?px in Find field, and $1.$2$3rem in Replace field.
But be alert, this regex doesn't work for sizes beginning with dot like .5px.
The search bar should look like this:
If you want to learn how this regular expression works click here.
Regex shouldn't be used this way, but...
This function should work but the predicament you are in is usually a one time thing and I normally advise against using Regex in this manner. The function pxToRem():
Finds all occurrences of a number (even with a decimal) adjacent to the letters 'px'.
Then a replacer function takes the number part and divides it by 16
Next it suffixes the new number with 'rem' and replaces the old number and 'px'.
Usage
Open your stylesheet, select as much of the text you need to change and copy it.
Next, paste it on a blank .html or .js file.
Wrap the text in grave marks ``` on a QWERTY keyboard it's the key located upper left hand corner `~
Assign the string to a variable.
Copy and paste pxToRem() code to the same page.
let css = `.box {width: 32px; height: 16px; border: 6px; padding 2.5px;}`;
function pxToRem(CSSString) {
const rgx = new RegExp(/(\d+\.?\d*)px/, 'g');
return CSSString.replace(rgx, (match, n) => (n / 16) + 'rem');
}
console.log(pxToRem(css));
Keep in mind that rem are relative to the font-size set on :root/html and if that font-size happens to be absolute (like the default of 16px) then the styles with rem aren't responsive, but they have the potential to be responsive. If you use a vmin units all rem will react immediately to any changes to the viewport. This not for the faint of heart.
If the font I am using couldn't be loaded or is not found, the alternate font will be used. If so, I need to change some other styles like font-weight, letter-spacing, font-size, etc.
for example:
div {
font-family:"Lemon",sans-serif;
}
Here Lemon is a really thick font, so the way I style this font might not be suitable for the alternative font. So if the first specified font could not be loaded, how can I change style of the alternative font accordingly?
Caveat: this method should be able to detect whether any non monospaced font is loaded or not.
It appears it is not possible to sense the actual font in use using CSS alone. Taking ideas from font.js highlighted in #Eddie Reeder answer and also from github.com/philoye/fontunstack/tree/master we can measure the required font against another font. I have chosen a monospace font to test against and a string of narrow characters (i) as being the most likely to be different from the required font.
Code like this (which I've deliberately spelled out to make clear what is going on) placed possibly in the head or at the start of body. It could of course be placed in a function to be called at the start and/or made to remove its test divs once the required script has been set up and/or to set CSS variables if that makes more sense than having two separate css style files.
<div id="maybeOurFont" style="font-family: Lemon, monospace; font-size: 100px; position: absolute; left: -9999px; top:0;">iiiiiiiiiiiiiiiiiiii</div>
<div id="testFont" style="font-family: monospace; font-size: 100px; position: absolute; left: -9999px; top:0;">iiiiiiiiiiiiiiiiiiii</div>
<script>
const pathToLemonStyle = "lemonstyle.css"; //replace with your path
const pathToNoLemonstyle = "nolemonstyle.css"; // ditto
const lemonLength = document.getElementById("maybeOurFont").offsetWidth;
const monoLength = document.getElementById("testFont").offsetWidth;
let useThisStyle = pathToLemonStyle;
if ( lemonLength == monoLength ) {
useThisStyle= pathToNoLemonstyle;
}
document.head.append('<style src="' + useThisStyle + '"></style>');
</script>
Using pure CSS, you can't. One option would be to use javascript to detect if a font is installed, then adjust your styles accordingly.
Something like:
$(document).ready(function () {
font.setup(); // run setup when the DOM is ready
if (!font.isInstalled("Lemon")) {
document.getElementById("example-div").style.fontWeight = "900";
}
});
This utilises font.js which must be included in your page.
I have the following CSS which I use to set the height of CodeMirror which works well across browsers :
.CodeMirror {
/* Firefox */
height: -moz-calc(100vh - 190px);
/* WebKit */
height: -webkit-calc(100vh - 190px);
/* Opera */
height: -o-calc(100vh - 190px);
/* Standard */
height: calc(100vh - 190px);
}
Now, I am moving to froala which appears to be the only WYSIWYG editor that supports CodeMirror as the 'view code' portion.
I have no problem embedding and setting up CodeMirror to work with this, and the style that I applied works with the embedded CodeMirror, however I am unable to apply the Height to the requisite CSS file in the manner I have done with CodeMirrors CSS file.
There are height, heightMax, heightMin, and fullPage properties for froala which can be set during JavaScript initialization, however this does not support calculated values.
Before using CSS's calc() method, I was using JavaScript to size CodeMirror with mixed results, and a lot of extra checks in place which was much more "jumpy" and often either going out of bounds (box going beyond the containing elements height), or falling just short (leaving a gap between the editor element and the containing elements height).
What I would like to do, is override the containing elements height via CSS (I don't mind editing the froala_editor.css file (or other files directly part of the project) to do this. To figure this out for CodeMirror took a rather long time to find the ONE spot where the height calc css would go into the .CodeMirror block. With froala, I do not know where or what the equivalent is called to size the editable area.
I have tried placing the size code in several places including .fr-box.fr-basic .fr-element, to no avail.
The height parameter of froala accepts valid CSS values like 100px, 100, or 100%. As a result, you can use browser detection to fairly effectively decide which value to set.
Following is one example on how this can be done, while still maintaining the calc method in CSS without the need to modify any of froala's CSS files :
// set the default calc value
var codeHeight = 'calc(100vh - 96px)';
// prepend any browser engine specific names if needed
if((navigator.userAgent.indexOf("Opera") || navigator.userAgent.indexOf('OPR')) != -1 ) {
codeHeight = '-o-' + codeHeight;
} else if(navigator.userAgent.indexOf("Chrome") != -1 ) {
codeHeight = '-webkit-' + codeHeight;
} else if(navigator.userAgent.indexOf("Safari") != -1) {
codeHeight = '-webkit-' + codeHeight;
} else if(navigator.userAgent.indexOf("Firefox") != -1 ) {
codeHeight = '-moz-' + codeHeight;
}
// Initialize froala using calc for height
$('.code').froalaEditor({
height: codeHeight
});
While the above is a hackish way to accomplish this, there are other browser detection methods which could be applied. This just demonstrates how this can be done as elegantly as possible without touching any of froala's sources.
In summary, this works as follows :
Detect the browser (above case uses JavaScript and UserAgent)
Set an accessible variable to the detected browser supported calc CSS method
Pass the accessible variable to froala's height init parameter.
I have a site.css and something similar to mobile.css.
What I am building is a webpage where you can preview the app you've made. Imagine it like a site devided in half where one half has a panel with controls while the other one has the preview (div), curently designed as a mobile phone.
So what I am actually doing is a mobile phone on my site (preview), but the problem is that I dont know how to use the mobile.css file in the preview div only.
Is there a way to import a CSS file for one div (and its children)?
A simplified look of my page: https://jsfiddle.net/kc8rgde2/1/
<iframe>, <style scoped> or external CSS preprocesors are not an option.
EDIT:
I kinda decided to go with SASS as it was the easiest to understand and Visual Studio had a nice extension for it.
Thank you for all the help.
I had an idea. It could work, and it needs a lot of testing.Check this fiddle ->
https://jsfiddle.net/kc8rgde2/2/
Basically, as you can see, in the fiddle there's no bootstrap loaded.
I load bootstrap, and access the file using the CDN link from an AJAX request.
The response of the ajax, is the content of the bootstrap css file (minified version) - (check the console!)
What i do after, is replacing all the classes (dots) with ("#phonePreview .") and this prepends the phone preview div id to all the classes.
$(document).ready(function() {
$.when($.get("https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"))
.done(function(response) {
var res = response.replace(/\./g,'#phonePreview .')
console.debug (res);
$('<style />').text(res).appendTo($('body'))
});
})
Prepending the parent id means that the classes are applied only to #phonePreview children.
It's just a starting point, but with some work it could work!
If you want to use styles specifically for devices under a certain size you could use media queries:
#media only screen and (max-width: 431px) {
.myDiv {
style: style;
style: style;
}
#div2 {
style: style;
style: style;
}
}
max-width: 431px means devices that are 431px or lower in width. You could also use height and change it to min-width.
I have ten div's added every second, each with an image, and I want them to slide in from the left. This is too intensive work for javascript, and also too much for keyframing.
So what would be the most efficient (CPU/memory wise, also considering mobile devices) way of doing this?
Thanks.
Can you use JS to add a class to them using a setInterval, then use CSS transitions with that class?
Using a framework like jQuery Transit can easily accomplish this. The great thing about this framework is that it works great on mobile devices (within reason) and uses the hardware acceleration capabilities of the browser wherever it can.
JS Fiddle Example
Javascript:
$(document).ready(function () {
showDiv($('div:first'), 90);
function showDiv(div, pixels) {
div.transition({
opacity: 1,
left: pixels + '%'
}, 1000, 'out', function () {
//call back
showDiv(div.next("div"), pixels - 10);
});
}
});
It isn't a perfect example by any means, but it should steer you in the right direction.
Insane mode for those that live on the edge.