How to calculate descender height in javascript? - javascript

My css has defined the font-family to cascade depending on what fonts are available:
.myfont {
text-transform: uppercase;
font-family: Calibri, Arial, sans-serif;
padding: 2em;
background-color: red;
}
and, depending on what font is rendered, I would like to adjust the padding to appropriately center the all-caps text in the <sarcasm>beautiful</sarcasm> red background. Is there a good way to calculate the size of the font descender so that I can adjust the bottom padding accordingly?
Bonus points for solutions that also calculate the ascender height, cap height, and x-height.
Thanks in advance!

This is possible: use this library: baseline ratio, or typography.js Insert two spans into a container div, with 0px font size and a large font size like 100 or 2000, call getBoundingClientRect();, get difference in height, and divide by the bigger ones height. The 0 px font lies on the baseline. This gives baseline ratio, percentage of ascender and descender.

AFAIK that's not possible with JavaScript. You may be able to find out the used font, but not the font parameters.
So you will need to search for these parameters (e.g. in font libraries) and store them by-font so that you can look them up once you know the used font.

A web dev agency called EightShapes have put together a tool that lets you generate CSS to crop away the space above and below text and so make layouts that work well around ascenders and descenders. There's an accompanying blog post about it.

Related

How do I scale the time font size based on the size of the time picker?

HTML and CSS
.pickthetime {
height: calc(var(--vh, 1vh) * 3);
width: calc(var(--vw, 1vw) * 25);
align-content: center; // center looks better, also tried left to stop it from breaking a new line on Safari on iOS
font-weight: 300;
}
<input class="pickthetime" type="time" id="pickthetime" name="pickthetime" required />
I have the actual picker set to a certain size as you can see on the CSS. No matter what I do, I can't seem to scale the font size automatically based on the size of the time picker. If I increase or decrease the font size too much using calc(var(--vw, 1vw) * somenumberhere) it's always too big or too small on some devices. Some font sizes work well on my Android phone, but then it won't work with my iPhone 11 or (using the Chrome device toolbar) iPhone X.
I have also tried to use FitText but the same issue occurs. It does scale a bit better on Chrome (using device toolbar) or on my Android phone.
I...don't know what to try from here. What works on 1 device, doesn't work on the other 2. All I want is for the font size of the time to render according to the width of the time picker (but I don't want it to become hidden by the little clock icon that browsers like Chrome or the arrow down icon that browsers like Safari on iOS use).
I would suggest not using vw/vh for styling the input, and instead using rem or another relative length unit.
This is why you're having trouble with mobile/desktop scaling: because the scale of the viewport width/height is so different between devices.
Using for example height: 1.25rem keeps the height relatively static across devices, depending on the root font-size property at a given breakpoint.
Assigning a rem value as the font-size of the input itself will likewise scale with the root element's font-size, and make it easier for you and other developers to understand the relationship between the input's height and its font-size.
Example:
/* Let's say the <body> has a font-size of 20px */
body {
font-size: 20px; /* 20px = 1rem */
}
.pickthetime {
font-size: 1rem; /* or 1x body's font-size = 20px */
height: 1.5rem; /* or, 1.5x body's font-size = 30px */
/* I would suggest not setting a width; if you do,
set a max-width as well, or style the containing
element with a set width/max-width */
width: 100%;
max-width: 300px;
}
In the above example, you can now tell that the font size will be the same as the rest of the text, and also that the height of the input element will be 1 and a half times the size of your text.
If you set the height of the field based on vh, you need to set the font size the same way. Font size is a height, not a width. If you set the width, depending on the width of the form field your text will either be too tall or too short for the box. I'm not really sure how you would want the form field to look when the shape of the text doesn't match the geometry of the form field.
I know this isn't really an answer, but the problem you've described has no solution. For a change that would help you can refer to another answer but I don't want to just say "Do this instead" because there are a lot of options depending on what you want.

Div text vertical padding

I've noticed that as fonts get larger and larger, the vertical padding in a div element above and below the text grows larger. Is there anyway quick way to prevent this? Is this font dependent?
I'm attempting to create a word cloud, but these vertical spacings are proving to be quite annoying.
Here is an example:
You can use the line-height style rule to change the amount of space around the text
Setting the line-height is your answer but I would recommend the em unit and setting the line-height to 1em for all font sizes in your tag cloud. I always use em's to represent line-height because regardless of whether the font is set by pixels, ems, or some other unit, line-height is always relative to the size of the font.
According the the W3C specification for line-height
A value of 'normal' sets the 'line-height' to a reasonable value for
the element's font. It is suggested that UAs set the 'normal' value to
be a number in the range of 1.0 to 1.2.
This means the font size can vary but the vertical height of the fonts will always remain consistent and relative to the corresponding size.
Try in your css:
line-height: 20px;
You could research for some already done word clouds.
Or just put classes to the different sizes, and so you can put negative padding to the bigger sized words.
.span bigger {
font-size:2 em;
padding: -4px;
}
.span big {
font-size:1.5 em;
padding: -2px;
}
.span small {
font-size:0.9 em;
padding: 0;
}
Hope it helped or at least gave you some cool ideas! ;)

How do I vertically fill a container with uppercase text using JS/CSS?

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.

Different fonts inside a label

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...

Always same line-height?

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.

Categories

Resources