I would like to add appropriate kerning between two fonts. Specifically, I currently have (two examples):
div.hw_count {
display: inline-block;
vertical-align: middle;
}
div.hw_count p {
font-style: italic;
font-family: Arial;
font-size: 80px;
}
div.hw_count_separator {
display: inline-block;
vertical-align: middle;
}
div.hw_count_separator p {
font-family: Arial;
font-size: 30px;
}
<div class="hw_count"><p>1</p></div>
<div class="hw_count_separator"><p>x</p></div>
<span style=padding:20px></span> <!-- just to space examples apart -->
<div class="hw_count"><p>2</p></div>
<div class="hw_count_separator"><p>x</p></div>
The issue is I'd like the spacing between the number and the 'x' to appear similar for all digits. It clearly looks greater for the number '1' (and sometimes appears even more distinct when I change font weight/family/style).
I don't suspect there is any way to do some magical kerning given that in my example the digit and 'x' are in different divs. But, is there any simple CSS-only way to decrease the right blank space appropriately for the given font/digit?
My only solution right now would be to tweak with javascript for each digit (I likely only have to tweak for digit '1'). However, I suspect this may break if I change fonts - I'd hate to have to re-tweak.
tl;dr; probably not worth the effort in code, I'd just apply a class for that special instance or search for the element by content, in jQuery it might look like $('.hw_count p:contains("1")'); and set a special class for that.
Actual text metrics are a little elusive. Using the most precise tool we have at our disposal, canvas, even then you can only consistently get width (without a library). But, width is the same for characters that are thinner than a certain dimension (this is a characteristic of the font family). The width of "1" and "2" are the same in in the fonts I tested: Arial, Verdana, and Times: http://codepen.io/anon/pen/zrjxQM
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.font = '80px Arial';
var text = ctx.measureText("1");
console.log('1: ' + text.width);
text = ctx.measureText("2");
console.log('2: ' + text.width);
text = ctx.measureText("M");
console.log('M: ' + text.width);
text = ctx.measureText("10");
console.log('10: ' + text.width);
The above code yields:
1: 44.4921875
2: 44.4921875
M: 66.640625
10: 88.984375
The attributes that might help are actualBoundingBoxRight and actualBoundingBoxLeft but those are only experimentally supported in Chrome:
https://developer.mozilla.org/en-US/docs/Web/API/TextMetrics and even then, I suspect they will report the same as above.
You might also try a library like http://fabricjs.com/docs/fabric.Text.html or a pure JS solution as demonstrated here http://galacticmilk.com/journal/2011/01/html5-typographic-metrics/#measure all of which would likely report and calculate based on the same "bounding box" that exists around the characters.
You might also be able to produce an image from a canvas, then measure the actual pixels but, that's so much work for a little gain.
Related
I have a text that is uppercase, e.g. ABC.
As it is uppercase, all characters have the same height.
I also have a container (div) with fixed height, e.g. 100px.
How do I make this text fill it vertically, so each letter is exactly 100 pixels high?
I tried font-size: 100px, but it does not fill the container (there are gaps above and below).
See http://jsfiddle.net/6z8un/1/ for an example.
UPDATE 1:
Let's assume all characters actually have the same height (difference either does not exist or is negligible). Otherwise the question does not make much sense.
UPDATE 2:
I am pretty sure it can be solved using https://stackoverflow.com/a/9847841/39068, but so far I had no perfect solution with it. I think ascent and descent are not enough, I would need something else for the top space.
line-height http://jsfiddle.net/6z8un/2/ will not solve the problem because this will not remove the whitespaces. You could apply the size by hardcoding (for me it fits with font-size of 126px) But this is different to every user (sans-serif can be configured by user/system/browser)
Windows default sans-serif font MS sans serif is different to Droid sans serif on Android or DejaVu Sans on Ubuntu.
To solve this problem, you could set a font to default, like Times New Roman, but not every system does have this font by default.
To solve this, you could use a custom font imported from a server like htttp://google.com/fonts
but not every browser does support custom fonts.
I think the only way to solve this is to use an image.
But custom fonts should do their job on modern browsers too :) (e.g.: http://jsfiddle.net/6z8un/5/ )
Is this ok?
http://jsfiddle.net/6z8un/4/
HTML:
<div><span>ABC</span></div>
CSS:
div {
height: 100px;
background-color: #ddd;
font-family: sans-serif;
}
span {
font-size:136px;
margin-top:-25px;
display:inline-block;
};
Use this code. I hope this can help you.
<div class="outer"><div class="inner">ABC</span></div>
.outer {
margin: 0;
padding: 0;
height: 75px;
overflow-y: hidden;
}
.inner {
font-size: 100px;
background-color: #ccc;
font-family: sans-serif;
margin-top: -18px;
}
Note: As I know whenever we use font-size the upper and lower gap is also the part of height. I mean font-size = upper gap + actual height of font + lower gap. So if we want 100px div then use font-size larger than 100.
So far I made a small script that measures letter heights using canvas (would be a good thing to put on GitHub I suppose).
It is currently slightly unprecise, mostly because of caching.
I have published it as a library on GitHub, see here: https://github.com/ashmind/textmetrics.
Unfortunately I did not have time to make demo work as a GitHub page yet, so I can't link to it.
in my project I need to right some big text, so in my css file I wrote:
#wrong_answer
{
color: red;
font-size: 30;
font-weight: bold;
}
and in my js file:
function wrong_answer()
{
$("body").append("<p id='wrong_answer'>Is not correct</p>");
};
and finaly I got red text, but very-very small and if I change font-size the size of text doesnt changes.
so question is why cant I change font-size?
30 what? 30px, 30pt, 30%, 30em? You have an invalid property value there.
When using jQuery you can specify just an integer but that's because jQuery treats integers like pixel values, e.g.:
//this will work
$([selection]).css({ fontSize : 30 });
Here are some great docs for font-size: https://developer.mozilla.org/en-US/docs/Web/CSS/font-size
UPDATE
You can use your developer tools (Chrome/Firefox/Safari for sure) to inspect the CSS associated with an element. When an invalid property value is encountered, these developer tools will alert you to the fact.
You need to specify the "unit of size" . . .
font-size: 30px;
The CSS declaration font-size: 30 is invalid and ignored by conforming browsers. If you mean pixels, you need to say that:
font-size: 30px
Read this page for better understanding about fonts.
http://www.w3schools.com/css/css_font.asp
Should be font-size: 30px or something similar. You need to specify the unit type.
If I have labels such as "1234B", "5678M"... How can I change this label so the letter at the end is smaller size than the size of numbers?
<p>1234<span class="smaller">B</span></p>
.smaller {
font-size: 5px;
}
The simplest way is to use the small element (which is still allowed in HTML5, though with contrived “semantics”, but to browsers it still means just smaller font size):
1234<small>B</small>
You can then use CSS to tune the font size reduction, e.g. with
small { font-size: 80%; }
However, this produces typographically bad results, since different font size implies different stroke width, so the letters will look thinner, too, in addition to being smaller. In typography, one would probably use small-caps glyphs of the font instead (though in typography, one would normally rather try and make digits and letters match in size, rather than unmatch!). This is in principle possible on web pages too (using font-feature-settings: "smcp", with prefixes), though still rare, and it requires a font that has such glyphs available (like Calibri, Cambria, or Palatino Linotype).
watson has it.............. but let me think CMS thinking......if you just want to lowercase the only letter and the numbers stay put you can do this:
HTML:
<div style="text-transform: lowercase;">3529M</div>
or
<div class="lowMe">3529M</div>
<div class="lowMe">5546D</div>
CSS:
.lowMe {text-transform: lowercase}
else I would just do span as it was mentioned...
Is there any solution that the height between two lines are always the same?
I mean that text with font size 14px and font size 19px have the same distance.
In the attachted picture you can see an example.
Yup, CSS line-height. See MDN.
E.g.:
.big {
font-size: 19px;
line-height: 19px;
}
.small {
font-size: 14px;
line-height: 19px;
}
A better solution for keeping line height consistent would be to style the body tag with your desired heights. **Note as a rule of thumb you should only be using pt and em in sizing your font/leading (leading is the typography term for line height)
body{
font-size: Xem;
line-height: Yem;
}
Then when you have certain sections that need different leading values you can style them with a class like CSS is suppose to be used.
.tightStory{
font-size: Xem;
line-height: Xem;
}
.looseStory{
font-size: Xem;
line-height: Zem;
}
Hope this helps
You can set line-height to a specific value, even in pixels, e.g. * { line-height: 21px }, though this is very rigid and tends to cause problems sooner or later. For texts in, say, font sizes of 14px and 19px, you should really use different line heights. If you explain why you would want to use the same line height, there might be a good solution to the original problem.
Setting line height does not set consistent spacing as in your image, which shows the distance between the baseline of text and the uppercase top line of the next line. Line height is the distance between baselines of text. The visual empty space between lines varies by font and by characters (think about lines containing letters like a, x, s only versus lines containing loads of characters like Ê, Å, g, Q). The uppercase top line, i.e. the maximum level of uppercase letters without diacritics, varies a lot by font.
Here's the thing. I use 'Highlight.js' (a javascript-based automatic syntax highlighter) to syntax-highlight code on my website. But it doesn't support line numbers or zebra-striping (for alternate lines of code).
My code block is wrapped in <pre><code> blocks like this:
<pre><code>
<script type="text/javascript">
// Say hello world until the user starts questioning
// the meaningfulness of their existence.
function helloWorld(world) {
for (var i = 42; --i >= 0;) {
alert('Hello ' + String(world));
}
}
</script>
<style>
p { color: pink }
b { color: blue }
u { color: "umber" }
</style>
</code></pre>
And the output looks like this:
Now I want to show line numbers for the code block dynamically using JavaScript. How do I do that? (Also, if possible, how do I show zebra-striping?)
Thanks.
PS: I don't know JavaScript, so please try to be as clear as possible. I will try my best to understand. Thanks.
You could use an alternate framework such as http://alexgorbatchev.com/SyntaxHighlighter/
Or take a look here and find something that suites.
http://www.1stwebdesigner.com/css/16-free-javascript-code-syntax-highlighters-for-better-programming/
The basic steps would be:
Take the HTML inside the element.
Split by newline characters (\n).
For each string, add a number and a dot in front of it.
Combine the strings again with newline characters.
Set the string as the HTML of the element.
However, this would mess up the syntax highlighting of the syntax highlighter because it most likely won't recognize that the code has line numbers in front. So the syntax highlighter needs to provide the functionality of line numbers for you.
Adding a new answer to an old question.
I wanted to display line numbers in the left margin the way ace.js does.
My solution has some hacky details, but I wanted to share it anyway, because it turns out that absolute-positioned spans within relative-positioned spans work pretty well for this.
Encouraged by the above answers and this answer about relative positioning without taking up space, I used:
var line = 1;
code = code.replace(/^/gm, function() {
return '<span class="line-number-position"><span class="line-number">' + line++ + '</span></span>';
});
The regular expression /^/gm "replaces" the beginning of each line with the span-within-span.
is a zero-width space, because apparently firefox seems to have trouble deciding whether to put a zero-height span at the top or the bottom of the character.
line-number-position and line-number are CSS classes like these:
.line-number-position {
position: relative;
top: 0;
}
.line-number {
position: absolute;
text-align: right;
right: 17px;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;
font-size: 12px;
}
Yes, there are some magic numbers in there to match ace formatting, but the point is to put a relative-positioned zero-sized span at the beginning of each line and use it as a reference point to add an absolute-positioned span out in the left margin.
Works on current Chrome, Safari, Firefox, and Opera.