MoonZoon icon indicating copy to clipboard operation
MoonZoon copied to clipboard

Border::inner / "jumping elements"

Open MartinKavik opened this issue 3 years ago • 0 comments

jumping GIF from https://trungk18.com/experience/css-div-jump-border/

PROBLEM: You can't change a border width when the element doesn't have a predefined size (assuming box-sizing: border-box) without accidentally changing the element's size. This size change causes "jumping" demonstrated on the animation above.

There are some workarounds - use box-shadow, outline, pseudo-elements, etc.:

  • https://www.delftstack.com/howto/css/css-inner-border/
  • https://trungk18.com/experience/css-div-jump-border/
  • https://css-tricks.com/snippets/css/multiple-borders/

The most reasonable choice seems to be outline + outline-offset. You can use it without MZ API changes this way atm:

Button::new()
    .update_raw_el(|el| {
        el
            .style_signal("outline", hovered.signal().map_bool(
                || format!("{} solid {}px", theme::purple_1(), 3),
                || format!("{} solid {}px", theme::purple_0(), 1),
            ))
            .style_signal("outline-offset", hovered.signal().map_bool(
                || px(-3),
                || px(-1),
            ))
    })

With the future API (the first draft):

Button::new()
    .s(Borders::all_signal(hovered.signal().map_bool(
        || Border::inner().color(theme::purple_1()).width(3),
        || Border::inner().color(theme::purple_0()),
    )))

(Notice inner() instead of new())

However, outline still ignores border-radius in Safari so this solution is blocked. Related bug info:

  • https://caniuse.com/mdn-css_properties_outline
  • https://github.com/Fyrd/caniuse/issues/6099#issuecomment-1006212844

In the meantime, we have to use other workarounds (mentioned above) or just don't change the border width (you can use transparent borders in some cases).

Other ideas?

MartinKavik avatar May 12 '22 09:05 MartinKavik