Change Arial to some other font on the whole webpage - javascript

I'm thinking about a script that can change a webpage's font appearance from Arial to some other font face of my choice.
How should I go about doing that?
I understand: * { font-family: "SomeFont"; }
But this won't achieve the objective to only target Arial text.
I can use jQuery or Javascript, whichever is more efficient and fast.
Edit: Seems like people have difficulty understanding the question. So I'll explain some more, I just want the Arial text on the webpage, if it exists, to change in appearance.

I was going to suggest looping through the styleSheets array and, for each style sheet, loop through the rules, find the ones defining Arial as the font, and change that to the other font you want. That way you wouldn't have to visit every element on the page.
The problem with that suggestion, though, is inline styles on elements.
So I hate to say, to do this you'll have to visit every element on the page. For most pages, that won't be a problem, but your mileage may vary.
Here's how you'd do it with jQuery:
$("*").each(function() {
var $this = $(this);
if ($this.css("font-family").toLowerCase().indexOf("arial") !== -1) {
$this.css("font-family", "SomeOtherFont");
}
});
Can't say I like it, though. :-) You can avoid building the massive list ($("*") builds a jQuery object containing all of the page elements, which can be quite large) at the outset if you do a recursive walk instead, e.g.:
$(document.body).children().each(updateFont);
function updateFont() {
var $this = $(this);
if ($this.css("font-family").toLowerCase().indexOf("arial") !== -1) {
$this.css("font-family", "SomeOtherFont");
}
$this.children().each(updateFont);
}
That may be preferable, you'd have to profile it.
Doing it without jQuery would involve recursively looping through the childNodes of each element and using either getComputedStyle (most browsers) or currentStyle (IE) to get the font information, then (if necessary) assigning to element.style.fontFamily.
Actually, a "both and" solution would probably be best. First, update the stylesheets, and then walk the tree to catch any inline styles. That way, presumably you'll get most of them by changing the stylesheets, which avoid the ugliness of the piecemeal update. Also, you don't have to use css() (jQuery) or getComputedStyle / currentStyle (without jQuery), you can just check element.style.fontFamily, so it would be more efficient.
Beware that IE's stylesheet object uses an array called rules, others use cssRules, but other than that they are largely the same.

It is possible to change only Arial using #font-face.
First link to a css:
<link rel="stylesheet" href="/css/fonts/luxi-Sans-fontfacekit/stylesheet.css" type="text/css" charset="utf-8" />
Then in your css refine what Arial is:
#font-face {
font-family: 'Arial';
src: url('luxisr-webfont.eot');
src: url('luxisr-webfont.eot?#iefix') format('embedded-opentype'),
url('luxisr-webfont.woff') format('woff'),
url('luxisr-webfont.ttf') format('truetype'),
url('luxisr-webfont.svg#LuxiSansRegular') format('svg');
font-weight: normal;
font-style: normal;
}
#font-face {
font-family: 'Arial';
src: url('luxisb-webfont.eot');
src: url('luxisb-webfont.eot?#iefix') format('embedded-opentype'),
url('luxisb-webfont.woff') format('woff'),
url('luxisb-webfont.ttf') format('truetype'),
url('luxisb-webfont.svg#LuxiSansBold') format('svg');
font-weight: bold;
font-style: normal;
}
Only Arial is changed (in my example to Luxi Sans). All other fonts remain as usual.

Related

Web Font Loader does not preload correct font

I am using the Web Font Loader to manage the loading of fonts in my code. But I'm finding that, even when I specify a bold weight for a particular font, the loader is only loading the normal weight in advance, and only subsequently loading the bold variant.
In the html:
<script src="https://cdnjs.cloudflare.com/ajax/libs/webfont/1.6.28/webfontloader.js"></script>
In the javascript:
var WebFontConfig = {
"timeout": 3000,
"classes": false,
"custom": {
"families": [
"TeX Gyre Adventor:700n"
],
"urls": [
"./css/fontstuff.css"
]
},
active: function () {
setTimeout(function() {
nowDoOtherStuff();
}, 2500);
}
};
WebFont.load(WebFontConfig);
In fontstuff.css:
#font-face {
font-family: 'TeX Gyre Adventor';
font-style: normal;
font-weight: 400;
src: url('../fonts/TexGyre/texgyreadventor-regular-webfont.woff2') format('woff2'),
url('../fonts/TexGyre/texgyreadventor-regular-webfont.woff') format('woff'),
url('../fonts/TexGyre/texgyreadventor-regular.otf') format('opentype');
}
#font-face {
font-family: 'TeX Gyre Adventor';
font-style: normal;
font-weight: 700;
src: url('../fonts/TexGyre/texgyreadventor-bold-webfont.woff2') format('woff2'),
url('../fonts/TexGyre/texgyreadventor-bold-webfont.woff') format('woff'),
url('../fonts/TexGyre/texgyreadventor-bold.otf') format('opentype');
}
So I am triggering my main function nowDoOtherStuff() off the active event hook, so according to my understanding by this point all the requested fonts should be available and ready... that's the point of Web Font Loader?
I put a delay of 2500ms so that it's clear in the Network tab what resources have actually been fetched when the active event fires, and what I see is:
Firstly, I'm not even requesting texgyreadventor-regular-webfont.woff2 so why is it being fetched at all?
Secondly, and most importantly, why is texgyreadventor-bold-webfont.woff2 (i.e. the font I requested) not actually fetched and ready when the active event fires? It's clear from the waterfall timing (and the artificial 2500ms delay) that the bold variant is only fetched after the active fires.
Why is Web Font Loader prioritizing the fetching of a font I didn't even ask for, and not fetching the font I actually want? This is causing issues with how the subsequent code lays out the content.
BTW this issue is solved by using a preload (which I have only more recently discovered) in the <head> as follows:
<link rel="preload" href="./fonts/TexGyre/texgyreadventor-bold-webfont.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
However, I would like to get the Web Font Loader approach working, without having to use preload... I thought that the Web Font Loader was already meant to be implementing a preload functionality?

ckEditor 4 not loading CSS file with custom fonts

I've implemented a custom font for CKEditor and although it is showing in the dropdown list it does not apply to the element. I cannot find the cause of why my CSS file isn't loading which is the cause of not applying the new font.
So, on my configuration default.js file I added the below lines of code:
config.font_names = 'Belluga Solid/Belluga_Solid;' + config.font_names;
config.contentsCss = "../fonts.css";
And then created a new fonts.css file:
#font-face {
font-family: "Belluga Solid";
src: local("Belluga Solid"), url("/MyFonts/Beluga/Belluga_Solid.eot") format("embedded-opentype"); /*non-IE*/
src: url("/MyFonts//Beluga/Belluga_Solid.ttf") format("truetype"); /*non-IE*/
src: url("/MyFonts//Beluga/Belluga_Solid.svg") format("svg"); /*non-IE*/
}
Looking at the source code, it correctly applies fine:
<p><span style="font-family:belluga_solid;">Lorem Ipsum</span></p>
It seems pretty straightforward to do. Looking at this tutorial the author got it all right: https://www.youtube.com/watch?v=knkFOuKPsKQ
I implemented the same solution but having a hard time figuring out how to solve the issue.
It's probably because the value of the font-family property in the element's styling doesn't match the value defined in the #font-face rule. The #font-face rule defined it as Belluga Solid, but your inline style sets the value to belluga_solid.
You can try modifying the #font-face rule so that it says this instead:
#font-face {
font-family: "belluga_solid";
}
That way, they will match and your font should hopefully display correctly.

Force the whole website use one font -family

I would like to apply
font-family: Helvetica to all element in the site.
So I write
body, html {
font-family: Helvetica !important;
}
in the CSS file, the problem is , the font-family is still override by other inner CSS. How to force the whole site use one font family?
Thanks a lot for helping.
Is it being overriden by other css style rules with !important? If so, there is nothing to do as more specific selectors win over more general ones.
* {
font-family: Helvetica !important;
}
You could use the inspector in chrome, or other browser's equivalent to see how the cascade styles on your particular element unfolds. Your inner CSS could have also defined the !important flag, which overrides you definition on body.
If you post your entire html and CSS people might be able to help more easily.

CSS for browser default font

If web designer has a full control over the entire code, it is easy to use browser default font - just don't change any font style and you got it.
However if there is not a full control over it and for example there is some font-related style defined on html or body element, or font-related CSS style for * { ... }, then there is a need to redefine font style to not inherit modified styling.
Is there any way, CSS, pure JavaScript or jQuery solution that would allow explicitly set browser default font for specific element?
Unfortunately, there is no simple "initial value" for font-family. It is, as you know, user-agent dependent.
Perhaps the closest you can come is by using a font keyword. font-family:serif; will use whatever the browser considers to be the default serif font. font-family:sans-serif; is the same, for sans-serif.
This is the closest I can suggest, sorry!
Yes. Do
.my-selector {
font: initial;
}
Well, I understand your requirement sounds simple but UNFORTUNATELY this is just a limitation of web technologies. We can not read browser's / system's font using either CSS or jQuery in any way.
The fonts rendered either by browser or system can not be read by web application. It is not designed that way. All we can do is apply font-family:serif or something similar to that.
I tried couple of POC for you but I could not retrieve the browser default settings.
All we can do is create a new ticket in W3C for font-family reset and let's keep hoping that they include something like that in future..
I would still do some digging for you and get back to you if I find something. This definitely is one very important requirement..
I dealt with such situations before but the other way. Just like overriding with the required font.. That's it!
However,
There is an alternative for this. I won't say it is the best way but we can try this :
Prpeare a JavaScript that reads the user agent, something like this..
var setDefaultFont = {
Android: function () {
$('*').css( "font-family", "//FONT USED IN ANDROID BROWSERS" );
},
BlackBerry: function () {
$('*').css( "font-family", "//FONT USED IN BLACKBERRY BROWSERS" );
},
iOS: function () {
$('*').css( "font-family", "//FONT USED IN iOS BROWSERS" );
},
Opera: function () {
$('*').css( "font-family", "//FONT USED IN OPERA BROWSERS" );
},
Windows: function () {
$('*').css( "font-family", "//FONT USED IN WINDOWS BROWSERS" );
}
};
We can be specific to Windows browsers if we need..
I know this is not the best solution but it should work
This has already been answered, but I found a solution that may be helpful:
*, html, body {
font-family: inherit !important;
}
This tells the root elements of the HTML document to inherit their font from the parent. In this case, the parent would be the browser's user agent styles, so your fonts will inherit from the default.
I've been coming across your questions on a somewhat regular basis it seems, and they appear largely theoretical cases. In any case, the others have more or less pointed you in the right direction, but I'm going to sound off just to re-enforce some points.
Explicit Means
There is no existing built-in functionality in Javascript nor CSS to explicitly assign the browser default font. This is outright impossible with the present CSS specification, however, you could, theoretically, utilize Javascript to get the name of the font for explicit use. I will not attempt to write the Javascript code because I predict it would be time consuming to accurately portray, but I will at least try to provide light on how it may be possible. Additionally, I under no circumstances am implying the following idea will work, but I believe it could work.
Conceptual Structure
I'd suggest the following:
Create 5 span nodes as following:
<span style="font-family: monospace;">Monospace Text</span>
<span style="font-family: sans-serif;">Sans-Serif Text</span>
<span style="font-family: serif;">Serif Text</span>
<span style="font-family: fantasy;">Fantasy Text</span>
<span style="font-family: cursive;">Cursive Text</span>
The five generic font families are the browser defaults, however this does not immediately resolve your question because a) it does not give us an explicit font-name that a person is using and b) the default font for a given element is one of these, not all of them.
Pay respect to the words "a person is using"; what the browser would have used by default versus what the user has set the default font to and subsequently sees by default is very different; this is why Rahul Patil's structure would be imperfect, despite I'll admit this was my original assumption and in most cases he would be absolutely correct.
Note
Certain elements default to different generic font families, and are not consistent from browser to browser. Code blocks, for example, are typically rendered as monospace by default. For consistency, you will need to utilize a CSS Reset file.
Use something like this to detect the font:
http://www.lalit.org/lab/javascript-css-font-detect/
This font detection is not ready for what you need out of the box, you need to modify it to parse a list of fonts and match it to the default. This script only shows the theory behind what may work for you; character dimension comparison, as typically all fonts are different in size in height and width, and that difference is easier to detect when the font size is large (hence why it uses 72 pixels).
Caveat
One major caveat I can think of is that this will typically only be able to detect ASCII / Romanized fonts and may not apply to Unicode sets; I'm sure you could modify it, but it may computationally intensive to accurately detect the font. You would likely retain a database of fonts applicable to each language, and you would need a consistent way to detect the language settings for the browser (and not the system); this is not easy, or even possible to my knowledge in a consistent way.
You can obtain an idea of the language settings using the "navigator.language" and "navigator.userLanguage" variables in Javascript, but these, to my knowledge reflect the system language and not the language used by the browser. Server side code would likely be necessary for this to be achieved with any degree of accuracy.
Build a Javascript routine to parse a list of fonts, and compare said fonts against the dimensions of the elements created in Item 1 of this list. You can get a list of fonts necessary to parse by using Flash. I'd suspect a Java applet would be able to do this as well. This may be helpful (JS+Flash):
https://github.com/gabriel/font-detect-js
http://font-detect.s3.amazonaws.com/index.html
This should, theoretically, give you the explicit font name used by the person. You could extend upon this and also get the default generic fonts for each individual element type (e.g. sans-serif, serif, monospace, fantasy and cursive), but I suspect this would be CPU intensive and would be best used with some of type of system level application; e.g. caching the given conditions for a given member, and create the CSS catered to that specific user.
Implicit Means
A number of people suggested some other means, Daniel Lisik in particular highlighted what I may do, with respect that is "serif" declaration is invalid in it's context, since declaring "sans-serif !important" would assign "sans-serif"; you can actually build up using "inherit !important" and make strict font-family changes with the given "font-family !important". For example:
<html>
<head>
<style>
div { font-family: Cursive; }
p { font-family: Inherit !important; }
.serif { font-family: Serif; }
.sans-serif { font-family: Sans-Serif; }
.serif-important { font-family: Serif !important; }
.sans-serif-important { font-family: Sans-Serif !important; }
</style>
</head>
<body>
<div>
Normal Div Text
<p>Default P Text</p>
<p class="serif">Serif</p>
<p class="sans-serif">Sans-Serif</p>
<p class="serif-important ">Important, Serif</p>
<p class="sans-serif-important ">Important, Sans-Serif</p>
</div>
</body>
</html>
"Normal Div Text" would be in "Cursive"
"Default P Text" would be in "Cursive"
"Serif" would be in "Cursive"
"Sans-Serif" would be in "Cursive"
"Important, Serif" would be in "Serif"
"Important, Sans-Serif" would be in "Sans-Serif"
If you need any clarifications, just ask and I'll edit as necessary.
References
http://www.w3.org/TR/CSS21/fonts.html#value-def-generic-family
http://www.w3.org/TR/CSS2/cascade.html#value-def-inherit
Resources
http://www.lalit.org/lab/javascript-css-font-detect/
https://github.com/gabriel/font-detect-js
http://font-detect.s3.amazonaws.com/index.html
Your question isn't very clear. I don't know if I've misunderstood but I will try to help anyway.
If you're really determined to respect the default browser fonts and font sizes set in the browser then this should do the trick:
html, body {
font-size: 100% !important;
}
body {
font-family: serif !important; /* Or sans-serif, monospace or whatever is appropriate. */
}
Then the inheritance should kick in, as long as you don't set font stacks or sizes on everything else.
Bear in mind, the cascade order comes into play here.
This would override all types of stylesheets except for user stylesheets containing !important declarations set on relevant elements. In this particular case, you just need to respect the user's choices.
Personally, I would just write this:
html, body {
font-size: 100%;
}
body {
font-family: serif; /* Or sans-serif, monospace or whatever is appropriate. */
}
Then I would refrain from setting font stacks on everything else simply because, if an user was really determined to have his own way, he's likely to have set !important declarations on the elements that matter to him, like fonts, etc in his own user stylesheet - and this will override a normal author stylesheet (which omits !important declarations).
The others are right, the initial keyword is a viable method as long as you're not worried about IE because, no version of IE supports it.
So I think your best bet is to look for a polyfill of some sort for IE, or create your own. Modernizer might be worth a look or if you want to create your own, there's polyfill.js. I don't know anything about creating polyfills, sorry!
I know it's not a perfect answer (it's 6am and I've been up all night), but I hope it helps you in some way.
P.S. I've just realised you might have been referring to hijacking a browser's settings to set the default font you want set, regardless of how the user has it set up. It would be pointless doing that. In any case, I don't think it would work if an user has his own user stylesheet especially if it has !important declarations set on the font properties.
You can try it in this way:
.element {
font-family: -webkit-body;
font-family: -moz-body
font-family: -o-body
font-family: body
}
And also try the following which is also working fine:
.element {
font-family: none;
}
Are you simply talking about element selectors?
div {
color: red;
}
input {
font-family: sans-serif;
}
As per my understanding, font-family: none; works fine for me in chrome and firefox.
.element {
font-family: none;
}
This code will inherit to default browser font.
Use a generic font-family. The browser will choose which font is "best" for him :)
font-family: serif;

Replace text with an image if font not available

I have a web page which uses a non-web-safe font (#font-face...) for a header.
This is going to look pretty bad if the viewer's browser does not support this, so is there a way to detect this capability and replace the text with an image if it is not supported?
#font-face {
font-family: 'awesomefont';
src: url('fonts/awesomefont-webfont.eot');
src: url('fonts/awesomefont-webfont.eot?#iefix') format('embedded-opentype'),
url('fonts/awesomefont-webfont.woff') format('woff'),
url('fonts/awesomefont-webfont.ttf') format('truetype'),
url('fonts/awesomefont-webfont.svg#awesomefont') format('svg');
font-weight: normal;
font-style: normal;
}
h1 {
font-family: 'awesomefont'; /* Substitute with image if font not supported */
}
p {
font-family: 'awesomefont', Arial, sans-serif; /* main body text can use alternative font */
}
#font-face {
font-family: 'Nosifer Caps';
font-style: normal;
font-weight: 400;
src: local('Nosifer Caps Regular'), local('NosiferCaps-Regular'), url('http://themes.googleusercontent.com/static/fonts/nosifercaps/v1/5Vh3eVJZ2pCbwAqfFmh1F3hCUOGz7vYGh680lGh-uXM.woff') format('woff');
}
p {
font-family: 'Nosifer Caps', cursive; // is this not the point of defining a websafe font after your non-websafe-font????
}
or do you want to ALWAYS have said font for your header.. in which case I wouldn't even go through the hassle of dealing with custom fonts. Just create your image and use that 100% of the time. The overhead of loading an entire font lib for one header image is just silly.
I'm not sure if there is a way to do what you're asking. But I generally use cufon for using custom fonts on my websites. It uses canvas to create an image from the text. If a browser does not support javascript, it simply displays the raw text
http://cufon.shoqolate.com/generate/
One option is to use one of the JS libraries which measure the width of the string to detect if the font is available. Unfortunately, functionality is not available in JS to do what you want directly.
Here are some implementations which use the string measurement technique:
http://derek1906.site50.net/works/jfont.php
http://www.lalit.org/lab/javascript-css-font-detect/

Categories

Resources