Displaced user-card, need some help with CSS

First a bit about position: absolute

The element is removed from the normal document flow, and no space is created for the element in the page layout. It is positioned relative to its closest positioned ancestor, if any; otherwise, it is placed relative to the initial containing block. Its final position is determined by the values of top , right , bottom , and left .

read more

User-cards, group-cards and a few other elements in Discourse have position: absolute with the nearest positioned ancestor for them - in the case of native Discourse UI - being #main which by default has

#main {
  position: relative
}

One key difference about them is that the top and left values are set dynamically with JS - so that they show up where they are supposed to show up.

Examples:

Your user-card has these values

and the user-card for the avatar right below yours has these values

Note the higher top value since the second one is lower.

As I mentioned above, these value are relative to the nearest positioned ancestor - #main

So in the case of your use-card it would be

~341px from the top of #main and ~1490px from its left side.

The #main element in Discourse extends the full width of the screen.

Your theme changes that to add a visual effect. But you also use margin: 0 auto on it to centre it.

Something like this

#main {
  width: 1110px;
}

Which creates this

and you fixed it by using

#main {
  margin: 0 auto;
}

which creates this

however, this fix is not registered by the JS that calculates the top and left values for user-cards, group-cards etc. It assumes the #main element starts here

and so the values are based on that… and so going back to your use-card

left: 1490px

is based on that, however, it is still relative to #main and so when you pushed #main to the center with

#main {
  margin: 0 auto;
}

You’re also pushing user-cards and other similar elements by the same amount because the JS that calculates their position is not aware of your change.

And so you get this

The CSS in my post above

#main {
  position: static;
}

Makes it so that #main is no longer positioned. So going back to the position: absolute

otherwise, it is placed relative to the initial containing block.

The containing block here is the body element and its left side is here

and so the JS values for top and left are accurate again and order is restored to the universe.

12 Likes