Skip to content

Should getBBox returns values when the shape can't be drawn #1018

Closed

Description

@karlcow

Using this WPT test as an example
https://wpt.live/svg/types/scripted/SVGGraphicsElement.getBBox-03.html

  <rect id="rect1" x="1" y="2" width="-10" height="20"/>

The value for the rect width is a negative number, which is invalid.

  • CSS 2.1 Negative values for 'width' are illegal.

and in https://svgwg.org/svg2-draft/shapes.html#RectElement

The width and height properties define the overall width and height of the rectangle :

  1. A negative value for either property is invalid and must be ignored.
  2. A computed value of zero for either dimension disables rendering of the element.

Then in 4.4.2. Interface SVGGraphicsElement for getBBox

The getBBox method is used to compute the bounding box of the current element. When the getBBox(options) method is called, the bounding box algorithm is invoked for the current element, with fill, stroke, markers and clipped members of the options dictionary argument used to control which parts of the element are included in the bounding box, using the element's user coordinate system as the coordinate system to return the bounding box in. A newly created DOMRect object that defines the computed bounding box is returned. If getBBox gets called on a non-rendered element, and the UA is not able to compute the geometry of the element, then throw an InvalidStateError.

Currently:

Browser x y width height
Firefox 0 0 0 0
Safari 0 0 0 0
Chrome 1 2 0 20

So I decided to try with a rect were width would be missing.

  <rect id="rect1" x="1" y="2" height="20"/>

And still the results are the same. Chrome returns 0, Firefox/Safari return 0 for everything as the shape is not valid.

In 7.8. Sizing properties: the effect of the ‘width’ and ‘height’ properties

The value auto for width and height on other elements is treated as 0.

but that's not the case here. We do not have a value auto.

The rules for parsing attribute values are in 4.2. Attribute syntax.

The Initial value column gives the initial value for the attribute. When an attribute fails to parse according to the specified CSS Value Definition Syntax, ABNF or EBNF grammar, or if parsing according to the URL Standard or by the prose describing how to parse the attribute indicates failure, the attribute is assumed to have been specified as the given initial value.

There is no table for width in SVG2 as it refers to CSS.

The CSS 2.2 spec in 10.2 Content width: the 'width' property gives as initial value for width: auto

but I'm still confused…

It says ignore at the beginning, then getBBOX() can not be computed.

Opinions?

  • Should the WPT tests be modified and it should return InvalidStateError?
  • OR Should the spec be modified to clarify what invalid width/height default to?

Activity

  1. Ahmad-S792 commented on Sep 24, 2025

    @Ahmad-S792
  2. added
    InteropImplementations are not interoperable with each other
    on Oct 9, 2025
  3. karlcow commented on Oct 9, 2025

    @karlcow
    MemberAuthor
  4. goldenboy777 commented on Oct 29, 2025

    @goldenboy777
    Contributor

    Resolution for this was added here
    https://www.w3.org/2025/10/23-svg-minutes.html#34be

  5. goldenboy777 commented on Oct 29, 2025

    @goldenboy777
    Contributor

    I looked at the spec of Bounding box a little bit and saw

    https://svgwg.org/svg2-draft/coords.html#BoundingBoxes calls out the case for zero width and/or height:

    An element which has zero width, zero height, or both (such as a vertical or horizontal line, or a ‘rect’ element with a zero width or height) still has a bounding box, with a positive value for the positive dimension, or with '0' for both the width and height if no positive dimension is specified. Similarly, subpaths segments of a ‘path’ element with zero width and height must be included in that element's geometry for the sake of the bounding box.

    So a bounding box for the below case be 0x20 ??: (Because one of the dimensions resolves to zero the rendering of the element would be disabled, but that would only mean that it shouldn't contribute to the ancestor bboxes.)

    <rect id="rect1" x="1" y="2" height="20"/>
    

    A negative value of width/height is essentially ignored and for element like rect it will be treated as zero.
    Doesn't this mean the resolution in https://www.w3.org/2025/10/23-svg-minutes.html#34be will change this? @karlcow @dirkschulze

  6. karlcow commented on Oct 30, 2025

    @karlcow
    MemberAuthor

    The resolution that I was about to write down today as a PR is

    RESOLUTION: let's remove the throwing part for invalid getbbox() and make the returned values be 0 for width/height and x/y

    So reading about what is written in the bounding box section.

    Even if an element is not in the rendering tree – due to it being 'display: none', within a ‘defs’ element, not usually rendered like a ‘symbol’ element or not currently present in the document tree – it still has a bounding box. A call to getBBox on the element will return the same rectangle as if the element were rendered. However, an element that is not in the rendering tree does not contribute to the bounding box of any ancestor element.

    that's an interesting case. so has dimensions but not visible. This is a valid bbox so it returns data.

    Then there is the quote you found:

    An element which has zero width, zero height, or both (such as a vertical or horizontal line, or a ‘rect’ element with a zero width or height) still has a bounding box, with a positive value for the positive dimension, or with '0' for both the width and height if no positive dimension is specified.

    I don't understand this part is not part of the parsing algorithm below in this section :/ Should it be? Or should this paragraph be rewritten has an algorithm?

    What are all the possible cases:

    • <rect id="rect1" x="10" y="20" width="30" height="40"/>
    • <rect id="rect1" x="10" y="20" width="-30" height="40"/>
    • <rect id="rect1" x="10" y="20" width="-30" height="-40"/>
    • <rect id="rect1" x="10" y="20" width="0" height="40"/>
    • <rect id="rect1" x="10" y="20" width="0" height="0"/>
    • <rect id="rect1" x="10" y="20" height="40"/>
    • <rect id="rect1" x="10" y="20"/>

    In the resolution, we are currently saying.

    • Remove: "If getBBox gets called on a non-rendered element, and the UA is not able to compute the geometry of the element, then throw an InvalidStateError."
    • Let's assign 0 to the returned value if the attribute is missing, or is negative.

    Your question is the case for width="0" height="40" aka should it return (0, 40) or (0, 0)

    Let's put it back on the agenda. :D
    Thanks @goldenboy777 for your sharp eye.

  7. karlcow commented on Oct 30, 2025

    @karlcow
    MemberAuthor

    The current result in Safari, Firefox and Chrome

    Image
  8. karlcow commented on Oct 30, 2025

    @karlcow
    MemberAuthor

    Note that the current resolution doesn't change anything in terms of rendering.
    It's just what do we think is logical to return as values, and if it has any cascading impact on the rest.

    It could mean we would need to modify the paragraph you found.

    @nikolaszimmermann @shallawa @longsonr @nullhook

  9. karlcow commented on Oct 30, 2025

    @karlcow
    MemberAuthor

    The codepen for the test above https://codepen.io/webcompat/full/jEWvBLm

  10. karlcow commented on Oct 30, 2025

    @karlcow
    MemberAuthor

    https://www.w3.org/2025/10/30-svg-minutes.html#d410

    karlcow: If with or height are negative, we should make everything 0 in getBBox
    karlcow: ...according to last resolution
    dmangal: We should not throw if there are invalid values.
    dmangal: I am concerned what we should return: everything 0 or only the width/height dimension turn 0
    dmangal: an element with 0 dimension does have a bounding box according to spec
    dmangal: according to the paragraph in qiuestion. Should we change the paragraph?
    karlcow_: The resolution shouldn't have any affect on the rest of the SVG document IMO
    karlcow_: Putting everyhthing to 0 seems to be simplest
    nzimmermann: Most obvious would be 0 everything.
    nzimmermann: Elements with 0-dimension doesn't have an effect on parent bounding box.
    nzimmermann: So there is no value to keep position and make dimension only 0
    nzimmermann: seems to be natural to return 0
    dmangal: A path can be 1 dimensional. Would that be different?
    krit: M 100 100 L 100 100 as example
    nzimmermann: valid question
    nzimmermann: we should test this scenario
    karlcow_: We should create WPT tests first and see what browsers return and decide based on the results.
    nzimmermann: there is no way to fill a dot. But of course we can stroke it. SVG2 does have arguments for getBBox. So maybe one can differentiate between getBBox w/o arguments and an argument for getting the stroke boundingbox
    nzimmermann: We should test these scenarios. Agree with karlcow_ : we should base our decision on the results on WPT.
    karlcow_: Who'll create the tests
    dmangal: I will
    ACTION: dmangal will create more detailed getBBox tests for WPT and also take the arguments into account.
    karlcow_: The paragraph you found almost looks like an algorithm. There are many places in SVG2 where things are said but not written as algorithm
    karlcow_: it is strange to me.
    dmangal: It seems off from the rest of the paragraph
    

    @goldenboy777 will create WPT tests to cover all possible scenarios for getBBox and see how browsers align.

  11. goldenboy777 commented on Oct 30, 2025

    @goldenboy777
    Contributor

    The codepen for the test above https://codepen.io/webcompat/full/jEWvBLm

    Thanks for the reference, Karl, I see there are also existing WPTs like SVGGraphicsElement.getBBox*, I will see what's missing and either create or update existing ones

  12. shepazu commented on Oct 30, 2025

    @shepazu
    Member

    From a programmatic perspective, which is true of a lot of drawing and animation tools, it is better to have a predictable and meaningful output from getBBox, even when the target is not currently rendered.

    Having done a lot of this, my personal preference would be for it to return all the information it can, meaning the value information for x & y, and for whatever valid width and height values are available. If it's not valid (say, width="-10"), then return 0, and my script can deal with that much more gracefully than returning null or all 0s.

    Keep in mind that a script may be coordinating multiple elements at once, so having all available information about the bbox of those elements as they mutate is valuable.

  13. longsonr commented on Oct 30, 2025

    @longsonr
    Contributor

    Firefox culls all invalid shapes early in the rendering process which is why it returns zeros. Changing that would have a performance cost for all those shapes that are not going to be rendered anyway.

  14. karlcow commented on Mar 18, 2026

    @karlcow
    MemberAuthor

    In the process of adding more tests.
    WebKit/WebKit#60860

  15. karlcow commented on Mar 19, 2026

    @karlcow
    MemberAuthor

    The current resolution is

    1. Remove: "If getBBox gets called on a non-rendered element, and the UA is not able to compute the geometry of the element, then throw an InvalidStateError."
    2. Let's assign 0 to the returned value if the attribute is missing, or is negative.
  16. karlcow commented on Mar 19, 2026

    @karlcow
    MemberAuthor

    The spec says:
    https://w3c.github.io/svgwg/svg2-draft/coords.html#BoundingBoxes

    Even if an element is not in the rendering tree – due to it being 'display: none', within a ‘defs’ element, not usually rendered like a ‘symbol’ element or not currently present in the document tree – it still has a bounding box.

    with

    A call to getBBox on the element will return the same rectangle as if the element were rendered.

    Then

    However, an element that is not in the rendering tree does not contribute to the bounding box of any ancestor element.

    And

    An element which has zero width, zero height, or both (such as a vertical or horizontal line, or a ‘rect’ element with a zero width or height) still has a bounding box, with a positive value for the positive dimension, or with '0' for both the width and height if no positive dimension is specified.

    Also

    Similarly, subpaths segments of a ‘path’ element with zero width and height must be included in that element's geometry for the sake of the bounding box.

    So there might more to change. There is also the algorithm to compute the bounding box.
    https://w3c.github.io/svgwg/svg2-draft/coords.html#:~:text=algorithm%20to%20compute%20the%20bounding%20box

  17. karlcow commented on Mar 19, 2026

    @karlcow
    MemberAuthor

    The algorithm to compute the bounding box is not really saying anything about the invalidity.

  18. karlcow commented on Mar 19, 2026

    @karlcow
    MemberAuthor

    In https://w3c.github.io/svgwg/svg2-draft/coords.html#BoundingBoxes

    An element with no position specified (such as a ‘path’ element with a value of none for the d property) is positioned at the point (0,0) for the purposes of calculating a bounding box.

    This seems to contradict the SVG WG resolution.

  19. added 2 commits that reference this issue on Mar 19, 2026
    16ab184
    c478e7e
  20. karlcow commented on Mar 19, 2026

    @karlcow
    MemberAuthor

    I put a PR up for a review if we go with the resolution.
    #1078
    But for now it seems incomplete given my comments above.

  21. added a commit that references this issue on Apr 23, 2026
    5909991
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    InteropImplementations are not interoperable with each other

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions