Can someone explain why my div with table-layout:fixed is changing the width of its parent element (body in this case) to make it 100%
Looks like you're not the first to bring this up. You might be the second, though.
To be clear, this is a combination of two issues:
The width of an absolutely positioned element is shrink-to-fit. Somehow the shrink-to-fit width is being determined to be as wide as the absposed element's containing block will allow. (The containing block for the absolutely positioned body is the initial containing block.)
A percentage width on an element whose containing block depends on its contents for auto sizing results in undefined behavior.
Issue #2 is pretty easy to write off:
implementations agree not to calculate the width of either element more than once.
i.e. body is sized using shrink-to-fit, then the table is set to 80% of that width, and the size of body is "not computed again". The only "undefinedness" of this is that the spec doesn't require or disallow, or indeed care what implementations do.
So the question then boils down to why shrink-to-fit is yielding "as wide as possible" in #1 prior to determining the size of the table in #2. Here is how the spec describes shrink-to-fit for absposed elements:
[...] Roughly: calculate the preferred width by formatting the content without breaking lines other than where explicit line breaks occur, and also calculate the preferred minimum width, e.g., by trying all possible line breaks. CSS 2.1 does not define the exact algorithm. Thirdly, calculate the available width: this is found by solving for 'width' after setting 'left' (in case 1) or 'right' (in case 3) to 0.
Then the shrink-to-fit width is: min(max(preferred minimum width, available width), preferred width).
But this doesn't tell us why, or even that, the preferred width of a fixed-layout table is "as wide as its containing block will allow". Neither css-sizing-3 nor css-tables-3 appears to contain the answer.
According to David Baron (from the same thread), who works on Gecko:
Fixed-layout tables report an intrinsic max-content inline size as infinite.
(note that "max-content inline size" means the same thing as "preferred width")
So there's our answer. The unbounded max-content inline size of fixed-layout tables is what causes this table's absolutely positioned parent to be stretched as wide as its own containing block (the initial containing block) will allow, in contrast to auto-layout tables.
And, at least for now, this is as close as I'll get to an official source because I'm having trouble reaching the same conclusion just by reading css-sizing-3, and I'm unsure if David's statement is based on Gecko's behavior alone, behavior of all implementations, or on specified behavior.