mikke89 / RmlUi

RmlUi - The HTML/CSS User Interface library evolved
https://mikke89.github.io/RmlUiDoc/
MIT License
2.57k stars 295 forks source link

Flex expanding width to edge #577

Closed Paril closed 5 months ago

Paril commented 5 months ago

I'm not sure how to describe this issue, but, here's the full rml & rcss to reproduce it:

*
{
    box-sizing: border-box;
}

div
{
    display: block;
}

body
{
    width: 100%;
    height: 100%;
    font-family: Lithos;
    font-weight: normal;
    font-style: normal;
    font-size: 15dp;
    color: white;
}

span
{
    display: inline;
}

img
{
    display: inline-block;
}

body .control_box
{
    background: rgba(255, 0, 0, 64);
    padding: 1em 2em;
    /*display: flex;*/
}

body .control_box > .control
{
    display: inline-flex;
    /*align-items: center;
    justify-content: center;*/

}

body .control_box > .control > img
{
    width: 24dp;
    height: 24dp;
}
<rml>
    <head>
        <link type="text/rcss" href="control_box.rcss" />
    </head>
    <body>
        <div class='control_box'>
            <div class='control'>
                <img src="/gfx/controller/keyboard/287.png" />
                <span>$m_select_item</span>
            </div>
            <div class='control'>
                <img src="/gfx/controller/keyboard/27.png" />
                <span>$m_back_menu</span>
            </div>
        </div>
    </body>
</rml>

In RmlUi, the inner .control elements are stretched all the way to fill the outer container; they should be fitting their content tightly. If you use the same css in an HTML layout engine, the results are as expected:

However, this is the result I'm getting - I mimicked the result by adding width: 100%; on .control:

Is this related to the "improved shrink to fit" PR, or is this a different issue entirely?

If I use the Rml::Debugger, the values are correct for the two inner elements (width 24px for img, ~130px for the text), but the width of the .control always ends up being 1620px.

Using inline-block instead of inline-flex also fixes it, but I wanted to use flex for the inner elements of the block.

Paril commented 5 months ago

I confirmed that https://github.com/mikke89/RmlUi/pull/559 doesn't fix this use-case, so I'm not sure if this is just an unrelated bug or if I've set something wrong... it seems to be specific to inline-flex, though. It always wants to fill the entire parent.

Paril commented 5 months ago

Ah, I just spotted what I was missing from the docs:

In RCSS, inline-flex boxes are required to have their widths set to a definite (non-auto) value.

That would do it, and is quite problematic here since I don't know how long the text is going to be (localization, etc). Is this effectively what shrink-to-fit addresses?

EDIT2: Removing Style::Display::InlineTable from the check in GetShrinkToFitWidth and adding it here:

        // Apply the shrink-to-fit algorithm here to find the width of the element.
        // See CSS 2.1 section 10.3.7 for when this should be applied.
        const bool shrink_to_fit = !replaced_element &&
            ((computed.float_() != Style::Float::None) || (absolutely_positioned && inset_auto) ||
                (computed.display() == Style::Display::InlineBlock || computed.display() == Style::Display::InlineFlex));

seems to enable this to work as I expect, but it certainly can't be that simple and probably breaks other things...