
A div that looks different in every browser - shdon
https://twitter.com/martijn_cuppens/status/1015169981368225793
======
systoll
Here's an animated version with some transparency
[https://codepen.io/anon/pen/PaMVYX?editors=0100](https://codepen.io/anon/pen/PaMVYX?editors=0100)

The root issue is that the browsers are being asked to draw a line that's
100px in from the edge of a 100px box -- it's an impossible task, so there's
no perfect solution.

This CSS test suite [http://test.csswg.org/suites/css-ui-3_dev/nightly-
unstable/x...](http://test.csswg.org/suites/css-ui-3_dev/nightly-
unstable/xhtml1print/outline-013.xht) suggests that browsers should treat it
as though it were the largest offset that made sense at the current outline
width, giving you
[https://codepen.io/pjwdev/pen/vrovPR?editors=0100](https://codepen.io/pjwdev/pen/vrovPR?editors=0100)

Safari achieves this if the border is the same colour the whole way around,
but doesn't get the individual sides in a sensible arrangement.

Edge doesn't match the test, but it does another reasonable thing -- it takes
the offset as a given, and uses the biggest outline width that makes sense.

Chrome and firefox...

~~~
gsnedders
The negative value case is:

> Negative values must cause the outline to shrink into the border box. Both
> the height and the width of outside of the shape drawn by the outline should
> not become smaller than twice the computed value of the outline-width
> property, to make sure that an outline can be rendered even with large
> negative values. User Agents should apply this constraint independently in
> each dimension. If the outline is drawn as multiple disconnected shapes,
> this constraint applies to each shape separately.

There's a lot of RFC 2119 SHOULD there, unfortunately.

------
nadsumatal
Joke: A man walks into a picture framing shop and says: "I'd like a 10cmx10xm
frame for my 10cmx10cm picture, but make it negative 12.5cm away from the
picture." The shop staff is confused, but makes a wild guess: "So you want a
frame with each border 2.5cm on the other side of the picture than it would
normally be?" The man just takes a note and goes to another shop.

He collected the wild guesses from various picture framing shops and posted
them on twitter, getting a lot of attention on Hacker News as well.

edit: present tense.

~~~
hlmencken
This sort of badinage is what makes HN so endearing. Thanks!

------
KwanEsq
And here's what it looks like in Servo:
[https://i.imgur.com/lv3xRhi.png](https://i.imgur.com/lv3xRhi.png)

~~~
kibwen
I was 50/50 on whether this would be a legitimate rendering or a cheeky
screencap of a panic message. :P

~~~
KwanEsq
What I found interesting was that I later noticed Matt Brubeck had already
done the same thing a couple of days earlier [0], yet mine in the nightly I'd
just downloaded was already different.

[0]
[https://twitter.com/mbrubeck/status/1015310959789740032](https://twitter.com/mbrubeck/status/1015310959789740032)

------
dopamean
On one hand I think this is really neat. On the other this is why I have never
taken front end development seriously enough to spend any real time learning
it [0]. From the get go it always seemed like the rules were arbitrary and
involved lots of guessing to get things right. I know this isn't actually true
but it felt true enough early on to poison my mind to it.

[0] Not something I'm proud of and I know front end development is serious
business so don't @ me.

~~~
sonnyblarney
" I know this isn't actually true "

It's true.

A confluence of vague definitions, poor implementations, bad documentation ...
and this is the web we have. It's the tip of the iceberg, and the painful life
of anyone doing html5 work, it's 'not fun' for anyone who's been exposed to
regular programming because the problems you spend your day solving mostly
should not be problems to begin with.

~~~
shawn
This is what us older people would like to believe. Meanwhile the young
webdevs are having a blast ignoring us and building the apps of the future.

~~~
pjmlp
Yeah and then they all jump around React as some amazing achievement, having
rediscovereed how 90's native UI do event handling.

~~~
jhomedall
React isn't really anything like 90s UI libraries. It is, however, very much
like the fairly recent native immediate-mode GUIs that have come out
([https://github.com/ocornut/imgui](https://github.com/ocornut/imgui),
[https://github.com/PistonDevelopers/conrod](https://github.com/PistonDevelopers/conrod),
etc).

The core feature of React is that your UI is a pure function of your
application state. In (e.g.) the Win32 UI, you would receive events, and then
need to manually transition your current UI state to the new UI state (hide
this button, disable this input, etc).

~~~
pjmlp
Smalltalk UIs used a pattern called dependency propagation to make objects
update themselves based on system wide notifications.

Similar idea was used on Oberon System 3 Gadgets toolkit.

Also java.util.Observable based on the same Smalltalk ideas was already part
of Java 1.0.

~~~
jhomedall
That's still event handling. You can do basic binding between outputs and
values, but more macroscopic changes (closing a dialog, changing tabs, etc)
requires tracking the state your UI is in, and manually transitioning.

This is markedly different than React, where the framework diffs the desired
UI state (which is a pure function of your application state), and the actual
UI state. The minimal number of UI operations necessary is then applied to
make the latter match the former.

ImGui above works the same way, which makes it very popular for devtools in
game development.

~~~
pjmlp
ImGui is quite similar to MS-DOS game UIs, before we migrated to Windows.

The source code of quite a few ones is available around the Net.

------
webwebweb
And GoogleBot seems to follow Safari's rendering instead of Chrome:
[https://developers.google.com/speed/pagespeed/insights/?url=...](https://developers.google.com/speed/pagespeed/insights/?url=https%3A%2F%2Fcodepen.io%2FMartijnCuppens%2Fpen%2FMXojmw&tab=desktop)

~~~
Operyl
I wonder if that’s because they’re just running an older version of
WebKit/blink.

~~~
kevingadd
"Chrome's" rendering in many cases is going to be whatever hardware
accelerated stack (probably Skia + your platform's particular hardware API) is
rasterizing the page. Headless rendering as found in a page scraper bot is
more likely to be using software rasterization and might be using an entirely
different API. Chrome has a few command line flags that can push everything
through different rendering paths and you can get different results from it.

~~~
bla2
Blink (the HTML engine) is still going to push the same drawing commands to
all the backends. Winding rule order stuff might be different if a backend is
buggy, but things like this shouldn't be different.

~~~
LukeShu
I wouldn't be surprised at all if there's a drawing command that's having a
negative number passed to it in a place where it doesn't expect negatives. I
wouldn't be too surprised if different backends handled this "undefined
behavior" differently.

~~~
gsnedders
Nah, this will all be handled within Blink. The drawing command will literally
be told to draw polygons in the specific places in the coordinate space.

------
JBiserkov
See also this
[https://mobile.twitter.com/frivoal/status/101544179390147788...](https://mobile.twitter.com/frivoal/status/1015441793901477888)

~~~
bfrydl
I think one of the most optimistic things to notice about these two images is
that Edge amazingly appears to be correct in both cases.

~~~
PeCaN
It's pretty clear that Microsoft really took a close look at the specs when
developing Edge, which is really nice. It also has the benefit of being the
newest of the major engines.

~~~
chrismorgan
Actually, much of the time it comes down to what bugs people report. In a
closely related area, IE and Edge both _added_ spread distance rather than
_subtracting_ it on inner box-shadows until I reported it last year, then it
was fixed in IE within a month: [https://developer.microsoft.com/en-
us/microsoft-edge/platfor...](https://developer.microsoft.com/en-us/microsoft-
edge/platform/issues/12515080/).

In this particular case, they may have got the best of it because IE didn’t
support outline-offset at all, and so when they implemented it they read the
spec carefully.

Edge _is_ a continuation of IE. Large swathes of the renderer have been
rewritten, but when you do find bugs in Edge they’re commonly shared with IE.

~~~
chrismorgan
(Correction: fixed in _Edge_ within a month; IE doesn’t get such fixes. Also
“IE and Edge both” should read “both IE and Edge” for increased clarity.)

------
crazygringo
Is one of these correct?

Or is this combination of CSS properties ambiguously or un-defined by the spec
in the first place?

~~~
lucideer
The code in question can be mostly boiled down to:

    
    
      outline: inset 100px green;
      outline-offset: -125px;
    

The issue is:

\- spec is deliberately liberal about how outline should look (this is kind of
a similar case to forms and scrollbars, the styling of which varies not just
by browser, but by OS/toolkit)

\- inset is a keyword rarely if ever applied to outlines (and I'm not sure why
it's even valid or what it's purpose would be)

\- outline-offset is a useful property, with well defined behaviour in most
cases: inset outlines are the exception where its behaviour is ill-defined

Edge's behaviour is probably technically "closest" to what I would expect, but
I'm not sure if "correct" is the right term. It's an odd case, and what it
should look like is debatable. IE's and Safari's could be "correct" either,
and in fact IE's kind of looks truest to the intent of outlines as a thing.

Chrome is doing very bizarre things and I can't really fathom why. They look
like rendering bugs.

 _Edited after a 2nd look, IE 's and Safari's make a bit more sense after some
consideration._

~~~
LukeShu
Fiddling with it:

Firefox's mistake is definitely that it isn't handling having outline-offset
less than "-min(width, height)/2" in a sane way. (In the demo, width and
height are both 100px; it starts do do funny things when outline-offset goes
below -50px). That said, I'm not entirely sure that there is a sane way.

IE is totally ignoring the outline-offset property; it isn't implemented in
IE.

------
TeMPOraL
Pretty. I could see various renders used as a logo for each respective
browser.

------
madrox
It blows my mind that problems like this exist, and yet platforms like Unity
and Xamarin are capable of write-once-build-everywhere apps on every platform.
Why hasn't web development abstracted away these problems yet?

~~~
pjmlp
Because many webdevs think that our grey bears and knowledge of doing native
applications are worthless, and who does native anyway.

I look forward to native still winning on mobile for the years to come, with
WebAssembly eventually becoming Flash's revenge.

------
cjhanks
I would think undefined behavior would be helpful in browser fingerprinting.

~~~
avip
Using actual rendering for fingerprinting is a serious perf. hit. I'm not
aware of any production setup using that.

~~~
cjhanks
Thanks for letting me know.

------
21
It seems to me that this example is like undefined behavior in C.

------
BadassFractal
At least Brave is consistent with Chrome, as they're both Chromium-based.
Phew.

~~~
withdavidli
my Brave browser on mobile shows up as same as Safari one.

~~~
r-w
WebKit is the only renderer on iOS.

------
Froyoh
I trust edge more than any other browser.

------
dmurray
What do CSS linters have to say about it?

~~~
r-w
“No”

------
coldseattle
Microsoft is the only one that gets it right.

