I'm finding Unicode for special characters from FileFormat.Info's search.
Some characters are rendering as the classic black-and-white glyphs, such as ⚠ (warning sign, \u26A0 or ⚠). These are preferable, since I can apply CSS styles (such as color) to them.
Others are rendering as newer cartoony emoji, such as ⌛ (hourglass, \u231B or ⌛). These are not preferable, since I cannot fully style them.
It appears that the browser is making this change, since I'm able to see the hourglass glyph on Mac Firefox, just not Mac Chrome nor Mac Safari.
Is there a way to force browsers to display the older (flat monotone) versions to display?
Update: It seems (from comments below) there is a text presentation selector, FE0E, available to enforce text-vs-emoji. The selector is concatenated as a suffix without space onto the character's code, such as ⌛︎ for HTML hex or \u231B\uFE0E for JS. However, it is simply not honored by all browsers (eg Chrome and Edge).
Append the Unicode variation selector character for forcing text, VS15, ︎.
This forces the previous character to be rendered as text rather than as an Emoji Symbol.
<p>🔒︎</p>
Result: 🔒︎
Learn more at: Unicode symbol as text or emoji
I had a Unicode character in the content of a span::before, and I had the font-family of the span set to "Segoe UI Symbol". But Chrome used "Segoe UI Emoji" as the font to render it.
However, when I set the font-family to "Segoe UI Symbol" explicitly for the span::before, rather than just for the span, then it worked.
For a CSS-only solution to prevent iOS displaying emojis, you can use font-family: monospace which defaults to the text variant of the glyph rather than the emoji variant:
<p>Normal character: ↩</p>
<p>Monospace character: <span style="font-family: monospace">↩</span></p>
If your primary concern is forcing monochromatic display so the emoji don't stand out from the text too much, CSS filters, either alone or in combination with the Unicode variation selector, may be something you want.
p.gscale {
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
}
a {
color: #999;
-webkit-filter: grayscale(100%) sepia(100%) saturate(400%) hue-rotate(170deg);
filter: grayscale(100%) sepia(100%) saturate(400%) hue-rotate(170deg);
}
<p class="gscale">You've now got emoji display on 🔒lockdown🔒.</p>
<p>External Link: celebrate 🎉</p>
Unlike the variation selector, it shouldn't matter how the emoji are rendered, because CSS filters apply to everything. (I use them to grayscale PNG-format "link type" icons on hyperlinks that have been modified to point to the Wayback Machine.)
Just mind the caveat. You can't override a parent element's filter in a child, so this technique can't be used to grayscale a paragraph, then re-colorize the links within it. 😢
...still, it's useful for situations where you're either going to be making the whole thing a hyperlink or disallowing rich markup within it. (eg. titles and descriptions)
However, this won't work unless CSS actually gets applied, so I'll give a second option which is more reliable in <title> elements than the Unicode variation selector (I'm looking at you GitHub. I don't like fake icons in my browser tabs):
If you're putting a user-provided string into a <title> element, filter out the emoji along with any bold/italic/underline/etc. markup. (Yes, for those who missed it, the standard does call for the contents of <title> to be plain text aside from the ampersand escapes and the browsers I tested all interpret tags within as literal text.)
The two ways I can think of are:
Directly use a manually-maintained regex which matches the blocks where the newest version of Unicode puts its emoji and their modifiers.
Iterate through the grapheme clusters and discard any which contain recognized emoji codepoints. (A grapheme cluster is a base glyph plus all the diacritics and other modifiers which make up the visible character. The example I link to uses Python's regex engine to tokenize and then the emoji package for the database, but Rust is a good example of a language where iterating grapheme clusters is quick and easy via a crate like unicode-segmentation.)
None of the other solutions worked for me but I eventually found something that did courtesy of css-tricks. In my use case, I was adding a link symbol at the end of each markdown header for direct linking to sections within articles but the emoji symbol looked a bit distracting. The following code allowed me to make the emoji look like a plain symbol and then switch back to looking like an emoji when hovered over which was perfect for my use case. If you just want to make the icon look more like a symbol just change the text-shadow hexadecimal color to #000 as shown in the second example.
.direct-link {
color: transparent;
text-shadow: 0 0 #dbe2ec;
}
.direct-link:hover {
color: inherit;
}
<h3>Blog Subheading🔗</h3>
.direct-link {
color: transparent;
text-shadow: 0 0 #000;
}
<h3>Blog Subheading🔗</h3>
Android fonts are not rich as you may expect.
Font files don't have these exotic glyph and Android has a hack for few characters without glyph. They are replaced with icons.
So solution is to integrate the site with a web font (woff).
Create new font file with FontForge and pick required glyph from free serif TTF for example. Every glyph takes 1k. Generate woff file.
Prepare simple CSS to import the custom font family.
style.css:
#font-face {
font-family: 'Exotic Icons';
src: url('exotic-icons.woff') format('woff');
}
.exotic-symbol-font {
position: relative;
top: 1px;
display: inline-block;
font-family: 'Exotic Icons';
font-style: normal;
font-weight: normal;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
index.html file:
<html>
<head>
<meta charset="utf-8">
<link href="style.css" rel="stylesheet"></head>
<title>Test custom glyphs</title>
</head>
<body>
<table>
<tr>
<td class="exotic-symbol-font">
😭 ☠ ♠ a g
</td>
</tr>
</table>
</body>
</html>
Google Chrome, desktop version 75, seems to disambiguate its approach to rendering Unicode characters based on the first Unicode escape it encounters while loading a page. For instance, when parsed as the first HTML Unicode escape in a page source, and having no emoji equivalent, ⏷ seems to clarify to Chrome that the page contains escapes not to be rendered as emoji.
Expanding upon ssokolow's answer, using a filter is nice and at least makes the contours visible instead of using a simple font, but converting an RGB color into a sequence of CSS filters is very hard when you want to use a specific color.
A better (although quite wordy) option is to use the <feColorMatrix> SVG filter. Combined with the grayscale filter and the data URI scheme, you can represent the color via RGB and in-line CSS:
.violet {
color: white;
filter: grayscale(100%) url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix type='matrix' values='0.78 0 0 0 0 0 0.082 0 0 0 0 0 0.522 0 0 0 0 0 1 0'/></filter></svg>#f");
}
Unfortunately, you cannot interpolate the URL with data (taken from attributes or variables), but at least you don't have to calculate CSS filters from RGB.
My specific version of the problem
My site is using the ◀︎ (BLACK RIGHT-POINTING TRIANGLE) and similar characters in CSS pseudo-elements (::after and ::before) to indicate the current item in a list.
In my tests, I always used the triangle character and the variation selector 15 together. First I was using both a webfont from Google Fonts and a font installed on the device that should both have contained the glyphs for those characters, but for some reason, this assumption must have been wrong. I also tried different subsets on Google Fonts, to no avail: Two of my android devices with Google Chrome and Samsung Internet (Chromium) always rendered the emoji instead of the text glyph.
My solution
My solution was to download the latest WOFF of the Gnu Free Font (which I knew to contain glyphs for those characters), include it in my project, and define it using #font-face:
#font-face {
font-family: "Free Sans";
src: url("/site/static/fonts/FreeFont/FreeSans.woff") format("woff");
}
Then, to set the styles for my pseudo elements:
span.current::after {
font-family: "Free Sans", $universal-font-family ! important;
}
Discussion
I'm not yet sure about the performance impact of using that 786K extra font just for those few characters. If that becomes a problem, it should be possible to use a stripped-down custom font with just those characters instead.
If none of the other answers work for you, it's possible you have one or more of these fonts in your font stack (as was the case for us):
Segoe UI Emoji
Apple Color Emoji
These are included in a number of commonly used font stacks, like the Github font stack if I'm not mistaken.
I dont know of a way to turn off the emoji type rendering. Usually I use an icon font such as font awesome or glyphicons (comes with Bootstrap 3).
The benefit of using these over the unicode characters is that
you can choose from many different styles so it fits the design of your site;
they are consistent across browsers (if you ever tried doing a unicode star character, you'll notice it's different in IE vs other browser);
also, they are fully stylable, like the unicode characters you're trying to use.
The only downside is that its one more thing for the browser to download when they view your page.
For me on OSX the solution was to set font-family to EmojiSymbols
None of the solutions above worked for the "Emoji for Google Chrome" Extension.
So as a workaround I made a screenshot of the Unicode Character 'BALLOT BOX WITH CHECK' (U+2611) and added it as image with php:
$ballotBoxWithCheck='<img src="pics/U2611.png" style="height:11px;margin-bottom:-1px">'; # ☑ or /U2611
See: https://spacetrace.org/man_card.php?tec_id=21&techname=multi-emp-vessel
Related
I use as font-family stack like this:
body{
font-family: icon, 'Merriweather Sans', ui-sans-serif, sans-serif;
}
with icon being an icon-font that has some symbols in it for example arrows, which can occur in copy text or headlines.
The icon font is loaded like this (simplified example):
#font-face {
font-family: 'icon';
src: url(icon.woff2);
unicode-range: U+1F872, ..., ...;
}
That way whenever the 'arrow bold to right' is used in a text it will be rendered in the icon font. It works well and is foolproof.
I also use (simplified example again)
p.text{
max-width: 70ch;
}
which ensures that text paragraphs don't have too many characters in one line for readability.
Firefox makes those text paragraphs a lot smaller than chrome. And after some experimenting, I found that FF uses the icon-font to determine the width of the zero while Chrome uses Merriweather Sans.
The icon font has no zero-glyph in it and would be hindered by its Unicode range to display one.
So at first glace it seems correct that Chrome calculates ch based on the first font-family in the stack that contains a zero and is allowed to render a zero.
On the other hand I'd think that for calculating the abstract ch unit one can argue that the actual presence ot the zero character isn't necessary. Also it should be perfectly ok if one would use one font only for displaying number (through Unicode-Range) while the next font displays letters. What font should be used for calculating the ch value then?
Can anyone tell me if one or the other browsers does it wrong and the other does it right?
And has anyone an idea for a good workaround?
I have the websafe font georgia that is beuatifull for what I want.
The only problem I am having is that the bottom of the font doesn't line up.
http://jsfiddle.net/JW7F8/
<style>
.georgia {
font-family:georgia;
font-size:1.9em;
}
</style>
<span class="georgia">
1234567890
</span>
As you can see in the fiddle is that the 1,2,6 and 8 all start a bit higher than the rest.
The question:
How can I render georgia that it all starts on one line whilst still being able to set the site with XXem.
I do not mind:
splitting up the string
setting different classes
I just need a workable solution that still allows for dynamic sizing.
This is just the style of the font, technically all the font characters line up (if you highlight the text it will show the height of the font character).
You won't be able to consistently line up Georgia font even by splitting the font because the offset will have to vary depending on font size. This could be possible using em's, but it would be hacky at least, and would be very difficult to get working consistently cross browser.
Also, changing the font position will cause Kerning issues.
However, there is another similar font which Georgia was influenced from, which does line up:
Georgia incorporates influences from Clarendon-style typefaces
http://en.wikipedia.org/wiki/Clarendon_(typeface)
For a websafe solution I ended up implementing this: http://jsfiddle.net/JW7F8/2/
<style>
.georgia {
font-family:georgia;
font-size:1.9em;
}
.subitx {
position:relative;
top:0.18em;
}
.subity {
position:relative;
top:0.13em;
font-size:1.2em
}
</style>
<span class="georgia">
<span class="subity">1</span><span class="subity">2</span>345<span class="subitx">6</span>7<span class="subitx">8</span>9<span class="subity">0</span>
</span>
Only shame is the fonts that are sized up are bolder than the rest.
I really wish there were more web safe fonts that work cross browser... sigh
The Georgia font has old-style digits, i.e. digits that vary in height and may extend below the baseline too.
Most fonts that people use on web page have modern-style “lining” digits, all digits being of equal height, roughly the same as uppercase letters.
Some fonts contain both. It has relatively recently become possible to choose between such alternatives in CSS, in several browsers, using font-feature-settings. But Georgia has only old-style digits.
It is best to choose a different font if you think that such a fundamental feature is not suitable for your text.
However, on WebKit browsers (Chrome, Safari), using #font-face (for local fonts, not embedded) and unicode-range, you could specify that digits be taken from another font. It’s technically simple but not really a good idea:
#font-face {
font-family: Georgiax;
src: local("Times New Roman");
unicode-range: U+30-39;
}
#font-face {
font-family: Georgiax;
src: local("Georgia");
unicode-range: U+0-29, U+40-10FFFF;
}
Then you would just use font-family: Georgiax as if it were a real font family. But as said, this technique is not supported by other than WebKit browsers, and taking digits from another font means a typographic blunder.
P.S. Georgia is not web-safe. No font is. You won’t find it on an Android, for example.
I have a css definition in the head of my page as follows:
#font-face {
font-family: "ownfont";src: url("../fonts/ownfont.ttf");
}
Then i give a css class to the body (on button click) which changes the font type from:
font-family: Verdana,Arial,Helvetica,sans-serif;
to
font-family: "ownfont",Verdana,Arial,Helvetica,sans-serif;
"ownfont" is a 4-character font where spaces and hypen will be shown in order to show some non-visual characters.
Firefox 3.6.3 shows everything as excepted (looks the same as before except for spaces and hypen), but Safari (on Mac and Win; Versions 4.0.5, 5.0) changes the heigth of my text lines (or at least it looks like that or as if a padding/margin has been increased - but nothing has been changed except for the font).
Why does this font setting yield to different results in firefox and safari?
Is there a way here to force both browsers to behave the same?
any help or suggestion is appreciated - thanks in advance
Try specifying line-height: 1ex; in your css.
If you know what font(s) you're going to be using it with, it might be simpler to remake your font to have metrics more like the others'.
My fonts of choice usually default to text figures
which is one reason I like them. However, for tables or headings I'd like to specify that lining figures should be used:
Is there a way to do so in CSS?
(To appease the search:
old-style numerals, text figures, non-lining figures, medieval numerals
lining numerals, titling figures)
Firefox 4.0 has basic text figure support. Here's how to turn on text (old-style) figures:
.text-figures {
-moz-font-feature-settings: "onum=1";
}
Looks like there's a set of css3 properties, such as font-variant-numeric, to control common properties. These are not yet supported by any browser, as far as I know.
Here's a jsFiddle where you can play around with the styles. It toggles between lining and old-style figures. I'm using Minion Pro on Windows 7, so you might have to find your own supported font on other platforms.
No, there's no such property in the CSS 2.1 specification. It's up to the web browser to chose a font available in the system and render it with whatever the ‘default’ style is.
A quick look in the CSS 3 Working Draft also doesn't reveal an option like this.
And although you can use the #font-face property in newer browsers, there doesn't seem to be an option to select OpenType features in general (like using lining or oldstyle figures).
A quick search revealed there has been a discussion about this on the W3 CSS mailing list.
Update: Inspired by Creating Custom Font Stacks with Unicode-Range I decided to give unicode-range property a try. Alas, you cannot change the lookup-table to use custom figures when normal figures 0-9 are used.
But, though it's not convenient to enter digits in high Unicode ranges (e.g. use the Unicode code converter), it is possible to use a specific set of figure, e.g. lining numerals for tables (and the fi-ligature as well):
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<title>Table numerals</title>
<style>
#font-face {
font-family: Calluna;
src: url(http://localhost/Calluna-Regular.otf);
}
body { font-family: Calluna }
#f { font-size: 32pt }
</style>
</head>
<body>
<p id="f">Table figures: </p>
</body>
</html>
OpenType features are now supported in many browsers:
font-feature-settings: 'lnum'
Old-style is also supported via 'onum'. You can omit the '=1' for boolean flags.
See Mozilla's description for more details, or this more thorough writeup of the various font features.
Try this..
body {
-moz-font-feature-settings:"lnum" 1;
-moz-font-feature-settings:"lnum=1";
-ms-font-feature-settings:"lnum" 1;
-o-font-feature-settings:"lnum" 1;
-webkit-font-feature-settings:"lnum" 1;
font-feature-settings:"lnum" 1;
font-variant-numeric: lining-nums;
}
I have the following CSS fragment:
INPUT{ font-family: Raavi; font-size: 14px;}
Which works fine when the textbox contains some Punjabi script like this: ਪੰਜਾਬੀ
But the user might enter English instead, and I would rather use the Verdana font with a different size, since the English letters in the Raavi font are real funky and the size is wrong.
So my question could be stated as:
Is there any type of conditional font-family and size selection within CSS based on the input
Is there anyway for CSS to know about the input language?
So I could create the following PSEUDO_CSS:
INPUT{ EN-font-family: Verdana; EN-font-size: 12px; PA-font-family; Raavi; EN-font-size: 14px;}
or
INPUT.EN{ font-family: Verdana; font-size: 12px;}
INPUT.PA{ font-family: Raavi; font-size: 14px;}
This is addressed in CSS3, and that's not going to help for compatibility with old browsers, but it works for me when mixing Greek and Latin text with different fonts for each. Here's an example taken from the CSS Fonts Module Working Draft:
#font-face {
font-family: BBCBengali;
src: url(fonts/BBCBengali.ttf) format("opentype");
unicode-range: U+00-FF, U+980-9FF;
}
The unicode-range bit is the magic key: that tells the browser to use this font-face statement only for this particular block of Unicode characters. If the browser finds characters in that range, it uses this font; for characters outside that range, it falls back to the next most specific CSS statement following the usual pattern of defaulting.
input { font-family: Verdana, Raavi, sans-serif; font-size: 14px;}
This should work for your purposes:
If the text is English, both fonts should contain the glyphs, and Verdana will be preferred
If the text is Punjabi, Verdana should not contain the glyphs, so the browser should fall back to Raavi
I'm not positive if all browsers will behave correctly, but that's what they should do according to the CSS spec.
A pure CSS solution might be as easy as:
input[lang=en] {
font-family:Verdana;
font-size:12px;
}
input[lang=pa] {
font-family:Raavi;
font-size:14px;
}
But it's still up to you to set the lang attribute of the input element.
Unfortunately, as with most fancy CSS features, attribute selectors are not 100% working across the array of browsers today. Your best bet in my opinion is to use a class per language and assign it to the input element.
Update:
Per your request, here's an example of a naive way to do it with vanilla JavaScript. There are certainly improvements to be made, but this "works".
<style type="text/css">
.lang-en {
font-family:Verdana;
font-size:12px;
}
.lang-pa {
font-family:Raavi;
font-size:14px;
}
</style>
<form>
<input type="text" onkeyup="assignLanguage(this);" />
</form>
<script type="text/javascript">
function assignLanguage(inputElement) {
var firstGlyph = inputElement.value.charCodeAt(0);
if((firstGlyph >= 65 && firstGlyph <= 90) || (firstGlyph >= 97 && firstGlyph <= 122)) {
inputElement.setAttribute('lang', 'en');
inputElement.setAttribute('xml:lang', 'en');
inputElement.setAttribute('class', 'lang-en');
} else {
inputElement.setAttribute('lang', 'pa');
inputElement.setAttribute('xml:lang', 'pa');
inputElement.setAttribute('class', 'lang-pa');
}
}
</script>
This example fires after a character has been typed. It then checks if it falls between a range considered "English" and assigns attributes accordingly. It sets the lang, xml:lang, and class attributes.
In your html tag you have that lang property.(just lang='en' or lang='en-EN')
We can use this in CSS.
If we want to give particular CSS for p tag for different language,
p:lang(en-EN){
}
The respective style we need to add.
This is the way that we can give particular css for different languages.
example
html{font-family: Raavi; font-size: 14px;}
html:lang(en-EN){font-family: Verdana; font-size: 12px;}
It is common practice when maintaining multi-lingual websites to use separate CSS files for each language. This is desirable because you will need to adjust more than the font. You will often need to adjust spacing to match the length of strings in the language. Also, you may need to adjust some of the basic formatting of the page in order to make it more natural to users of the language.
The robust answer is to internationalize and not to just settle for a different font because eventually you will find that font selection will be insufficient.
How could CSS know about the input language?
I'm afraid the only solution is to find a unicode font which looks pretty for both character sets. Which is far from perfect if your remote reader has not installed it. Maybe Arial Unicode MS.
The only reliable solution for now is to list the fonts in the desired order, as Miles indicated.
Hopefully the (correct) solution indicated by Zack might be properly supported by more browsers.
But even then it will be your responsibility to tag the various sections with the proper lang attribute.
Nothing can reliably detect the language of any text.