REM font size not adjusting below arbitrary threshold - css

In Safari 12.0.2 and Chrome 71.0.3578.98 on Mac Mojave 10.14.2, when setting the font-size using rem units, the actual size won't go below 9px.
See this example:
https://codepen.io/stephenjwatkins/pen/OrbGxL
My browser's font size is set to the default (16px) with a minimum font size set to 6px:
Setting text-size-adjust to none doesn't affect the problem. Firefox renders the size correctly.
The only thing that I've found to fix the problem is setting font-size: 0; to a parent element. For instance, if you add font-size: 0; to .container, the correct font size is rendered.
Does anyone know why it's not honoring the rem size below a certain threshold?

Chrome and its Blink rendering engine seem to have some non-obvious font-scaling rules. I'm unaware of any official comprehensive documentation, so let's go to the source.
(Note that I'm not an expert on Chromium internals generally or Blink renderer particularly. I've just been tracing through the source code and speculating on the most probable answers to the questions as posed.)
It seems to me that the engine calls upon the FontBuilder class during a redraw. This class has various dispatch methods that pass the DOM, zoom, and other relevant factors into what appears to be the crucial method: FontSize :: getComputedSizeFromSpecifiedSize. In that method, we see some juicy comments that address the points you've raised:
1. Why does setting font-size: 0; to a parent element fix it?
// Text with a 0px font size should not be visible and therefore needs to be
// exempt from minimum font size rules. Acid3 relies on this for pixel-perfect
// rendering. This is also compatible with other browsers that have minimum
// font size settings (e.g. Firefox).
2. Why is it not honoring the rem size below a certain threshold?
// We support two types of minimum font size. The first is a hard override
// that applies to all fonts. This is "minSize." The second type of minimum
// font size is a "smart minimum" that is applied only when the Web page can't
// know what size it really asked for, e.g., when it uses logical sizes like
// "small" or expresses the font-size as a percentage of the user's default
// font setting.
// With the smart minimum, we never want to get smaller than the minimum font
// size to keep fonts readable. However we always allow the page to set an
// explicit pixel size that is smaller, since sites will mis-render otherwise
// (e.g., http://www.gamespot.com with a 9px minimum).
3. For the curious, what are these minimum values when given relative units (eg x-small)?
// Strict mode table matches MacIE and Mozilla's settings exactly.
static const int strictFontSizeTable[fontSizeTableMax - fontSizeTableMin +
1][totalKeywords] = {
{9, 9, 9, 9, 11, 14, 18, 27}, {9, 9, 9, 10, 12, 15, 20, 30},
{9, 9, 10, 11, 13, 17, 22, 33}, {9, 9, 10, 12, 14, 18, 24, 36},
{9, 10, 12, 13, 16, 20, 26, 39}, // fixed font default (13)
{9, 10, 12, 14, 17, 21, 28, 42}, {9, 10, 13, 15, 18, 23, 30, 45},
{9, 10, 13, 16, 18, 24, 32, 48} // proportional font default (16)
};
// HTML 1 2 3 4 5 6 7
// CSS xxs xs s m l xl xxl
// |
// user pref
Interestingly, and a bit of an aside, the FontBuilder class dispatches to TextAutosizer :: computeAutosizedFontSize to scale the font size. This method uses hard coded values and a variable scaling factor:
// Somewhat arbitrary "pleasant" font size.
const float pleasantSize = 16;
// Multiply fonts that the page author has specified to be larger than
// pleasantSize by less and less, until huge fonts are not increased at all.
// For specifiedSize between 0 and pleasantSize we directly apply the
// multiplier; hence for specifiedSize == pleasantSize, computedSize will be
// multiplier * pleasantSize. For greater specifiedSizes we want to
// gradually fade out the multiplier, so for every 1px increase in
// specifiedSize beyond pleasantSize we will only increase computedSize
// by gradientAfterPleasantSize px until we meet the
// computedSize = specifiedSize line, after which we stay on that line (so
// then every 1px increase in specifiedSize increases computedSize by 1px).
const float gradientAfterPleasantSize = 0.5;
From these facts, we see there are a good number of hard-coded pixel values, with 9 and 16 being commonly sprinkled about the relevant code. These hard-codes, the presence of several rules to scale the font down to a limit, with the ability to override using font-size all seem to match the observations and suggest it's behaving as intended -- if not necessarily intuitively.
Also, I've found that the most recent comment posted in Chrome bug #319623 very much resembles your report.
Possibly related: when using relative units on the html tag, rem-based values defined elsewhere will have a lower bound of 9px.
See CodePen: http://codepen.io/larrybotha/pen/wKYYXE
Workaround: absolute unit on html, em unit on body. rems everywhere else.
It may be prudent to watch that bug for further developments, though maybe not with breath held. The last update was in 2015.

Related

OpenCL global worksize and offset question

Let's say the global work size is 32, and I set the offset as 1. Does this mean that get_global_id(0) would start from 1 and end at 31, making the effective global work size to 31 rather than 32?
If I want to retain the total global work size as 32, should I specify the global work size as 32+1 for when I set the offset to 1?
If you set the global work size as 32 and set the offset as 1, get_global_id(0) will start from 1 and end at 32. The global work size specifies the NDRange size and the offset does not change it.

What does generate_anchor_base()'s arguments mean?

Github page
Looking generate_anchor_base method, which is Faster R-CNN util method in ChainerCV.
What is the base_size = 16? I saw in the Documentation that it is
The width and the height of the reference window.
But what does "reference window" mean?
Also it says that anchor_scales=[8, 16, 32] are the areas of the anchors but I thought that that the areas are (128, 256, 512)
Another question:
If the base size is 16 and h = 128 and w=128, Does that mean anchor_base[index, 0] = py - h / 2 is a negative value?
since py = 8 and and h/2 = 128/2
The method is a util function of Faster R-CNN, so I assume you understood what is the "anchor" proposed in Faster R-CNN.
"Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks" https://arxiv.org/abs/1506.01497
base_size and anchor_scales determines the size of the anchor.
For example, when base_size=16 and anchor_scales=[8, 16, 32] (and ratio=1.0), height and width of the anchor will be 16 * [8, 16, 32] = (128, 256, 512), as you expected.
ratio determines the height and width aspect ratio.
(I might be wrong in below paragraph, please correct if I'm wrong.)
I think base_size need to be set as the size of the current hidden layer's scale. In the chainercv Faster R-CNN implementation, extractor's feature is fed into rpn (region proposal network) and generate_anchor_base is used in rpn. So you need to take care what is the feature of extractor's output. chainercv uses VGG16 as the feature extractor, and conv5_3 layer is used as extracted feature (see here), this layer is a place where max_pooling_2d is applied 4 times, which results 2^4=16 times smallen feature.
For the another question, I think your understanding is correct, py - h / 2 will be negative value. But this anchor_base value is just a relative value. Once anchor_base is prepared at the initialization of model (here), actual (absolute value) anchor is created in each forward call (here) in _enumerate_shifted_anchor method.

how to get the current widget's cursor size in pixels

How to get the current mouse cursor size measured in pixels? I tried mywidget.cursor().pixmap().size() but it returns (0,0) for the standard arrow cursor.
(I need this to show a special tool tip label which would appear just below the cursor and would follow the cursor and I cannot use the standard QToolTip for certain reasons - delays etc. I already have a nice, working solution but if I display the label exactly at the cursor position, the cursor is painted over it hiding some text on the label. Of course I could move it down using some 'magic' number like 32 pixels, but this would cause me bad stomach feelings.)
You can't do this with the standard cursors. The QCursor methods only work with custom bitmaps or pixmaps. So you will either have to use your own cursors, or estimate the size.
A quick web-search suggests that the standard cursors can vary in size and there is no fixed maximum (although that probably depends on the platform). For example, on X11, the size range usually includes 16, 24, 32, 48, and 64, but other sizes may be possible (even as large as 512). The default is normally 32.
If you need accuracy, it would seem that using custom cursors is the only way to solve this problem.
You could use the code that is used in QTipLabel::placeTip, which offsets tooltips based on cursor size:
const int screenIndex = /*figure out what screen you are on*/;
const QScreen *screen = QGuiApplication::screens().value(screenIndex, QGuiApplication::primaryScreen());
if (const QPlatformScreen *platformScreen = screen ? screen->handle() : nullptr) {
QPlatformCursor *cursor = platformScreen->cursor();
const QSize nativeSize = cursor ? cursor->size() : QSize(16, 16);
const QSize cursorSize = QHighDpi::fromNativePixels(nativeSize, platformScreen);
}
To do this you do need at least one private header:
#include <qpa/qplatformscreen.h>
#include <qpa/qplatformcursor.h>
#include <QtGui/private/qhighdpiscaling_p.h>
If it doesn't have to be portable you can look at the size implementation of the QPlatformCursor implementation for the platform you're targeting (e.g. QWindowsCursor::size()) and use that code.

Display two object same real distance (e.g. inches) apart across different browers / screen sizes

I'm developing a psychology experiment in the browser. In order to keep the same viewing angle across people, I want to display two characters around 5 inches apart on the screen.
Is there any way to detect the real size of the monitor being used, and using the screen resolution and DPI, render the two objects the same real width apart? (I will only allow people that have real computers, e.g. not mobile)
I heard detecting real size may not be possible, if true, and assuming people will report to me the real size of their monitor, is this possible?
I'm using HTML5 Canvas, fwiw. Perhaps resizing this canvas w.r.t to the resolution and DPI is a solution.
No, unfortunately. The browser will always report 96 DPI. Without actual DPI you cannot produce exact measures in other units than pixels.
Even if you could the browser would only reflect the system DPI which in itself is just an approximation.
You need to "calibrate" for the individual device providing a mechanism to do so, e.g. a scale that can be varied and measure on screen. When it measures 1 inch you know how many pixels covers that inch, and then this value can be used as a scale for the rest.
Example on how to get screen DPI via "calibration"
var ctx = document.querySelector("canvas").getContext("2d"),
rng = document.querySelector("input");
ctx.translate(0.5, 0.5);
ctx.font = "16px sans-serif";
ctx.fillStyle = "#c00";
render(+rng.value);
rng.onchange = rng.oninput = function() {render(+this.value)}; // update on change
function render(v) {
ctx.clearRect(-0.5, -0.5, 600, 300);
ctx.strokeRect(0, 0, v, v);
ctx.fillText(v + " PPI", 10, 20);
// draw marks which should be 4 inches apart
ctx.fillRect(0, 0, 3, 150);
ctx.fillRect(96*4 * (v / 96), 0, 3, 150); // assuming 96 DPI base resolution
ctx.fillText("------ Should be 4 inches apart ------", 50, 140);
}
<label>Adjust so square below equals 1 inch:
<input type=range value=96 min=72 max=145></label>
<canvas width=600 height=300></canvas>
This example can of course be extended to take a vertical parameter as well as considering pixel aspect ratio (ie. retina displays) and scale.
You need to then build all your objects and graphics using a base scale, for example 96 DPI. Then use the relationship between the actual DPI and 96 DPI as a scale factor for all positions and sizes.

minWidth setting ignored in flex 3.5?

I've done a bit of a search but couldn't find an answer to this question.
For example:
sampleComponent.explicitMinWidth = 500;
sampleComponent.explicitWidth = 10;
Sets the width of the sampleComponent to 10, even though I've set the minimum width to 500.
The same thing seems to happen with width. In Adobe's documentation, it states that 'measuredMinWidth - Specifies the default minimum height and minimum width of the component, in pixels. Flex cannot set the size of a component smaller than its specified minimum size.'
I've tried setting the measuredMinWidth as well, same result.
Eventually, I tried every combination of minimum width settings I could, but they were all ignored when I set the width (or explicit width).
sampleComponent.measuredMinWidth = 300;
sampleComponent.minWidth = 300;
sampleComponent.explicitMinWidth = 300;
sampleComponent.width = 10;
Additionally, what is the difference between width and explicitWidth, in every case I've tried, they have performed identically (couldn't find any help on this either)
The min/max values are considered only when flex is calculating the size of the component. If you explicitly set values to width/height yourself those values will be ignored.
Which brings us to the issue of explicit: size of a component may be set by either specifying a fixed value, or a percentage. When setting a fixed value (in mxml) for width/height, that value gets saved in explicitWidth, explicitHeight etc, while percentages get stored in percentageWidth, percentageHeight and so on...
More info about this can be read on the adobe livedocs.

Resources