<pre class='metadata'>
Title: CSS Table Module Level 3
Shortname: css-tables
Level: 3
Status: WD
Prepare for TR: yes
Date: 2025-12-16
Work Status: Exploring
Group: csswg
ED: https://drafts.csswg.org/css-tables-3/
TR: https://www.w3.org/TR/css-tables-3/
Previous Version: https://www.w3.org/TR/2019/WD-css-tables-3-20190727/
Previous Version: https://www.w3.org/TR/CSS2/tables.html
Repository: w3c/csswg-drafts
Warning: not ready
Editor: Keith Cirkel, Mozilla, w3cid 146197
Former Editor: François Remy, Invited Expert, w3cid 53348
Former Editor: Greg Whitworth, Microsoft, w3cid 69511
Former editor: Bert Bos, W3C
Former Editor: L. David Baron, Google https://www.google.com/, https://dbaron.org/, w3cid 15393
Former editor: Markus Mielke, Microsoft
Former editor: Saloni Mira Rai, Microsoft
Abstract: This CSS module defines a two-dimensional grid-based layout system, optimized for tabular data rendering. In the table layout model, each display node is assigned to an intersection between a set of consecutive rows and a set of consecutive columns, themselves generated from the table structure and sized according to their content.
Ignored Terms: block-level box
WPT Path Prefix: css/css-tables/
WPT Display: open
</pre>

<!-- NOTE TO SELF:
BEFORE PUBLISHING A NEW WORKING DRAFT:
- switch Status to WD
- search the w3c list archives for the wg resolution allowing to republish
- fix all the linting issues
AFTER PUBLISHING A NEW WORKING DRAFT:
- revert Status to ED
- update Previous Version to the permalink of the new version you pushed
- commit those changes to csswg-drafts
-->

<pre class=link-defaults>
spec:css2; type:property;
	text:top
	text:right
	text:bottom
spec:css-borders-4; type:property;
	text:border-image
	text:border-image-source
	text:border-radius
	text:border-style
	text:border-width
spec:css-sizing-3; type:property;
	text:min-height
	text:min-width
	text:max-width
	text:box-sizing
spec:filter-effects-1; type:property; text:filter
spec:css-display-4; type:property; text:display
</pre>

<!--
████ ██    ██ ████████ ████████   ███████
 ██  ███   ██    ██    ██     ██ ██     ██
 ██  ████  ██    ██    ██     ██ ██     ██
 ██  ██ ██ ██    ██    ████████  ██     ██
 ██  ██  ████    ██    ██   ██   ██     ██
 ██  ██   ███    ██    ██    ██  ██     ██
████ ██    ██    ██    ██     ██  ███████
-->
<h2 id="intro">Introduction</h2>

	<em>This section is not normative</em>

	Many types of information (ex: weather readings collected over the past year)
		are best visually represented in a two-axis grid
		where rows represent one item of the list
			(ex: a date, and the various weather properties measured during that day),
		and where columns represent the successive values of an item's property
			(ex: the temperatures measured over the past year).

	Sometimes, to make the representation easier to understand,
		some cells of the grid are used to represent a description or summary of their parent row/column,
		instead of actual data.
	This happens more frequently for
		the cells found on the first row and/or column (called headers)
		or the cells found on the last row and/or column (called footers).


	This kind of tabular data representation is usually known as tables.
	Tables layout can be abused to render other grid-like representations like calendars or timelines,
		though authors should prefer other layout modes
		when the information being represented does not make sense as a data table.

	The rendering of tables in HTML has been defined for a long time in the HTML specification.
	However, its interactions with features defined in CSS remained for a long time undefined.
	The goal of this specification is to define
		the expected behavior of user agents supporting both HTML tables and CSS.

	Please be aware that some behaviors defined in this document
		will not be the most logical or useful way of solving the problem they aim to solve,
		but such behaviors are often the result of compatibility requirements and not a deliberate choice
		of the editors of this specification.
	Authors wishing to use more complex layouts
		are encouraged to rely on more modern CSS modules such as CSS Grid.

	<wpt title="
		The following tests are crash tests
		that relate to general usage
		of the features described in this specification
		but are not tied to any particular normative statement.">
		colspan-zero-crash.html
		crashtests/caption-repaint-crash.html
		crashtests/caption-with-multicol-table-cell.html
		crashtests/cell-contents-with-negative-outer-size.html
		crashtests/col_span_dynamic_crash.html
		crashtests/dialog-table-crash.html
		crashtests/dynamic-recompute-baseline.html
		crashtests/dynamic_col_width_crash.html
		crashtests/dynamic_table_layout_crash.html
		crashtests/empty-tbody-after-tall-section-crash.html
		crashtests/empty_cells_crash.html
		crashtests/empty_table_with_cols.html
		crashtests/expression_width_crash.html
		crashtests/inline-splitting-crash.html
		crashtests/large-border-crash.html
		crashtests/large-col-widths.html
		crashtests/legacy_ng_mix_crash.html
		crashtests/move-oof-inside-section-row-with-borders.html
		crashtests/negative-section-distribution.html
		crashtests/negative_caption_margin.html
		crashtests/orthogonal-cell-borders.html
		crashtests/orthogonal-cell-crash.html
		crashtests/table-column-display-change-chrome-crash.html
		crashtests/textarea-intrinsic-size-crash.html
		crashtests/atomic-item-crash.html
		crashtests/remove-table-column-group.html
		crashtests/transition-table-row-group-crash.html
		crashtests/uninitialized_read_crash.html
		table-caption-after-crash.html
		crashtests/vertical_percentage_crash.html
		tfoot-crash-print.html
		th-text-align.html
		toggle-row-display-property-001.html
		table-collapsed-row-or-column-crash.html
	</wpt>

	<wpt title="Tests generally related to table layout">
		absolute-tables-001.html
		absolute-tables-006.html
		anonymous-table-cell-margin-collapsing.html
		chrome-rowspan-bug.html
		col_removal.html
		colspan-001.html
		colspan-002.html
		colspan-003.html
		colspan-004.html
		dynamic-rowspan-change.html
		html-display-table.html
		inheritance.html
		multicol-table-collapsed-border-crash.html
		multicol-table-crash.html
		remove-caption-from-anon-table.html
		remove-colgroup-from-anon-table.html
		row-group-order.html
		table-position-sticky-computed.html
		table-cell-child-overflow-measure.html
		table-cell-inline-size-box-sizing-quirks.html
		table-cell-scroll-height.html
		table-cell-writing-mode-computed.html
		zero-rowspan-001.html
		zero-rowspan-002.html
		subpixel-table-cell-height-001.html
		subpixel-table-width-001.html
	</wpt>

<h3 id="values">Value Definitions</h3>

	This specification follows the <a href="https://www.w3.org/TR/CSS2/about.html#property-defs">CSS property definition conventions</a> from [[!CSS2]]
	using the <a href="https://www.w3.org/TR/css-values-3/#value-defs">value definition syntax</a> from [[!CSS-VALUES-3]].
	Value types not defined in this specification are defined in CSS Values &amp; Units [[!CSS-VALUES-3]].
	Combination with other CSS modules may expand the definitions of these value types.

	In addition to the property-specific values listed in their definitions,
	all properties defined in this specification
	also accept the <a>CSS-wide keywords</a> as their property value.
	For readability they have not been repeated explicitly.

<!--
 ██████   ███████  ██    ██ ████████ ████████ ██    ██ ████████       ██     ██  ███████  ████████  ████████ ██
██    ██ ██     ██ ███   ██    ██    ██       ███   ██    ██          ███   ███ ██     ██ ██     ██ ██       ██
██       ██     ██ ████  ██    ██    ██       ████  ██    ██          ████ ████ ██     ██ ██     ██ ██       ██
██       ██     ██ ██ ██ ██    ██    ██████   ██ ██ ██    ██          ██ ███ ██ ██     ██ ██     ██ ██████   ██
██       ██     ██ ██  ████    ██    ██       ██  ████    ██          ██     ██ ██     ██ ██     ██ ██       ██
██    ██ ██     ██ ██   ███    ██    ██       ██   ███    ██          ██     ██ ██     ██ ██     ██ ██       ██
 ██████   ███████  ██    ██    ██    ████████ ██    ██    ██          ██     ██  ███████  ████████  ████████ ████████
-->
<h2 id="content-model">Content Model</h2>

	<!--——————————————————————————————————————————————————————————————————————————-->
	<h3 id="table-structure">Table Structure</h3>

	The CSS table model is based on the HTML4 table model,
		in which the structure of a table closely parallels the visual layout of the table.
	In this model, a table consists of an optional caption and any number of rows of cells.

	In addition, adjacent rows and columns may be grouped structurally and
	this grouping can be reflected in presentation (e.g., a border may be drawn around a group of rows).

	The table model is said to be "row primary" since
		authors specify rows, not columns, explicitly in the document language.
	Columns are derived once all the rows have been specified:
		the first cell of the first row belongs to the first column
			and as many other columns as spanning requires (and it creates them if needed),
		and the following cells of that row each belong to the next available column
			and as many other columns as spanning requires (creating those if needed);
		the cells of the following rows each belong to the next available column for that row (taking rowspan into account)
			and as many other columns as spanning requires (creating those if needed).
		<span class="hint">(see [[#dimensioning-the-row-column-grid]])</span>.

	To summarize, an instance of the table model consists of:
	<ul class="compact">
		<li>Its <a href="#table-root-element">table-root</a> containing:
		<ul>
			<li>Zero, one or more <a href="#table-row">table rows</a>, optionally in <a href="#table-row-group">row groups</a>,
				<ul><li>Each of them containing one or more <a href="#table-cell">table cells</a></li></ul>
			<li>Optionally: one or more <a href="#table-column">table columns</a>,
				optionally in <a href="#table-column-group">column groups</a>
			<li>Optionally: one or more <a href="#table-caption">table caption</a>.
		</ul>
	</ul>

	<style>
		ul.compact { margin-top: -1em !important; list-style-type: disc; }
		ul.compact li { margin-top: 0 !important; margin-bottom: 0 !important; list-style-type: disc; }
	</style>

	<figure>
		<img alt="[see-caption-below]" src="images/table-structure.png" width=493>
		<figcaption>Two representations of the structure of a table (tree vs layout)</figcaption>
	</figure>

	The CSS model does not require that the document language include elements that correspond to each of these components.
	For document languages (such as XML applications) that do not have pre-defined table elements,
		authors must map document language elements to table elements.
	This is done with the 'display' property.

	The following 'display' values assign table formatting rules to an arbitrary element:

	<dl id="display-types">
		<dt><dfn>table</dfn> (equivalent to HTML: &lt;table&gt;)
		<dd>Specifies that an element defines a table
			that is <a>block-level</a> when placed in <a>flow layout</a>.

		<dt><dfn>inline-table</dfn> (equivalent to HTML: &lt;table&gt;)
		<dd>Specifies that an element defines a table
			that is <a>inline-level</a> when placed in <a>flow layout</a>.

		<dt><dfn>table-row</dfn> (equivalent to HTML: &lt;tr&gt;)
		<dd>Specifies that an element is a row of cells.

		<dt><dfn>table-row-group</dfn> (equivalent to HTML: &lt;tbody&gt;)
		<dd>Specifies that an element groups some amount of rows. 

			Unless explicitly mentioned otherwise, mentions of [=table-row-groups=] in this spec also encompass the specialized [=table-header-groups=] and [=table-footer-groups=].

		<dt><dfn>table-header-group</dfn> (equivalent to HTML: &lt;thead&gt;)
		<dd>Like [=table-row-group=] but, for layout purposes,
			the first such row group is always displayed before all other rows and row groups.

			<div class="advisement">
				If a table owns multiple <code>display: table-header-group</code> boxes,
					only the first is treated as a header;
					the others are treated as if they had <code>display: table-row-group</code>.
			</div>

		<dt><dfn>table-footer-group</dfn> (equivalent to HTML: &lt;tfoot&gt;)
		<dd>Like [=table-row-group=] but, for layout purposes,
			the first such row group is always displayed after all other rows and row groups.

			<div class="advisement">
				If a table owns multiple <code>display: table-footer-group</code> boxes,
					only the first is treated as a footer;
					the others are treated as if they had <code>display: table-row-group</code>.
			</div>

		<dt><dfn>table-column</dfn> (equivalent to HTML: &lt;col&gt;)
		<dd>Specifies that an element describes a column of cells.

		<dt><dfn>table-column-group</dfn> (equivalent to HTML: &lt;colgroup&gt;)
		<dd>Specifies that an element groups one or more columns.

		<dt><dfn>table-cell</dfn> (equivalent to HTML: &lt;td&gt; or &lt;th&gt;)
		<dd>Specifies that an element represents a table cell.

		<dt><dfn>table-caption</dfn> (equivalent to HTML: &lt;caption&gt;)
		<dd>Specifies a caption for the table.
			Table captions are positioned between the table margins and its borders.

			<wpt>
				caption-cyclic-percentage.html
				caption-writing-mode-001.html
				caption-writing-mode-002.html
			</wpt>
	</dl>

	Note: [=Replaced elements=] with a 'display' value of
	''table-row'',
	''table-row-group'',
	''table-header-group'',
	''table-footer-group'',
	''table-column'',
	''table-column-group'',
	''table-cell'',
	and ''table-caption''
	are treated as [=inline-level boxes=],
	as per [[css-display-3#layout-specific-display]];
	[=replaced elements=] with a 'display' value of ''table'' or ''inline-table''
	behave according to their [=outer display type=],
	as per [[css-display-3#outer-role]].
	<strong>This is a breaking change from CSS 2.1 but matches implementations.</strong>

	<wpt>
		table-model-fixup-2.html
	</wpt>

	<h4 id="terminology">Terminology</h4>

			In addition to the table structure display types,
			the following wording is also being used in this spec:

		<dl export>

			<dt><dfn lt="table wrapper box | table-wrapper box" local-lt="table-wrapper">table wrapper box</dfn>
			<dd>
				A block container box <a href="#fixup-algorithm">generated around table grid boxes</a>
				to account for any space occupied by each <a>table-caption</a> it owns.

			<dt><dfn lt="table grid box | table-grid box" local-lt="table-grid">table grid box</dfn>
			<dd>
				A block-level box containing the table-internal boxes, excluding its captions.

			<dt><dfn id="table-root-element">table-root</dfn> element
			<dd>
				An element whose <a>inner display type</a> is ''display/table''.

			<dt><dfn id="table-non-root-element">table-non-root</dfn> box or element
			<dd>
				A <a>proper table child</a>, or a <a>table-cell</a> box.

			<dt><dfn id="table-track">table-track</dfn> box or element
			<dd>
				A
				<a>table-row</a>, or
				<a>table-column</a> box.

			<dt><dfn id="table-track-group-element">table-track-group</dfn> box or element
			<dd>
				A
				<a>table-row-group</a>, or
				<a>table-column-group</a> box.

			<dt><dfn id="proper-table-child-element">proper table child</dfn> box or element
			<dd>
				A
				<a>table-track-group</a>,
				<a>table-track</a>, or
				<a>table-caption</a> box.

			<dt><dfn id="proper-table-row-parent-element">proper table-row parent</dfn> box or element
			<dd>
				A <a>table-root</a> or a <a>table-row-group</a> box.

			<dt><dfn id="table-internal-element">table-internal</dfn> box or element
			<dd>
				A <a>table-cell</a>, <a>table-track</a> or <a>table-track-group</a> box.

			<dt><dfn id="tabular-container">tabular container</dfn>
			<dd>
				A <a>table-row</a> or <a>proper table-row parent</a> box.

			<dt><dfn noexport id="consecutive-boxes">consecutive</dfn> boxes
			<dd>
				Two sibling boxes are consecutive
					if they have no intervening siblings
					other than, optionally, an anonymous inline containing only white spaces.
				A sequence of sibling boxes is consecutive
					if each box in the sequence is consecutive to the one before it in the sequence.

				<wpt>
					whitespace-001.html
				</wpt>

			<dt><dfn id="table-grid">table grid</dfn>
			<dd>
				A matrix 
					containing as many <dfn id="row">rows</dfn> and <dfn id="column">columns</dfn>
					as needed to describe the position of all the <a>table-rows</a> and <a>table-cells</a> of a <a>table-root</a>,
					as determined by the <a href="#dimensioning-the-row-column-grid">grid-dimensioning algorithm</a>.
				
				Each row of the grid might correspond to a <a>table-row</a>, and each column to a <a>table-column</a>.

			<dt><dfn noexport id="slot">slot</dfn> of the table grid
			<dd>
				A <a>slot</a> <code>(r,c)</code> is an available space created
					by the intersection of a row <code>r</code> and a column <code>c</code> in the <a>table grid</a>.
				
				Each slot of the table grid is covered by at least one <a>table-cell</a> (<a href="#missing-cells-fixup">some of them anonymous</a>), and at most two.
				Each table-cell of a table-root covers at least one slot.

				Table-cells which cover more than one slot do so densely, 
					meaning the set of slots they cover can always be described as a set of four strictly-positive integers <code>(rowStart, colStart, rowSpan, colSpan)</code>
					such that a slot <code>(r,c)</code> is covered by the table-cell 
						if and only if <code>r</code> lies in the interval between <code>rowStart</code> (included) and <code>rowStart+rowSpan</code> (excluded), 
						and <code>c</code> lies in the interval between <code>colStart</code> (included) and <code>colStart+colSpan</code> (excluded);
				
				Such table-cell is said to <dfn>originate</dfn> from row <code>rowStart</code> and column <code>colStart</code>.
				Also:

				<ul><li>A table-cell is said to originate a table-row <i>(resp. table-column)</i> if it originates its corresponding row <i>(resp. column)</i>
					<li>A table-cell is said to originate a table-row-group <i>(resp. table-column-group)</i> if the group contains the cell's originating row <i>(resp. column)</i>
					</ul>

				Such table-cell is said to <dfn>span</dfn> all rows <code>r</code> and columns <code>c</code> matching the above condition. 
				Also:

				<ul><li>A table-cell is said to span a table-row <i>(resp. table-column)</i> if it spans its corresponding row <i>(resp. column)</i>
					<li>A table-row <i>(resp. table-column)</i> corresponding to a row <i>(resp. column)</i> is said to span this row <i>(resp. column)</i>
					<li>A table-row <i>(resp. table-column)</i> is said to span all columns of the grid <i>(resp. row)</i>
					<li>A table-row-group <i>(resp. table-column)</i> containing a row <i>(resp. column)</i> is said to span the row <i>(resp. column)</i>
					<li>A table-row-group <i>(resp. table-column)</i> is said to span all columns of the grid <i>(resp. row)</i>
					</ul>

		</dl>

<!--
████████ ████ ██     ██ ██     ██ ████████
██        ██   ██   ██  ██     ██ ██     ██
██        ██    ██ ██   ██     ██ ██     ██
██████    ██     ███    ██     ██ ████████
██        ██    ██ ██   ██     ██ ██
██        ██   ██   ██  ██     ██ ██
██       ████ ██     ██  ███████  ██
-->
	<h3 id="fixup">Fixup</h3>

		Document languages other than HTML may not contain all the elements in the CSS 2.1 table model.
		In these cases, the "missing" elements must be assumed in order for the table model to work.

		Any <a>table-internal</a> element will automatically generate necessary anonymous table objects around itself, if necessary.
		Any descendant of a <a>table-root</a> that is not table-internal
			must have a set of ancestors in the table consisting of
			at least three nested objects corresponding to
			a <a>table</a>/<a>inline-table</a>,
			a <a>table-row</a>, and
			a <a>table-cell</a>.
		Missing boxes cause the generation of <a href="#fixup-boxes">anonymous boxes</a> according to the following rules:

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="fixup-algorithm">Fixup Algorithm</h4>

			For the purposes of these rules, <a>out-of-flow</a> elements are represented as inline elements of zero width and height.
			Their containing blocks are chosen accordingly.

			The following steps are performed in three stages:

			<ol>
				<li><b>Remove irrelevant boxes:</b><br/>
					The following boxes are discarded as if they were <code>display:none</code>:
					<ol>
						<li>Children of a <a>table-column</a>.

						<li>Children of a <a>table-column-group</a> which are not a <a>table-column</a>.

						<li>Anonymous inline boxes which contain only white space and
							are between two immediate siblings each of which is a <a>table-non-root</a> box.

						<li>Anonymous inline boxes which meet all of the following criteria:
							<ul>
								<li>they contain only white space
								<li>they are the first and/or last child of a <a>tabular container</a>
								<li>whose immediate sibling, if any, is a <a>table-non-root</a> box
							</ul>
					</ol>
				</li>
				<li><b>Generate missing child wrappers:</b>
					<ol>
						<li>An anonymous <a>table-row</a> box must be generated
							around each sequence of consecutive children of a <a>table-root</a> box
							which are not <a>proper table child</a> boxes.
							<a class="hint" href="https://jsfiddle.net/hj2w7wwa/2/">!!Testcase</a>

						<li>An anonymous <a>table-row</a> box must be generated
							around each sequence of consecutive children of a <a>table-row-group</a> box
							which are not <a>table-row</a> boxes.
							<a class="hint" href="https://jsfiddle.net/hj2w7wwa/3/">!Testcase</a>

						<li>An anonymous <a>table-cell</a> box must be generated
							around each sequence of consecutive children of a <a>table-row</a> box
							which are not <a>table-cell</a> boxes.
							<a class="hint" href="https://jsfiddle.net/hj2w7wwa/4/">!Testcase</a>

					</ol>
				</li>
				<li><b>Generate missing parents:</b>
					<ol>
						<li>An anonymous <a>table-row</a> box must be generated
							around each sequence of consecutive <a>table-cell</a> boxes
							whose parent is not a <a>table-row</a>.
							<a class="hint" href="https://jsfiddle.net/hj2w7wwa/5/">Testcase</a>

						<li>An anonymous <a>table</a> or <a>inline-table</a> box must be generated
							around each sequence of consecutive <a>proper table child</a> boxes
							which are misparented.
							If the box's parent is an inline, run-in, or ruby box (or any box that would perform inlinification of its children),
								then an <a>inline-table</a> box must be generated;
								otherwise it must be a <a>table</a> box.
							<ul>
								<li>A <a>table-row</a> is misparented
									if its parent is neither a <a>table-row-group</a> nor a <a>table-root</a> box.
								<li>A <a>table-column</a> box is misparented
									if its parent is neither a <a>table-column-group</a> box nor a <a>table-root</a> box.
								<li>A <a>table-row-group</a>, <a>table-column-group</a>, or <a>table-caption</a> box is misparented
									if its parent is not a <a>table-root</a> box.
							</ul>
							<a class="hint" href="https://jsfiddle.net/hj2w7wwa/7/">Testcase</a>
							<a class="hint" href="https://jsfiddle.net/hj2w7wwa/8/">Testcase</a>
							<a class="hint" href="https://jsfiddle.net/hj2w7wwa/9/">!Testcase</a>

						<li>An anonymous <a>table-wrapper</a> box must be generated around each <a>table-root</a>.
							Its display type is <code>inline-block</code> for <a>inline-table</a> boxes and block for <a>table</a> boxes.
							The table wrapper box establishes a block formatting context.
							The table-root box (not the table-wrapper box) is used when doing baseline vertical alignment for an <a>inline-table</a>.
							The width of the table-wrapper box is the border-edge width of the table grid box inside it.
							Percentages which would depend on the 'width' and 'height' on the table-wrapper box's size are relative to the table-wrapper box's containing block instead, not the table-wrapper box itself.
					</ol>
				</li>
			</ol>

			<div class="note">
				Please note that some layout modes such as flexbox and grid <a href="http://www.w3.org/TR/css-display-3/#blockify">override the display type</a> of their children.
				These transformations happen before the table fixup.
			</div>

			<div class="note">
				Please note that the 'float' and 'position' properties sometimes <a href="http://www.w3.org/TR/CSS22/visuren.html#dis-pos-flo">affect the computed value</a> of 'display'.
				When those properties are used on what should have been table internal boxes, they switch to <code>block</code> instead.
				This transformation happens before the table fixup.
			</div>


			<div class="note">
				We have modified the text of this section from CSS 2.2 to make it easier to read.
				If you find any mistakes due to these changes please file an issue
			</div>

			<wpt>
				anonymous-table-ws-001.html
				fixup-dynamic-anonymous-inline-table-001.html
				fixup-dynamic-anonymous-inline-table-002.html
				fixup-dynamic-anonymous-inline-table-003.html
				fixup-dynamic-anonymous-table-001.html
				iframe-display-table-content-insertion.html
				insert-after-col.html
				insert-after-colgroup.html
				table-model-fixup.html
				table-row-group-nested-anonymous-001.html
			</wpt>

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="fixup-boxes">Characteristics of fixup boxes</h4>

			Beside their display type, the anonymous boxes created for fixup purposes
				do not receive any specific or default styling,
				except where otherwise mentioned by this specification.

			<div class="note">

				This means in particular that
					their computed background is “transparent”,
					their computed padding is “0px”,
					their computed border-style is “none”.
					
				It is also worth reminding that an <a>anonymous box</a> inherits property values through the box tree.

			</div>

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="fixup-examples">Examples</h4>

			<div class="example">
				<xmp class="lang-markup">
					<div class="row">
						<div class="cell">George</div>
						<div class="cell">4287</div>
						<div class="cell">1998</div>
					</div>
				</xmp>

				Here is the associated styles:

				<pre class="lang-css">
					.row { display: table-row }
					.cell { display: table-cell }
				</pre>

				After fixup, this will produce layout boxes as though this was the initial HTML:

				<xmp class="lang-markup">
					<table>
						<tr>
							<td>George</td>
							<td>4287</td>
							<td>1998</td>
						</tr>
					</table>
				</xmp>
			</div>

			<div class="example">

				In this example, three <a>table-cell</a> anonymous boxes are assumed to contain the text in the rows. The text inside
				of the divs with a <code>display: table-row</code> are encapsulated in anonymous inline boxes, as explained in
				<a href="https://www.w3.org/TR/CSS21/visuren.html#anonymous" target="_blank">visual formatting model</a>:

				<xmp class="lang-markup">
					<div class="inline-table">
						<div class="row">This is the top row.</div>
						<div class="row">This is the middle row.</div>
						<div class="row">This is the bottom row.</div>
					</div>
				</xmp>

				<pre class="lang-css">
					.inline-table { display: inline-table; }
					.row { display: table-row; }
				</pre>

				This will produce layout boxes as though this was the initial HTML:

				<xmp class="lang-markup">
					<table>
						<tr>
							<td>This is the top row.</td>
						</tr>
						<tr>
							<td>This is the middle row.</td>
						</tr>
						<tr>
							<td>This is the bottom row.</td>
						</tr>
					</table>
				</xmp>
			</div>

<!--
██          ███    ██    ██  ███████  ██     ██ ████████
██         ██ ██    ██  ██  ██     ██ ██     ██    ██
██        ██   ██    ████   ██     ██ ██     ██    ██
██       ██     ██    ██    ██     ██ ██     ██    ██
██       █████████    ██    ██     ██ ██     ██    ██
██       ██     ██    ██    ██     ██ ██     ██    ██
████████ ██     ██    ██     ███████   ███████     ██
-->
<h2 id="layout">Layout</h2>

	<!--——————————————————————————————————————————————————————————————————————————-->
	<h3 id="layout-principles">Core layout principles</h3>

		Unlike other block-level boxes, tables do not fill their containing block by default.
		When their 'width' computes to <code>auto</code>, they behave as if they had <code>fit-content</code> specified instead.
		This is different from most block-level boxes, which behave as if they had <code>stretch</code> instead.

		The <dfn id="min-content-width-of-a-table" export>min-content width of a table</dfn> is
			the width required to fit all of its columns min-content widths and its [=undistributable spaces=].

		The <dfn id="max-content-width-of-a-table" export>max-content width of a table</dfn> is
			the width required to fit all of its columns max-content widths and its [=undistributable spaces=].

		If the width assigned to a table is larger than its <a href="#min-content-width-of-a-table">min-content width</a>,
			the <a href="#width-distribution">Available Width Distribution</a> algorithm
			will adjust column widths in consequence.

		This section overrides the general-purpose rules that apply to calculating widths described in other specifications.
		In particular, if the margins of a table are set to <code>0</code> and the width to <code>auto</code>,
			the table will not automatically size to fill its containing block.
		However, once the used value of <code>width</code> for the table is found (using the algorithms given below)
			then the other parts of those rules do apply.
		Therefore, a table can be centered using left and right <code>auto</code> margins, for instance.

	<!--——————————————————————————————————————————————————————————————————————————-->
	<h3 id="table-layout-algorithm">Table layout algorithm</h3>

		To layout a table, user agents must apply the following actions:

			<ol>
				<li><b>Determine the number of rows/columns the table requires.</b><br/>
					This is done by executing the steps described in [[#dimensioning-the-row-column-grid]].

				<li><b>&lbrack;A&rbrack; If the row/column grid has at least one <a>slot</a>:</b>
					<ol>
						<li><b>Ensure each cell <a>slot</a> is occupied by at least one cell.</b><br/>
							This is done by executing the steps described in [[#missing-cells-fixup]].

						<li><b>Compute the minimum width of each column.</b><br/>
							This is done by executing the steps described in [[#content-measure]].

						<li><b>Compute the width of the table.</b><br/>
							This is done by executing the steps described in [[#computing-the-table-width]].

						<li><b>Distribute the width of the table among columns.</b><br/>
							This is done by executing the steps described in [[#width-distribution-algorithm]].

						<li><b>Compute the height of the table.</b><br/>
							This is done by executing the steps described in [[#computing-the-table-height]].

						<li><b>Distribute the height of the table among rows.</b><br/>
							This is done by executing the steps described in [[#height-distribution-algorithm]].

					</ol>

					<b>&lbrack;B&rbrack; Else, an <dfn id="empty-table">empty table</dfn> is laid out:</b>
					<ol>
						<li><b>Compute the width of the table.</b><br/>
							This is done by returning the largest value of <a href="#capmin">CAPMIN</a>
							and the computed width of the table grid box (including borders and paddings)
								if it is definite (use zero otherwise).

						<li><b>Compute the height of the table.</b><br/>
							This is done by returning the sum of all table-caption heights
								(their width being set to the table width,
								with margins taken into consideration appropriately)
							and the computed height of the table grid box (including borders and paddings)
								if it is definite (use zero otherwise).

					</ol>

				<li><b>Assign to each table-caption and table-cell their position and size.</b><br/>
					This is done by running the steps of [[#bounding-box-assignment]].

			</ol>

		<figure>
			<p class="note">
				The following schema describes the algorithm in a different way,
					to make it easier to understand.
			</p>
			<img alt="[see-caption-below]" src="images/CSS-Tables-Layout-Merged.svg" width=800 style="width: 100%">
			<figcaption>Overview of the table layout algorithm. Not normative.</figcaption>
		</figure>

		<wpt>
			html5-table-formatting-1.html
		</wpt>

	<!--——————————————————————————————————————————————————————————————————————————-->
	<h3 id="dimensioning-the-row-column-grid">Dimensioning the row/column grid</h3>

		Like mentioned in the <a href="#table-structure">Table structure</a> section,
			how many rows and columns a table has
			can be determined from the table structure.
		Both dimensioning the row/column <a>grid</a> and assigning table-cells their <nobr><a>slot</a>(s)</nobr> in that grid
			do require running the HTML Algorithms for tables.

		<h4 id="dimensioning-the-row-column-grid--step1">HTML Algorithm</h4>
		<p class="note">
			CSS Boxes that do not originate from an HTML table element equivalent to their display type
				need to be converted to their HTML equivalent before we can apply this algorithm, see below.
			There is no way to specify the <a>span</a> of a cell in css only in this level of the spec,
				the use of an HTML td element is required to do so.

		Apply the <a href="https://www.w3.org/TR/html5/tabular-data.html#forming-a-table">HTML5 Table Formatting algorithm</a>,
			where boxes act like <a href="#display-types">the HTML element equivalent to their display type</a>,
			and use the attributes of their originating element if and only if it is an HTML element of the same type
			(otherwise, they act like if they didn't have any attribute).

		<div class="example">
			<xmp class="lang-markup">
				<ul class="table">
					<li><b>One</b><i>1</i></li>
					<li><b>Two</b><i>2</i></li>
					<li><b>Three</b><i>3</i></li>
				</ul>
				<style>
					ul.table { display: table; }
					ul.table > li { display: table-row; }
					ul.table > li > * { display: table-cell; }
				</style>
			</xmp>
			produces the same row/column grid as
			<xmp class="lang-markup">
				<table><tbody>
					<tr>
						<td></td>
						<td></td>
					</tr>
					<tr>
						<td></td>
						<td></td>
					</tr>
					<tr>
						<td></td>
						<td></td>
					</tr>
				</tbody></table>
			</xmp>
		</div>

		<div class="example">
			<pre class="lang-markup" style="margin-bottom:0;padding-bottom:0;">
				&lt;!-- built using dom api, as this would be fixed by the html parser --&gt;
			</pre>
			<xmp class="lang-markup" style="margin-top:0;padding-top:0;">
				<grid style="display: table">
					<row style="display: table-row">
						<th rowspan="2">1</th>
						<colgroup style="display: table-cell" span="2" colspan="2">2</colgroup>
					</row>
					<tr>
						<td>A</td>
						<td>B</td>
						<td>C</td>
					</tr>
				</grid>
			</xmp>
			produces the same row/column grid as
			<xmp class="lang-markup">
				<table>
					<tr>
						<th rowspan="2">1</th>
						<td>2</td>
					</tr>
					<tr>
						<td>A</td>
						<td>B</td>
						<td>C</td>
					</tr>
				</table>
			</xmp>
			Note how the second cell of the first row doesn't have ```colspan=2``` applied, because its originating element is not an HTML TD element.

			<a class="hint" href="https://jsfiddle.net/eqrwaLyc/">Testcase</a>.
			<a class="hint" href="https://jsfiddle.net/eqrwaLyc/1/">!!Testcase</a>.
			<a class="hint" href="https://jsfiddle.net/sckxeLmh/2/">!Test case</a>.
			<a class="hint" href="https://jsfiddle.net/sckxeLmh/4/">!!Test case</a>.
			<a class="hint" href="https://jsfiddle.net/sckxeLmh/5/">!!Test case</a>.

		</div>

		<wpt>
			html5-table-formatting-fixed-layout-1.html
			table_grid_size_col_colspan.html
		</wpt>

		<h4 id="dimensioning-the-row-column-grid--step2">Track merging</h4>
		<p class="note">
			The HTML Table Formatting algorithm sometimes generates more tracks than necessary to layout the table properly.
			Those tracks have historically been ignored by user agents,
			so the next step just gets rid of them entirely to avoid dealing with them as exceptions later in the spec.
			We have tried to maintain the functionality with this change, but if you happen to find any issues
			due to this change please file an issue.

		Modify iteratively the obtained grid by merging consecutive tracks as follows:
		As long as there exists an <a>eligible track</a> in the obtained row/column grid such that
			there is no table-column/table-row box defining the said track explicitly, and
			both the said track and the previous one are spanned by the exact same set of cells,
			those two tracks must be merged into one single track for the purpose of computing the layout of the table.
		Reduce the <a>span</a> of the cells that spanned the deleted track by one to compensate,
			and shift similarly the tracks from which cells <a>originate</a> when needed.
		<span class="hint">(see <a href="#spanning-ghost-rows">spanning-ghost-rows test cases</a>)</span>

		For tables <a>in auto mode</a>, every track is an <dfn>eligible track</dfn> for the purpose of the track-merging algorithm.
		For tables <a>in fixed mode</a>, only rows are eligible to be merged that way; which means that every column is preserved.

		Finally, assign to the <a>table-root</a> grid its correct number of rows and columns (from its mapped element),
			and to each <a>table-cell</a> its accurate <a href="#slot">rowStart/colStart/rowSpan/colSpan</a> (from its mapped element).

		<wpt>
			column-track-merging.html
		</wpt>

	<!--——————————————————————————————————————————————————————————————————————————-->
	<h3 id="missing-cells-fixup">Missing cells fixup</h3>

		<p class=note>
			The following section clarifies and extends the CSS 2.1 statement saying that
				missing cells are rendered as if an anonymous table-cell box occupied their position in the grid
				(a "missing cell" is a slot in the row/column grid that is not covered yet by any table-cell box).

		Once the amount of columns in a table is known, any table-row box must be modified such that
			it owns enough cells to fill all the columns of the table, when taking <a>spans</a> into account.
		New table-cell <a href="#fixup-boxes">anonymous boxes</a> must be appended to its rows content until this condition is met.

		<wpt>
			col-definite-max-size-001.html
			col-definite-min-size-001.html
			col-definite-size-001.html
			html5-table-formatting-2.html
			html5-table-formatting-3.html
		</wpt>

	<!--——————————————————————————————————————————————————————————————————————————-->
	<h3 id="layout-modes">Table layout modes</h3>

		This section covers the flags which modify the way tables are being laid out.
		There are three major flags for table layout: 'table-layout', 'border-collapse', and 'caption-side'.
		The 'border-collapse' flag has an optional 'border-spacing' parameter.

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="table-layout-property">The Table-Layout property</h4>

			<pre class='propdef'>
				Name: table-layout
				Value: auto | fixed
				Initial: auto
				Applies to: <a>table grid boxes</a>
				Inherited: no
				Computed value: specified keyword
				Animation type: discrete
			</pre>

			<wpt>
				parsing/table-layout-computed.html
				parsing/table-layout-invalid.html
				parsing/table-layout-valid.html
			</wpt>

			A table-root is said to be laid out <dfn>in fixed mode</dfn>
				whenever the computed value of the 'table-layout' property is equal to <code>fixed</code>,
				and the specified width of the table root is either
					a <code>&lt;length-percentage&gt;</code>,
					<code>min-content</code> or
					<code>fit-content</code>.
			When the specified width is not one of those values,
				or if the computed value of the 'table-layout' property is <code>auto</code>,
				then the table-root is said to be laid out <dfn>in auto mode</dfn>.

			When a table-root is laid out <a>in fixed mode</a>,
			the content of its table-cells is ignored for the purpose of width computation,
			the aggregation algorithm for column sizing considers only table-cells belonging to the first row track,
			such that layout only depends on the values explicitly specified for the table-columns or cells of the first row of the table;
			columns with indefinite widths are attributed their fair share of the remaining space
			after the columns with a definite width have been considered, or 0px if there is no remaining space
			(see [[#computing-column-measures]]).

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="border-collapse-property">The Border-Collapse property</h4>

			<pre class='propdef'>
				Name: border-collapse
				Value: separate | collapse
				Initial: separate
				Applies To: <a>table grid boxes</a>
				Inherited: yes
				Computed value: specified keyword
				Animation type: discrete
			</pre>

			When the 'border-collapse' property has <code>collapse</code> as its value,
			the borders of adjacent cells are merged together such that each cell draws only half of the shared border.
			As a result, some other properties like 'border-spacing' will not applied in this case (see [[#collapsed-style-overrides]]),
			(see [[#border-collapsing]]).

			A <a>table-root</a> is said to be laid out <dfn>in collapsed-borders mode</dfn> in this case.
			Otherwise, the <a>table-root</a> is said to be laid out <dfn>in separated-borders mode</dfn>.

			<wpt>
				background-clip-001.html
				box-shadow-001.html
				collapsed-border-color-change-with-compositing.html
				collapsed-border-remove-row-group.html
				collapsed-scroll-overflow.html
				parsing/border-collapse-computed.html
				parsing/border-collapse-invalid.html
				parsing/border-collapse-valid.html
			</wpt>

			<!--——————————————————————————————————————————————————————————————————————————-->
			<h5 id="border-spacing-property">The Border-Spacing property</h5>

			<pre class='propdef'>
				Name: border-spacing
				Value: <<length [0,∞]>>{1,2}
				Initial: 0px 0px
				Inherited: yes
				Applies To: <a>table grid boxes</a> when 'border-collapse' is ''border-collapse/separate''
				Computed Value: two absolute lengths
				Animation type: by computed value
			</pre>

			The lengths specify the distance that separates adjoining cell borders <a>in separated-borders mode</a>,
				and must be non-negative.

			If one length is specified, it gives both the horizontal and vertical spacing.
			If two are specified, the first gives the horizontal spacing and the second the vertical spacing.

			See [[#computing-undistributable-space]] for details on how this affects the table layout.

			<wpt>
				animations/border-spacing-interpolation.html
				parsing/border-spacing-computed.html
				parsing/border-spacing-invalid.html
				parsing/border-spacing-valid.html
			</wpt>

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="caption-side-property">The Caption-Side property</h4>

			<pre class='propdef'>
				Name: caption-side
				Value: top | bottom
				Initial: top
				Applies to: <a>table-caption</a> boxes
				Inherited: yes
				Computed value: specified keyword
				Animation type: discrete
			</pre>

			<wpt>
				caption-side-1.html
				parsing/caption-side-computed.html
				parsing/caption-side-invalid.html
				parsing/caption-side-valid.html
			</wpt>

			This property specifies the position of the caption box with respect to the table grid box.
			Values have the following meanings:

			<dl dfn-type=value dfn-for=caption-side>
				<dt><dfn>top</dfn>
				<dd>
					Positions the caption box above the table grid box.

				<dt><dfn>bottom</dfn>
				<dd>
					Positions the caption box below the table grid box.
			</dl>

			<div class="note">
				CSS2 described a different width and horizontal alignment behavior.
				That behavior was supposed to be introduced in CSS3
					using the values <code>top-outside</code> and <code>bottom-outside</code>.
				<a href="http://fantasai.inkedblade.net/style/discuss/captions/">#REF</a>
			</div>

			<div class="note">
				Gecko also supports the "left" and "right" values, but currently this specification
				is not attempting to define their implementation of said values.
			</div>

			<div class="note">
				Gecko has a bug when dealing with multiple captions.
				<a class="hint" href="http://codepen.io/FremyCompany/pen/WrJxwP">!Testcase</a>
			</div>

			<div class="example">

				To align caption content horizontally within the caption box, use the 'text-align' property.

				In this example, the 'caption-side' property places captions below tables.
				The caption will be as wide as the parent of the table, and caption text will be left-justified.

				<pre>
					caption {
						caption-side: bottom;
						width: auto;
						text-align: left
					}
				</pre>
			</div>

	<!--——————————————————————————————————————————————————————————————————————————-->
	<h3 id="style-overrides">Style overrides</h3>

		Some css properties behave differently inside css tables.
		The following sections list the exceptions and their effects.

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="global-style-overrides">Overrides applying in all modes</h4>

			The following rules apply to all tables, irrespective of the layout mode in use.

			<ul>

				<li>The computed values of properties 'position', 'float', 'margin'-*, 'top', 'right', 'bottom', and 'left' on the table
					are used on the table-wrapper box and not the table grid box;
					the same holds true for the properties whose use could force the used value of 'transform-style' to <code>flat</code> (see [[css-transforms-2#grouping-property-values|list]]) and their shorthands/longhands relatives:
						this list currently includes 'overflow', 'opacity', 'filter', 'clip', 'clip-path', 'isolation', 'mask'-*, 'mix-blend-mode', 'transform'-* and 'perspective'.
					<br>
					Where the specified values are not applied on the table grid and/or wrapper boxes,
						the unset values are used instead for that box (inherit or initial, depending on the property).

					<wpt>
						caption-relative-positioning.html
					</wpt>

				<li>The 'overflow' property on the <a>table-root</a> and <a>table-wrapper</a> box, when its value is not either <code>visible</code>, <code>clip</code> or <code>hidden</code>,
					is ignored and treated as if its value was <code>visible</code>.

				<li>All css properties of <a>table-column</a> and <a>table-column-group</a> boxes are ignored,
					except when explicitly specified by this specification.

				<li>The 'margin', 'padding', 'overflow' and 'z-index' of <a>table-track</a> and <a>table-track-group</a> boxes are ignored.

				<li>The 'margin' of <a>table-cell</a> boxes is ignored (as if it was set to 0px).

					<wpt>
						no-overflow-with-table-cell-margins.html
					</wpt>

				<li>The 'background' of <a>table-cell</a> boxes
					are painted using a special background painting algorithm described in [[#drawing-cell-backgrounds]].

			</ul>


		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="collapsed-style-overrides">Overrides applying in collapsed-borders mode</h4>

			When a table is laid out <a>in collapsed-borders mode</a>, the following rules apply:

			<ul>
				<li>The 'padding' of the <a>table-root</a> is ignored (as if it was set to 0px).

				<li>The 'border-spacing' of the <a>table-root</a> is ignored (as if it was set to 0px).

				<li>The 'border-radius' of both <a>table-root</a> and <a>table-non-root</a> boxes
					is ignored (as if it was set to 0px).
				<li>The values used for the layout and rendering of the borders of the <a>table-root</a>
						and the <a>table-cell</a> boxes it owns are
						determined using a special conflict resolution algorithm described in [[#border-collapsing]].
			</ul>

	<!--——————————————————————————————————————————————————————————————————————————-->
	<h3 id="border-collapsing">Border-collapsing</h3>

		<div class="note">

			This entire section is a proposal to make the rendering of collapsed borders sane.
			As implementations diverge very visibly, it is expected to require more discussion than some other parts.
			Since browsers handle this so differently, convergence cannot happen without reimplementation.
			A major concern for this proposal was to support as many cases as possible, and yet
				keep the effort required for a new implementation of tables as low as possible.

			<b>Background:</b>
			CSS+HTML allow unprecedented combinations of border modes for table junctions,
				and it makes it difficult to support all cases properly;
				in fact some combinations are not <a href="https://en.wikipedia.org/wiki/Well-posed_problem">well-posed problems</a>,
				so no rendering algorithm could be optimal.

			Because they grew from something simple (HTML) to something very complex (HTML+CSS),
				the current table rendering models (backgrounds and borders) used by web browsers are insane
				(in the sense they are buggy, not interoperable and not CSSish at all).
			Many usual CSS assumptions are broken, and renderings diverge widely.

			This proposal aims at fixing this situation.

		</div>

		<wpt>
			border-collapse-double-border.html
			border-collapse-dynamic-col-001.html
			border-collapse-dynamic-oof.html
			border-collapse-dynamic-section.html
			border-collapse-empty-cell.html
			border-collapse-rowspan-cell.html
			collapsed-border-remove-cell.html
		</wpt>

		ISSUE(604): border-collapsing breaking change from 2.1

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="conflict-resolution-for-collapsed-borders">Conflict Resolution for Collapsed Borders</h4>

			<wpt>
				border-conflict-resolution.html
			</wpt>

			When they are laid out <a>in collapsed-borders mode</a>,
				<a>table-root</a> and <a>table-cell</a> boxes sharing a border attempt to unify their borders
				so that they render using the same style, width, and color (whenever this is possible).
			This is accomplished by running the following algorithm.

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h5 id="border-conflict-resolution-algorithm">Conflict Resolution Algorithm for Collapsed Borders</h5>
		<div class="note">
			For the purpose of this algorithm, &#8220;harmonizing&#8221; a set of borders means
				applying the <a href="#border-style-harmonization-algorithm">&#8220;Harmonization Algorithm for Collapsed Borders&#8221;</a> on the given set of borders, and
				set those borders' used values to the value resulting from the algorithm,
				except for cells having a 'border-image-source' different from none:
				those keep their initial values.
		</div>

		<b>For any <a>table-cell</a> C° of a <a>table-root</a>:</b>

		<ul>
			<li>Resolve conflicts with border-right:
			<ol start="0">
				<li>Let S be an ordered set of <a>table-cell</a> border styles, sorted by cell in RowStart/ColumnStart order;
					initially, let S contain only C°&#8217;s border-right style

				<li>Add to the set S the border-left style of all cells
					sharing a section of their left border with C°&#8217;s right border

				<li>Repeat the following two instructions, until no new border style is added to S:
				<ul>
					<li>For all newly-added left borders from cell C<sub>i</sub> having a <a href="#slot">rowspan</a> greater than one,
						add to the set S the border-right style of all cells
						sharing a section of their border-right with C<sub>i</sub>&#8217;s border-left

					<li>For all newly-added right borders from cell C<sub>i</sub> having a <a href="#slot">rowspan</a> greater than one,
						add to the set S the border-left style of all cells
						sharing a section of their border-left with C<sub>i</sub>&#8217;s border-right
				</ul>

				<li>Harmonize the conflicting borders of S
			</ol>

			<li>Resolve conflicts with border-bottom:
			<ol start="0">
				<li>Let S be an ordered set of <a>table-cell</a> border styles, sorted by cell in RowStart/ColumnStart order;
					initially, let S contain only C°&#8217;s border-bottom style

				<li>Add to the set S the border-top style of all cells
					sharing a section of their top border with C°&#8217;s bottom border

				<li>Repeat the following two instructions, until no new border style is added to S:
				<ul>
					<li>For all newly-added top borders from cell C<sub>i</sub> having a <a href="#slot">rowspan</a> greater than one,
						add to the set S the border-bottom style of all cells
						sharing a section of their bottom border with C<sub>i</sub>&#8217;s top border

					<li>For all newly-added bottom borders from cell C<sub>i</sub> having a <a href="#slot">rowspan</a> greater than one,
						add to the set S the border-top style of all cells
						sharing a section of their top border with C<sub>i</sub>&#8217;s bottom border
				</ul>

				<li>Harmonize the conflicting borders of S
			</ol>

			<li>Divide the used width of all borders by two.<br>
				<div class="note">
					This effect will be compensated at rendering time wherever needed,
					but is required for layout correctness.
					<span class="hint">(see [[#drawing-collapsed-borders-2]])</span>
				</div>
		</ul>

		<b>Then, for that <a>table-root</a>:</b>

		<ul>
			<li>Harmonize the <a>table-root</a> border-{top,bottom,left,right}
					with the corresponding border of all cells forming the border of the table (independently),
					without actually modifying the border properties of the <a>table-root</a>.<br>
				<br>
				If the table and the cell border styles have the same specificity,
					keep the cell border style.
				<br>
				Once this is done, set the <a>table-root</a> border-{&#8230;}-width
					to half the maximum width found during the harmonization processes for that border,
					then set border-{&#8230;}-style to solid, and border-{&#8230;}-color to transparent.
		</ul>

		<!--——————————————————————————————————————————————————————————————————————————-->
		<div class="note">
			Implementations may of course choose to skip some of the steps of the previous algorithm,
			provided they can prove those have no visible impact on the final results;
			certain borders are harmonized more than once using the previous steps,
			but preventing this would make the spec harder to read.
		</div>

		<div class="example">
			To help the reader get a better idea of what this algorithm is doing,
			the main steps of applying the previous algorithm over a sample table have been outlined here:
			<br/>
			<br/>
			<a href="https://jsfiddle.net/bn3d1sm4/">https://jsfiddle.net/bn3d1sm4/</a><br/>
			<a href="https://jsfiddle.net/bn3d1sm4/1/">https://jsfiddle.net/bn3d1sm4/1/</a><br/>
			<a href="https://jsfiddle.net/bn3d1sm4/2/">https://jsfiddle.net/bn3d1sm4/2/</a><br/>
			&#8230;<br/>
			<a href="https://jsfiddle.net/bn3d1sm4/15/">https://jsfiddle.net/bn3d1sm4/15/</a><br/>
		</div>

		<wpt>
			collapsed-border-writing-mode-color.html
			subpixel-collapsed-borders-001.html
			subpixel-collapsed-borders-002.html
			subpixel-collapsed-borders-003.html
			subpixel-table-cell-width-001.html
			subpixel-table-cell-width-002.html
		</wpt>

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h5 id="border-style-harmonization-algorithm">Harmonization Algorithm for Collapsed Borders</h5>
		<div class="note">
			For the purpose of this algorithm, &#8220;considering&#8221; a border&#8217;s properties means
			that &#8220;if its properties are <a href="#border-specificity">more specific</a> than CurrentlyWinningBorderProperties,
			set CurrentlyWinningBorderProperties to its properties&#8221;.
		</div>

		ISSUE(606): Change specificity in harmonization of collapsed borders?

		Given an ordered set of border styles (BC<sub>1,</sub> BC<sub>2</sub>, &#8230; located in cells C<sub>1,</sub> C<sub>2</sub>, &#8230;)
		execute the following algorithm to determine the used value of the border properties for those conflicting borders.

		<ul>
			<li>
				Set CurrentlyWinningBorderProperties to &#8220;border: 0px none transparent&#8221;

			<li>
				For each border BC<sub>i</sub>:
				<ul>
					<li>Consider the BC<sub>i</sub> border&#8217;s properties
				</ul>

			<li>
				If the border separates two columns:
				<ul>
					<li>For each border BC<sub>i</sub>:
						For each table-column spanned by the C<sub>i</sub> cell, if any.
						Consider the border&#8217;s properties of any border of the table-column that would be drawn contiguously to BC<sub>i</sub>.

					<li>For each border BC<sub>i</sub>:
						For each table-column-group containing a column spanned by the C<sub>i</sub> cell, if any.
						Consider the border&#8217;s properties of any border of the table-column-group that would be drawn contiguously to BC<sub>i</sub>.
				</ul>

			<li>
				If the border separates two rows:
				<ul>
					<li>For each border BC<sub>i</sub>:
						For each table-row spanned by the C<sub>i</sub> cell, if any.
						Consider the border&#8217;s properties of any border of the table-row that would be drawn contiguously to BC<sub>i</sub>.

					<li>For each border BC<sub>i</sub>:
						For each table-row-group containing a row spanned by the C<sub>i</sub> cell, if any.
						Consider the border&#8217;s properties of any border of the table-row-group that would be drawn contiguously to BC<sub>i</sub>.
				</ul>

			<li>
				Return CurrentlyWinningBorderProperties
		</ul>

		<wpt>
			rowspan-cell-border-after-color.html
		</wpt>

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h5 id="border-specificity">Specificity of a border style</h5>

		Given two borders styles, the border style having the most specificity is the border style which&#8230;

		<ol>
			<li>&#8230; has the value "hidden" as 'border-style', if only one does
			<li>&#8230; has the biggest 'border-width', once converted into css pixels
			<li>&#8230; has the 'border-style' which comes first in the following list:
				<pre>double, solid, dashed, dotted, ridge, outset, groove, inset, none</pre>
		</ol>

		If none of these criteria match, then both borders share the same specificity.

	<!--——————————————————————————————————————————————————————————————————————————-->
	<h3 id="content-measure">Computing table measures</h3>

		<wpt>
			calc-percent-plus-0px-auto.html
			calc-percent-plus-0px-fixed.html
			height-distribution/percentage-sizing-of-table-cell-children-002.html
		</wpt>

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="computing-undistributable-space">Computing Undistributable Space</h4>

			The <dfn>undistributable space</dfn> of the table is the sum of
				the distances between the borders of consecutive table-cells
				(and between the border of the table-root and the table-cells).

			The distance between the borders of two consecutive table-cells is the 'border-spacing', if any.

			The distance between
				the table border and
				the borders of the cells on the edge of the table
			is
				the table's padding for that side,
				plus the relevant border spacing distance (if any).

			<div class="example">
				For example, on the right hand side, the distance is padding-right + horizontal border-spacing.
			</div>

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="computing-cell-measures">Computing Cell Measures</h4>

			The following terms are parameters of tables or table cells.
			These parameters encapsulate the differences
				between tables with different values of 'border-collapse' (separate or collapse)
				so that the remaining subsections of this section do not need to refer to them differently.

			<dl>
				<!--——————————————————————————————————————————————————————————————————————————-->
				<dt><dfn>cell intrinsic offsets</dfn></dt>
				<dd>The cell intrinsic offsets is a term to capture the parts of padding and border of a table cell
						that are relevant to intrinsic width calculation.
					It is a set of computed values for border-left-width, padding-left, padding-right, and border-right-width
						(along with zero values for margin-left and margin-right)
						defined as follows:
					<ul>
						<li><a>In separated-borders mode</a>: the computed horizontal padding and border of the table-cell
						<li><a>In collapsed-borders mode</a>: the computed horizontal padding of the cell and, for border values,
							the used border-width values of the cell (half the winning border-width)
					</ul>

				<!--——————————————————————————————————————————————————————————————————————————-->
				<dt><dfn>table intrinsic offsets</dfn></dt>
				<dd>The table intrinsic offsets capture the parts of the padding and border of a table
						that are relevant to intrinsic width calculation.
					It is a set of computed values for border-left-width, padding-left, padding-right, and border-right-width
						(along with zero values for margin-left and margin-right)
						defined as follows:
					<ul>
						<li><a>In separated-borders mode</a>: the computed horizontal padding and border of the table-root
						<li><a>In collapsed-borders mode</a>: the used border-width values of the cell (half the winning border-width)
					</ul>

					<p class="note">
						The margins are not included in the [=table intrinsic offsets=]
							because handling of margins depends on the 'caption-side' property.

					ISSUE(608): Handling of intrinsic offsets when in border collapsing mode

				<!--——————————————————————————————————————————————————————————————————————————-->
				<dt><dfn>total horizontal border spacing</dfn></dt>
				<dd>The total horizontal border spacing is defined for each table:
					<ul>
						<li>For tables laid out <a>in separated-borders mode</a> containing at least one column,
							the horizontal component of the computed value of the border-spacing property times one plus
							the number of columns in the table
						<li>Otherwise, 0
					</ul>

				<!--——————————————————————————————————————————————————————————————————————————-->
				<dt><dfn id="offsets-adjusted-width">offsets-adjusted min-width, width, and max-width</dfn></dt>
				<dd>
					<ul>
						<li>For <a>table-track</a> and <a>table-track-group</a> boxes, 
							the offsets-adjusted value of width properties is their computed value, 
							irrespective of the value of 'box-sizing' applied on the element.
						<li>For <a>table-cell</a> boxes,
							the offsets-adjusted value of width properties is their computed value
							from which the cell's border-{left|right}-width and/or padding-{left|right} have eventually been deduced,
							depending on the value of 'box-sizing'.
							<div class="note">
								When the table is laid out <a>in collapsed-borders mode</a>, 
								the border value to deduce is half the value of the winning border value on each side
								(see <a href="#border-conflict-resolution-algorithm">conflict resolution explanation note</a>)
							</div>
					</ul>
					
					<a class="hint" href="https://wptest.center/#/hmmbt3">Testcase.</a>
					<a class="hint" href="https://wptest.center/#/rnfac4">Testcase.</a>
					<a class="hint" href="https://wptest.center/#/3lao88">Testcase.</a>

				<!--——————————————————————————————————————————————————————————————————————————-->
				<dt><dfn>outer min-content</dfn> and <dfn>outer max-content</dfn> widths</dt>
				<dd>The outer min-content and max-content widths are defined for table cells, columns, and column groups.
					The 'width', 'min-width', and 'max-width' values used in these definitions are the offsets-adjusted values defined <a href="#offsets-adjusted-width">above</a>:
					<ul>
						<li>The <b>outer min-content width</b> of a table-cell is
								<code>max('min-width', min-content width)</code>
								adjusted by the [=cell intrinsic offsets=].

						<li>The <b>outer min-content width</b> of a table-column or table-column-group is
							<code>max('min-width', 'width')</code>.

						<li>The <b>outer max-content width</b> of a table-cell in a [=constrainedness|non-constrained column=] is
								<code>max('min-width', 'width', min-content width, min('max-width', max-content width))</code>
								adjusted by the [=cell intrinsic offsets=].

						<li>The <b>outer max-content width</b> of a table-cell in a [=constrainedness|constrained column=] is
								<code>max('min-width', 'width', min-content width, min('max-width', 'width'))</code>
								adjusted by the [=cell intrinsic offsets=].

						<li>The <b>outer max-content width</b> of a table-column or table-column-group is
								<code>max('min-width', min('max-width', 'width'))</code>.
					</ul>

				<!--——————————————————————————————————————————————————————————————————————————-->
				<dt><dfn>percentage contribution</dfn>s</dt>
				<dd>The percentage contribution of a table cell, column, or column group
						is defined in terms of the computed values of 'width' and 'max-width'
						that have computed values that are percentages:<br/>
					<br/>
					<code>min(percentage 'width', percentage 'max-width')</code>.<br/>
					<br/>
					If the computed values are not percentages,
						then <code>0%</code> is used for 'width', and
						an <code>infinite</code> percentage is used for 'max-width'.

					<div class="note">
						Please note that 'min-width' is not included in this computation.
							As a result, a percentage 'min-width' is ignored.
						Since 'width' functions like a 'min-width' in table layout
							and column sizing cannot be both length-based and percent-based,
							authors should not use 'min-width' on table-internal boxes
							and prefer to rely on 'width' only instead.
					</div>
			</dl>

			<wpt>
				fractional-percent-width.html
			</wpt>

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="computing-column-measures">Computing Column Measures</h4>

			This subsection defines three important values associated with each column of a table: 
				their <a href="#min-content-width-of-a-column">min-content width</a> (the smallest possible width attributed to this column),
				their <a href="#max-content-width-of-a-column">max-content width</a> (the width that would be attributed to the column if no other constraint applied),
				their <a href="#intrinsic-percentage-width-of-a-column">intrinsic percentage width</a> (the percentage of the table width the column desires to get, and could end up overriding its max-content width).

			<p class="note">
			To compute these values, an iterative algorithm is used. 
				First, these values are computed ignoring any cell spanning more than one column.
				Then, these values are updated by taking into account cells spanning incrementally more columns.
				When cells that spanned all columns of the table have been considered, this algorithm ends and the values are then finalized.

			<p class="advisement">
				For the purpose of measuring a column when laid out <a>in fixed mode</a>,
					only cells which <a>originate</a> in the first row of the table
					(after reordering the header and footer)
					will be considered, if any.
				In addition, the min-content and max-content width of cells
					is considered zero unless they are directly specified
					as a length-percentage, in which case they are resolved
					based on the table width (if it is definite, otherwise use 0).

				For the purpose of calculating the outer min-content width of cells,
					descendants of table cells whose width depends on percentages of their parent cell's width
					are considered to have an auto width.
				<a href="https://jsfiddle.net/0e12ve9b/1/">Testcase</a>
				<a href="https://jsfiddle.net/0e12ve9b/3/">Testcase</a>

			<dl>
				<!--——————————————————————————————————————————————————————————————————————————-->
				<dt>min-content width of a column based on cells of span up to 1</dt>
				<dd>The largest of:
					<ul>
						<li>the width specified for the column:<ul>
							<li>the <a>outer min-content</a> width of its corresponding table-column, if any (and not auto)
							<li>the <a>outer min-content</a> width of its corresponding table-column-group, if any
							<li>or 0, if there is none
							</ul>
						<li>the <a>outer min-content</a> width of each cell that <a>spans</a> the column whose <a href="#slot">colSpan</a> is 1
							(or just the one in the first row <a>in fixed mode</a>)
							or 0 if there is none
					</ul>

				<!--——————————————————————————————————————————————————————————————————————————-->
				<dt>max-content width of a column based on cells of span up to 1</dt>
				<dd>The largest of:
					<ul>
						<li>the <a>outer max-content</a> width of its corresponding table-column-group, if any
						<li>the <a>outer max-content</a> width of its corresponding table-column, if any
						<li>the <a>outer max-content</a> width of each cell that <a>spans</a> the column whose <a href="#slot">colSpan</a> is 1
							(or just the one in the first row if <a>in fixed mode</a>)
							or 0 if there is no such cell
					</ul>

				<!--——————————————————————————————————————————————————————————————————————————-->
				<dt>intrinsic percentage width of a column based on cells of span up to 1</dt>
				<dd>The largest of the [=percentage contributions=] of
						each cell that <a>spans</a> the column whose <a href="#slot">colSpan</a> is 1,
						of its corresponding table-column (if any), and
						of its corresponding table-column-group (if any)

				<!--——————————————————————————————————————————————————————————————————————————-->
				<dt>min-content width of a column based on cells of span up to N (N > 1)</dt>
				<dd>the largest of the min-content width of the column based on cells of span up to N-1 and the contributions
						of the cells in the column whose <a href="#slot">colSpan</a> is N,
						where the contribution of a cell is the result of taking the following steps:
					<ol>
						<li>Define the baseline min-content width
							as the sum of the min-content widths based on cells of span up to N-1
							of all columns that the cell spans.

						<li>Define the baseline max-content width
							as the sum of the max-content widths based on cells of span up to N-1
							of all columns that the cell spans.

						<li>Define the baseline border spacing as the sum of the horizontal
							border-spacing for any columns spanned by the cell,
							other than the one in which the cell originates.

						<li>The contribution of the cell is the sum of:
							<ul>
								<li>the min-content width of the column based on cells of span up to N-1
								<li>the product of:
									<ul>
										<li>the ratio of:
											<ul>
												<li>the max-content width of the column based on cells of span up to N-1 of the column
													minus the min-content width of the column based on cells of span up to N-1 of the column, to
												<li>the baseline max-content width minus the baseline min-content width
											</ul>
											or zero if this ratio is undefined, and

										<li>the outer min-content width of the cell
											minus the baseline min-content width and the baseline border spacing,
											clamped to be at least 0 and at most the difference
											between the baseline max-content width and the baseline min-content width
									</ul>
								<li>the product of:
									<ul>
										<li>the ratio of the max-content width
											based on cells of span up to N-1 of the column to the baseline max-content width
										<li>the outer min-content width of the cell
											minus the baseline max-content width and baseline border spacing,
											or 0 if this is negative
									</ul>
							</ul>
					</ol>

				<!--——————————————————————————————————————————————————————————————————————————-->
				<dt>max-content width of a column based on cells of span up to N (N > 1)</dt>
				<dd>The largest of the max-content width
					based on cells of span up to N-1 and the contributions of the cells in the column whose <a href="#slot">colSpan</a> is N,
					where the contribution of a cell is the result of taking the following steps:
					<ol>
						<li>Define the baseline max-content width as
							the sum of the max-content widths based on cells of span up to N-1
							of all columns that the cell spans.

						<li>Define the baseline border spacing as
							the sum of the horizontal border-spacing
							for any columns spanned by the cell,
							other than the one in which the cell originates.

						<li>The contribution of the cell is the sum of:
							<ul>
								<li>the max-content width of the column based on cells of span up to N-1
								<li>the product of:
									<ul>
										<li>the ratio of the max-content width
											based on cells of span up to N-1 of the column to the baseline max-content width
										<li>the outer max-content width of the cell
											minus the baseline max-content width and the baseline border spacing,
											or 0 if this is negative
									</ul>
							</ul>
					</ol>


				<!--——————————————————————————————————————————————————————————————————————————-->
				<dt>intrinsic percentage width of a column based on cells of span up to N (N > 1)</dt>
				<dd>If the intrinsic percentage width of a column based on cells of span up to N-1 is greater than 0%,
					then the intrinsic percentage width of the column based on cells of span up to N is
					the same as the intrinsic percentage width of the column based on cells of span up to N-1.<br/>
					<br/>
					Otherwise, it is the largest of the contributions of the cells in the column
					whose <a href="#slot">colSpan</a> is N,
					where the contribution of a cell is the result of taking the following steps:
					<ol>
						<li>Start with the [=percentage contribution=] of the cell.
						<li>Subtract the intrinsic percentage width of the column based on cells of span up to N-1 of all columns that the cell spans.
							If this gives a negative result, change it to 0%.
						<li>Multiply by the ratio of
							<ul>
								<li>the column's non-spanning max-content width to
								<li>the sum of the non-spanning max-content widths of all columns spanned by the cell
									that have an intrinsic percentage width of the column based on cells of span up to N-1 equal to 0%.
							</ul>
							However, if this ratio is undefined because the denominator is zero,
							instead use the 1 divided by the number of columns spanned by the cell
							that have an intrinsic percentage width of the column based on cells of span up to N-1 equal to zero.
					</ol>

				<!--——————————————————————————————————————————————————————————————————————————-->
				<dt><dfn>min-content width of a column</dfn></dt>
				<dd>the min-content width of the column based on cells of span up to N, where N is the number of columns in the table

				<!--——————————————————————————————————————————————————————————————————————————-->
				<dt><dfn>max-content width of a column</dfn></dt>
				<dd>the max-content width of the column based on cells of span up to N, where N is the number of columns in the table

				<!--——————————————————————————————————————————————————————————————————————————-->
				<dt><dfn>intrinsic percentage width of a column</dfn></dt>
				<dd>the smaller of:
					<ul>
						<li>the intrinsic percentage width of the column based on cells of span up to N,
							where N is the number of columns in the table
						<li>100% minus the sum of the intrinsic percentage width of all prior columns in the table
							(further left when direction is "ltr" (right for "rtl"))
							<a href="https://wptest.center/#/45xdf3" class="hint">Testcase</a>
					</ul>
					<p class="note">
						The clamping of the total of the intrinsic percentage widths of columns to a maximum of 100%
						means that the table layout algorithm is not invariant under switching of columns.
					</p>

				<!--——————————————————————————————————————————————————————————————————————————-->
				<dt><dfn>constrainedness</dfn></dt>
				<dd>A column is constrained if
						its corresponding table-column-group (if any),
						its corresponding table-column (if any),
						or any of the cells spanning only that column
					has a computed 'width' that is not "auto",
						and is not a percentage.

			</dl>

			<div class="note">
				In a future revision of this specification, this algorithm will need to account
					for character-alignment of cells ('<<string>>' values of the 'text-align' property).
				This requires (based on the 9 March 2011 editor's draft of css3-text) separately tracking max-content widths
					for the part of the column before the center of the alignment string and
					the part of the column after the center of the alignment string.
				For tracking min-content widths, there are two options:
					either not track them, or track three values:
					two values as for max-content widths for any cells that do not have break points in them,
					and a fourth value for any cells that do have break points in them
					(and to which character alignment is therefore not mandatory).
			</div>

			<div class="issue">
				EDITORIAL.
				The way this describes distribution of widths from colspanning cells is wrong.
				For min-content and max-content widths it should refer to the rules
					for distributing excess width to columns for intrinsic width calculation.
			</div>

			<wpt>
				height-distribution/computing-row-measure-0.html
				height-distribution/computing-row-measure-1.html
				height-distribution/percentage-sizing-of-table-cell-children.html
				height-distribution/percentage-sizing-of-table-cell-replaced-children-001.html
				table-colspan-percent-auto.html
				width-distribution/computing-column-measure-0.html
				width-distribution/computing-column-measure-1.html
				width-distribution/computing-column-measure-2.html
				width-distribution/td-max-width-auto-layout.html
				width-distribution/td-min-width-auto-layout.html
			</wpt>

<!--
██      ██ ████ ████████  ████████ ██     ██       ████████  ████  ██████  ████████ ████████  ████ ████████  ██     ██ ████████ ████  ███████  ██    ██
██  ██  ██  ██  ██     ██    ██    ██     ██       ██     ██  ██  ██    ██    ██    ██     ██  ██  ██     ██ ██     ██    ██     ██  ██     ██ ███   ██
██  ██  ██  ██  ██     ██    ██    ██     ██       ██     ██  ██  ██          ██    ██     ██  ██  ██     ██ ██     ██    ██     ██  ██     ██ ████  ██
██  ██  ██  ██  ██     ██    ██    █████████       ██     ██  ██   ██████     ██    ████████   ██  ████████  ██     ██    ██     ██  ██     ██ ██ ██ ██
██  ██  ██  ██  ██     ██    ██    ██     ██       ██     ██  ██        ██    ██    ██   ██    ██  ██     ██ ██     ██    ██     ██  ██     ██ ██  ████
██  ██  ██  ██  ██     ██    ██    ██     ██       ██     ██  ██  ██    ██    ██    ██    ██   ██  ██     ██ ██     ██    ██     ██  ██     ██ ██   ███
 ███  ███  ████ ████████     ██    ██     ██       ████████  ████  ██████     ██    ██     ██ ████ ████████   ███████     ██    ████  ███████  ██    ██
-->
	<h3 id="width-distribution">Available Width Distribution</h3>

		<wpt>
			width-distribution/distribution-algo-1.html
			width-distribution/distribution-algo-2.html
			width-distribution/distribution-algo-min-content-guess.html
			width-distribution/distribution-algo-min-content-percent-guess.html
			width-distribution/distribution-algo-min-content-specified-guess.1.html
			width-distribution/distribution-algo-min-content-specified-guess.html
			width-distribution/td-with-subpixel-padding-vertical-rl.html
			width-distribution/td-with-subpixel-padding.html
		</wpt>

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="computing-the-table-width">Computing the table width</h4>

			Before deciding on the final width of all columns,
				it is necessary to compute the width of the table itself.

			<p class="note">
				As noted before, this would usually be the sum of preferred width of all columns, plus any extra.
				In this case, the width distribution will result in giving each column its preferred width.
				There are however a few cases where the author asks for some other width explicitly,
					as well as a few cases where the table cannot be given the width it requires.

			The <dfn id="capmin">caption width minimum (CAPMIN)</dfn> is
				the largest of the <a href="#table-caption">table captions</a> <a>min-content contribution</a>.

			The <dfn id="gridmin">row/column-grid width minimum (GRIDMIN)</dfn> width is
				the sum of the <a href="#min-content-width-of-a-column">min-content width</a> of all the columns
				plus cell spacing or borders.

			The <dfn id="gridmax">row/column-grid width maximum (GRIDMAX)</dfn> width is
				the sum of the <a href="#max-content-width-of-a-column">max-content width</a> of all the columns
				plus cell spacing or borders.

			The <dfn id="used-min-width-of-table">used min-width of a table</dfn> is
				the greater of
					the resolved 'min-width',
					<a href="#capmin">CAPMIN</a>, and
					<a href="#gridmin">GRIDMIN</a>.

			The <dfn id="used-width-of-table">used width of a table</dfn> depends on the columns and captions widths as follows:

			<ul>
				<li>If the <a>table-root</a>'s 'width' property has a computed value (resolving to <dfn>resolved-table-width</dfn>)
					other than <code>auto</code>,
						the <a href="#used-width-of-table">used width</a> is the greater of
							<a>resolved-table-width</a>, and
							the <a href="#used-min-width-of-table">used min-width of the table</a>.
					<div class="note">
						If the used width is greater than <a href="#gridmin">GRIDMIN</a>,
						the extra width should be distributed over the columns.
						<span class=hint>See [[#width-distribution]].</span>
					</div>

				<li>If the <a>table-root</a> has 'width: auto',
						the <a href="#used-width-of-table">used width</a> is the greater of
							min(<a href="#gridmax">GRIDMAX</a>, the table's containing block width),
							the <a href="#used-min-width-of-table">used min-width of the table</a>.
			</ul>

			<wpt>
				absolute-tables-002.html
				absolute-tables-003.html
			</wpt>

			The <dfn>assignable table width</dfn> is
				the used width of the table
				minus the [=total horizontal border spacing=] (if any).
			This is the width that we will be able to allocate to the columns.

			<div class="note">
				In this algorithm, rows (and row groups) and columns (and column groups) both constrain
				and are constrained by the dimensions of the cells they contain.
				Setting the width of a column might indirectly influence the height of a row, and vice versa.
			</div>

			<wpt>
				visibility-collapse-col-001.html
				visibility-collapse-col-002.html
				visibility-collapse-col-003.html
				visibility-collapse-col-004-dynamic.html
				visibility-collapse-col-005.html
				visibility-collapse-colspan-001.html
				visibility-collapse-colspan-002.html
				visibility-hidden-col-001.html
				visibility-hidden-nested-001.html
				visibility-hidden-nested-002.html
				width-distribution/computing-table-width-0.html
				width-distribution/computing-table-width-1.html
				table-intrinsic-size-001.html
				table-intrinsic-size-002.html
				table-intrinsic-size-003.html
				table-intrinsic-size-004.html
			</wpt>

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="width-distribution-principles">Core distribution principles</h4>

			<p style="font-style: italic">
				This section is not normative.

			<h5 id="width-distribution-principles-rN">Rules</h5>

			Ideally, each column should get its preferred width (usually its <a href="#max-content-width-of-a-column">max-content width</a>).
			However, the <a>assignable table width</a> calculated before
				could be either too big or too small to achieve this result,
				in which case the user agent must assign adhoc widths to columns
				as described in the width distribution algorithm.

			This algorithm follows three rules when determining a column's used width:

			<p id="width-distribution-principles-r0">
				<b>Rule 0: </b>
				<span>
					<a>In fixed mode</a>,
					auto and percentages columns are assigned a minimum width of zero pixels, and
					percentage resolution follows a different set of rules,
					whose goal is to ensure pixel columns always get assigned their preferred width.
				</span>

			<p id="width-distribution-principles-r1">
				<b>Rule 1: </b>
				<span>
					When assigning preferred widths,
					specified percent columns have a higher priority
					than specified unit value columns, which have a higher priority
					than auto columns.
				</span>

			<p id="width-distribution-principles-r2">
				<b>Rule 2: </b>
				<span>
					Columns using the same <a>sizing type</a> (percent columns, pixel columns, or auto columns) follow the same distribution method.
					For example, they all get their <a href="#min-content-width-of-a-column">min-content width</a> or they all get their <a href="#max-content-width-of-a-column">max-content width</a>.
					<br/>
					<span class="note" style="display: block; margin-top: 0.5em">
						There is one exception to this rule.
						When giving its preferred percent width to a percent-column,
							if that would result in a size smaller than its <a href="#min-content-width-of-a-column">min-content width</a>,
							the column will be assigned its <a href="#min-content-width-of-a-column">min-content width</a> instead
							though the percent-columns group as a whole is still regarded
							as being assigned the preferred percent widths.
					</span>
				</span>

			<p id="width-distribution-principles-r3">
				<b>Rule 3: </b>
				<span>
					The sum of width assigned to all columns should be equal to the <a>assignable table width</a>.
				</span>

			<style>
				#width-distribution-principles-r0,
				#width-distribution-principles-r1,
				#width-distribution-principles-r2,
				#width-distribution-principles-r3 {
					display: flex;
				}

				#width-distribution-principles-r0 > :first-child,
				#width-distribution-principles-r1 > :first-child,
				#width-distribution-principles-r2 > :first-child,
				#width-distribution-principles-r3 > :first-child {
					flex-shrink: 0; flex-basis: 5em;
				}

				#width-distribution-principles-r0 > *,
				#width-distribution-principles-r1 > *,
				#width-distribution-principles-r2 > *,
				#width-distribution-principles-r3 > * {
					display: inline-block;
				}
			</style>

			<wpt>
				percent-width-cell-dynamic.html
			</wpt>

			<h5 id="width-distribution-principles-rR">Available sizings</h5>

			All three types of columns have the following possible used widths.

				<ol>
					<li>min-content width: <br/>
						<span class="hint">The size required to fit the content of the column</span>
					<li>min-content width + delta: <br/>
						<span class="hint">A value between the min-content and preferred widths</span>
					<li>preferred width: <br/>
						<span class="hint">The size specified for the column,
							or the size required to fit the content of the column without breaking</span>
					<li>preferred width + delta<br/>
						<span class="hint">A value larger than the preferred width</span></ol>

			The distribution algorithm defines those values and explains when to use them.

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="width-distribution-algorithm">Distribution algorithm</h4>

			When a table is laid out at a given used width,
				the used width of each column must be determined as follows,
				eventually after considering <a href="#width-distribution-in-fixed-mode">the changes to this algorithm</a>
				applied <a>in fixed mode</a>.

			First, each column of the table is assigned a <dfn>sizing type</dfn>:

				- <dfn id="table-percent-column" export>percent-column</dfn>:<br>
					a column whose any constraint is defined to use a percentage only (with a value different from 0%)
				- <dfn id="table-pixel-column" export>pixel-column</dfn>:<br>
					column whose any constraint is defined to use a defined length only (and is not a percent-column)
				- <dfn id="table-auto-column" export>auto-column</dfn>:<br>
					any other column

			Then, valid sizing methods are to be assigned to the columns by sizing type, yielding the following sizing-guesses:

			<ol>
				<li>The <dfn>min-content sizing-guess</dfn> is the set of column width assignments where
					each column is assigned its min-content width.

				<li>The <dfn>min-content-percentage sizing-guess</dfn> is the set of column width assignments where:
					<ul>
						<li>each <a>percent-column</a>
							is assigned the larger of:
							<ul>
								<li>its intrinsic percentage width times the assignable width and
								<li>its min-content width.
							</ul>

						<li>all other columns are assigned their min-content width.
					</ul>

				<li>The <dfn>min-content-specified sizing-guess</dfn> is the set of column width assignments where:
					<ul>
						<li>each <a>percent-column</a>
							is assigned the larger of:
							<ul>
								<li>its intrinsic percentage width times the assignable width and
								<li>its min-content width
							</ul>

						<li>any other column that is [=constrainedness|constrained=]
							is assigned its max-content width

						<li>all other columns are assigned their min-content width.
					</ul>

				<li>The <dfn>max-content sizing-guess</dfn> is the set of column width assignments where:
					<ul>
						<li>each <a>percent-column</a>
							is assigned the larger of:
							<ul>
								<li>its intrinsic percentage width times the assignable width and
								<li>its min-content width
							</ul>

						<li>all other columns are assigned their max-content width.
					</ul>
			</ol>

			<div class="note">
				Note that:

				- The <a>assignable table width</a> is always greater than or equal
					to the table width resulting from the min-content sizing-guess.
				- The widths for each column in the four sizing-guesses
					(min-content, min-content-percentage, min-content-specified, and max-content)
					are in nondecreasing order.

			</div>

			If the <a>assignable table width</a> is less than or equal to the <a>max-content sizing-guess</a>,
				the used widths of the columns must be the linear combination (with weights adding to 1)
				of the two consecutive sizing-guesses whose width sums bound the available width.

			Otherwise, the used widths of the columns are the result of starting from the <a>max-content sizing-guess</a>
				and distributing the excess width to the columns of the table
				according to the rules for <a>distributing excess width to columns</a> (for used width).

		<figure>
			<p class="note">
				The following schema describes the algorithm in a different way,
					to make it easier to understand.
			</p>
			<details style="border: 3px solid silver; text-align: left;">
				<summary style="background: silver; padding: 0 7px; outline: 3px solid silver;">Legend</summary>
				<div style="padding: 0 1em;">

					<b>Sizing algorithms: </b>
					Each drawing of the table represents a way of sizing the columns.
					The four cases on the left are the sizing-guesses described above in the spec: 
						<a href="#min-content-sizing-guess">min-content</a>, 
						<a href="#min-content-percentage-sizing-guess">min-content-percentage</a>, 
						<a href="#min-content-specified-sizing-guess">min-content-specified</a>, and 
						<a href="#max-content-sizing-guess">max-content</a>.
					The cases on the right are interpolations required for available sizes that do not match exactly one of the four sizing-guesses.

					<b>Choice of sizing method: </b>
					The sizing method selection always starts at the min-content sizing-guess (top left), 
						and then proceeds by comparing the available width and the width consumed by the method currently in use.
					Green arrows indicate the direction you should follow 
						if you have extra space to distribute after applying the current method.
					Red arrows indicate the direction you should follow 
						if you have distributed too much space by applying the current method and need to backtrack.

					<b>Columns types: </b>
					Each type of column (auto, px, %) has its own color in the schema (yellow, blue, orange).
					In an interpolation: 
						columns that get shrunk down from their size in previous sizing-guess are repainted red, and 
						columns that get expanded from their size in previous sizing-guess are repainted green.

				</div>
			</details>
			<img alt="[see-caption-below]" src="images/CSS-Tables-Column-Width-Assignment.svg" width=768 style="width: 100%">
			<figcaption>Overview of the width distribution algorithm. Not normative.</figcaption>
		</figure>

		<h5 id="width-distribution-in-fixed-mode">Changes to width distribution in fixed mode</h5>

			The following changes to previous algorithm apply <a>in fixed mode</a>:

				- The <a href="#min-content-width-of-a-column">min-content width</a> of percent-columns and auto-columns is considered to be zero

				- Cells ignore their border and padding size if their width is a percentage ('box-sizing' is ignored)

				- If, when percentages are resolved based on the <a>assignable table width</a>,
					the sum of columns widths based on this resolution would exceed the assignable table width,
					they are instead to be resolved relative to their percentage value such that
					the sum of columns width meets the assignable table width exactly.

				- Columns whose size is computed as a sum of a percentage and a pixel length must be sized as if they counted as two columns,
					one with the pixel value, the other with the percentage value. This is different from resolving the percentage away,
					because of how width distribution works for percentage-based columns.

			<wpt>
				fixed-layout-1.html
				fixed-layout-2.html
			</wpt>

		<h5 id="distributing-width-to-columns">Distributing excess width to columns</h5>

		The rules for <dfn>distributing excess width to columns</dfn> can be invoked in two ways:

		<ul>
			<li>for distributing the excess width of a table to its columns
				during the computation of the used widths of those columns (for used width calculation), or

			<li>for distributing the excess max-content or min-content width of a cell spanning more than one column
				to the max-content or min-content widths of the columns it spans (for intrinsic width calculation).
		</ul>

		The rules for these two cases are largely the same, but there are slight differences.

		The remainder of this section uses the term <dfn>distributed width</dfn> to refer to the one of these widths that is being distributed,
		and the <dfn>excess width</dfn> is used to refer to the amount by which the width being distributed
		exceeds the sum of the distributed widths of the columns it is being distributed to.

		<ol>

			<li>If there are [=constrainedness|non-constrained columns=] that have originating cells
					with intrinsic percentage width of 0% and
					with nonzero max-content width
					<i class="hint">(aka the columns allowed to grow by this rule)</i>,
				the [=distributed widths=] of the columns allowed to grow by this rule
					are increased in proportion to max-content width
					so the total increase adds to the [=excess width=].

			<li>Otherwise, if there are [=constrainedness|non-constrained columns=] that have originating cells
					with intrinsic percentage width of 0%
					<i class="hint">(aka the columns allowed to grow by this rule,
					which thanks to the previous rule must have zero max-content width)</i>,
				the [=distributed widths=] of the columns allowed to grow by this rule
					are increased by equal amounts
					so the total increase adds to the [=excess width=].

			<li>Otherwise, if there are [=constrainedness|constrained columns=]
					with intrinsic percentage width of 0% and
					with nonzero max-content width
					<i class="hint">(aka the columns allowed to grow by this rule, which, due to other rules, must have originating cells)</i>,
				the [=distributed widths=] of the columns allowed to grow by this rule
					are increased in proportion to max-content width
					so the total increase adds to the [=excess width=].

			<li>Otherwise, if there are columns
					with intrinsic percentage width greater than 0%
					<i class="hint">(aka the columns allowed to grow by this rule, which, due to other rules, must have originating cells)</i>,
				the [=distributed widths=] of the columns allowed to grow by this rule
					are increased in proportion to intrinsic percentage width
					so the total increase adds to the [=excess width=].

			<li>Otherwise, if there is any such column,
					the [=distributed widths=] of all columns that have originating cells
					are increased by equal amounts
					so the total increase adds to the [=excess width=].

			<li>Otherwise,
					the [=distributed widths=] of all columns
					are increased by equal amounts
					so the total increase adds to the [=excess width=].
		</ol>

		<div class="advisement">
			These rules do not apply when the table is laid out <a>in fixed mode</a>.
			In this case, the simpler rules that follow apply instead:
			<ul><li>If there are any columns with no width specified, the [=excess width=] is distributed in equally to such columns
				<li>otherwise, if there are columns with non-zero length widths from the base assignment, the excess width is distributed proportionally to width among those columns
				<li>otherwise, if there are columns with non-zero percentage widths from the base assignment, the excess width is distributed proportionally to percentage width among those columns
				<li>otherwise, the excess width is distributed equally to the zero-sized columns</ul>
		</div>

		<wpt>
			auto-layout-calc-width-001.html
			fixed-layout-calc-width-001.html
			fixed-layout-excess-width-distribution-001.html
		</wpt>

<!--
██     ██ ████████ ████  ██████   ██     ██ ████████       ████████  ████  ██████  ████████ ████████  ████ ████████  ██     ██ ████████ ████  ███████  ██    ██
██     ██ ██        ██  ██    ██  ██     ██    ██          ██     ██  ██  ██    ██    ██    ██     ██  ██  ██     ██ ██     ██    ██     ██  ██     ██ ███   ██
██     ██ ██        ██  ██        ██     ██    ██          ██     ██  ██  ██          ██    ██     ██  ██  ██     ██ ██     ██    ██     ██  ██     ██ ████  ██
█████████ ██████    ██  ██   ████ █████████    ██          ██     ██  ██   ██████     ██    ████████   ██  ████████  ██     ██    ██     ██  ██     ██ ██ ██ ██
██     ██ ██        ██  ██    ██  ██     ██    ██          ██     ██  ██        ██    ██    ██   ██    ██  ██     ██ ██     ██    ██     ██  ██     ██ ██  ████
██     ██ ██        ██  ██    ██  ██     ██    ██          ██     ██  ██  ██    ██    ██    ██    ██   ██  ██     ██ ██     ██    ██     ██  ██     ██ ██   ███
██     ██ ████████ ████  ██████   ██     ██    ██          ████████  ████  ██████     ██    ██     ██ ████ ████████   ███████     ██    ████  ███████  ██    ██
-->
	<h3 id="height-distribution">Available Height Distribution</h3>

		<wpt>
			table-cell-overflow-explicit-height-001.html
			table-cell-overflow-explicit-height-002.html
		</wpt>

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="computing-the-table-height">Computing the table height</h4>

			<p class="note">
				<a class="hint" href="https://jsfiddle.net/bsgt4wbx/">?Testcase</a>
				<a class="hint" href="https://jsfiddle.net/bsgt4wbx/1/">?Testcase</a>
				<a class="hint" href="https://jsfiddle.net/bsgt4wbx/3/">?Testcase</a>

			The <strong>height of a table</strong> is the sum of the row heights plus any cell spacing or borders.
			If the table has a 'height' property with a value other than auto, it is treated as a minimum height for the table grid,
				and will eventually be distributed to the height of the rows if their collective <a href="#">minimum height</a> ends up smaller than this number.
				If their collective size ends up being greater than the specified 'height', the specified 'height' will have no effect.

			The <strong>minimum height of a row</strong> is the maximum of:
			<ul><li>the computed 'height' (if definite, percentages being considered 0px) of its corresponding table-row (if any)
				<li>the computed 'height' of each cell spanning the current row exclusively (if definite, percentages being treated as 0px), and
				<li>the minimum height (<a>ROWMIN</a>) required by the cells spanning the row.</ul>

			<dfn id="ROWMIN">ROWMIN</dfn> is defined as 
				the sum of the <a href="#row-layout">minimum height of the rows</a>
				after a first row layout pass.

			To compute the <strong>height of a table</strong>, it is therefore necessary to 
				perform a first-pass layout on all its rows,
				compute the sum of all minimum row heights plus spacings/borders,
				and return the greater of either that value or the table-root specified 'height' (min-height).

			Once the table height has been determined, 
				rows will usually get a <a href="#row-relayout">second layout pass</a> (where their cells' heights are no longer considered auto),
				then <a href="#height-distribution-algorithm">height distribution</a> will happen to adjust their heights to collectively meet the table height,
				then table-cell descendants might get a <a href="#table-cell-content-relayout">second layout</a> (where their percentage heights are resolved).

			<wpt>
				absolute-crash.html
				absolute-tables-004.html
				absolute-tables-005.html
				absolute-tables-007.html
				empty-table-height.html
				max-height-table.html
				min-height-table.html
				min-height-table-2.html
				min-max-size-table-content-box.html
				paint/table-border-paint-caption-change.html
				percentages-grandchildren-quirks-mode-001.html
				percentages-grandchildren-quirks-mode-002.html
				table-as-item-cell-percentage-001.html
				table-as-item-cell-percentage-002.html
				table-as-item-cell-percentage-003.html
				table-as-item-cell-percentage-004.html
				visibility-collapse-non-rowcol-001.html
				visibility-collapse-row-001.html
				visibility-collapse-row-002-dynamic.html
				visibility-collapse-row-003-dynamic.html
				visibility-collapse-row-004.html
				visibility-collapse-row-005.html
				visibility-collapse-row-group-001.html
				visibility-collapse-row-group-002.html
				visibility-collapse-rowcol-001.html
				visibility-collapse-rowcol-002.html
				visibility-collapse-rowspan-001.html
				visibility-collapse-rowspan-003-border-separate.html
				visibility-collapse-rowspan-003.html
				visibility-hidden-row-001.html
				visibility-hidden-row-002.html
			</wpt>

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="row-layout">Row layout (first pass)</h4>

			The <strong>minimum height of a row</strong> (without spanning-related height distribution)
				is defined as the height of
				a hypothetical linebox containing the cells originating in the row
				and where cells spanning multiple rows are considered having a height of 0px
				(but their correct baseline).
			In this hypothetical linebox, cell heights are considered auto,
				their width (including borders and paddings) is forced to the widths and inner spacings of the columns they span,
				but their other properties are conserved.

			For the purpose of calculating this height,
				descendants of table cells whose height depends on percentages of their parent cell's height
				<a href="#appropriateness-of-child-percentage-resolution">(see section below)</a>
				are considered to have an auto height
					if they have 'overflow' set to ''overflow/visible'', ''overflow/clip'', or ''overflow/hidden''
					or if they are replaced elements,
				and a 0px height if they have not.
			<a href="https://jsfiddle.net/0e12ve9b/">Testcase</a>
			<a href="https://jsfiddle.net/0e12ve9b/3/">!!Testcase</a>

			<div class="note">
				For table-cell descendants whose percentage height was ignored as a result of the above,
					a second layout pass of the table-cell content will happen once height distribution has concluded
					to attempt to properly take this sizing into account
					<a href="#resolving-percentages-heights-in-table-cell-content">(see section below)</a>
			</div>

			The <dfn id="table-cell-baseline">baseline of a cell</dfn> is defined as
				the baseline of the first <a>in-flow</a> line box in the cell, or
				the first in-flow table-row in the cell,
				whichever comes first.
			If there is no such line box or table-row,
				the baseline is the bottom of content edge of the cell box.

			<wpt>
				baseline-vertical.html
				baseline-empty-cell-001.html
				table-cell-baseline-static-position.html
				table-cell-overflow-auto.html
			</wpt>

			<div class="example">

				Here is how this works out in practice:

				<xmp>
					td { vertical-align: baseline; outline: 3px solid silver; }
					img { float: left; clear: left; width: 32px; height: 32px; }
					img[title] { float: none; }

					<table><tr>
						<td>Baseline</td>
						<td>Baseline<table><tr><td>After</td></tr></table></td>
						<td><table><tr><td>Baseline</td></tr></table>After</td>
						<td><table align=right><tr><td>Before</td></tr></table><p>Baseline</p></td>
						<td><img src="http://w3.org/favicon.ico"><p>Baseline</p></td>
						<td><img src="http://w3.org/favicon.ico" title="Baseline"/><br/><img src="http://w3.org/favicon.ico" title="After"></td>
						<td><img src="http://w3.org/favicon.ico"><img src="http://w3.org/favicon.ico"><!--Baseline--></td>
					</tr></table>
				</xmp>

				<figure>
					<img alt="[see-caption-below]" src="images/td-baseline-example-rendering.png" width="585" height="185">
					<figcaption>Rendering of <a href="https://jsfiddle.net/x8sh0f60/3/">this example</a> in a compliant browser</figcaption>
				</figure>
			</div>

			<p class="advisement">
				For the purposes of finding a baseline,
					<a>in-flow</a> boxes with a scrolling mechanisms (see the 'overflow' property)
					must be considered as if scrolled to their origin position.

			<p class="note">
				The baseline of a cell may end up below its bottom border,
					see the example below.

			<div class="example">

				The cell in this example has a baseline below its bottom border:

				<xmp>
					div { height: 0; overflow: hidden; }

					<table>
					<tr>
					<td>
					<div> Test </div>
					</td>
					</tr>
					</table>
				</xmp>
			</div>

			The 'vertical-align' property of each table cell determines its alignment within the row.
			Each cell's content has a baseline, a top, a middle, and a bottom, as does the row itself.

			In the context of table cells, values for 'vertical-align' have the following meanings:

			<table class="def">
				<tr>
					<th style="vertical-align:top">baseline</th>
					<td>The baseline of the cell is aligned with the baseline of the other cells of the first row it spans (see the definition of baselines of <a href="#table-cell-baseline">cells</a> and <a href="#table-row-baseline">rows</a>).</td>
				<tr>
					<th style="vertical-align:top">top</th>
					<td>The top of the cell box is aligned with the top of the first row it spans.</td>
				<tr>
					<th style="vertical-align:top">bottom</th>
					<td>The bottom of the cell box is aligned with the bottom of the last row it spans.</td>
				<tr>
					<th style="vertical-align:top">middle</th>
					<td>The center of the cell is aligned with the center of the rows it spans.</td>
				<tr>
					<th style="vertical-align:top" title="sub, super, text-top, text-bottom, &lt;length>, &lt;percentage>">...</th>
					<td>Other values do not apply to cells; the cell is aligned at the baseline instead.</td>
			</table>

			The maximum distance between
				the top of the cell box
				and the baseline over all cells that have 'vertical-align: baseline'
				is used to set the <dfn id="table-row-baseline">baseline of the row</dfn>.
			If a row doesn't have any cell that has 'vertical-align: baseline',
				the baseline of that row is the bottom content edge of the lowest cell in the row.

			The <dfn id="table-root-baseline" export>baseline of a table-root</dfn> is the baseline of its first row, if any.
				Otherwise, it is the bottom content edge of the table-root.

			<a class="hint" href="https://wptest.center/#/mz09g6">Testcase</a>
			<a class="hint" href="https://wptest.center/#/x80356">!!Testcase</a>

			<div class="advisement">

				To avoid ambiguous situations,
				the alignment of cells proceeds in the following order:

				<ul><li>First the cells that are aligned on their baseline are positioned.
						This will establish the baseline of the row.
					<li>Next the cells with 'vertical-align: top' are positioned.
						The row now has a top, possibly a baseline, and a provisional height,
							which is the distance from the top to the lowest bottom of the cells positioned so far.
					<li>If any of the remaining cells, those aligned at the bottom or the middle,
							have a height that is larger than the current height of the row,
							the height of the row will be increased to the maximum of those cells,
							by lowering the bottom.
					<li>Finally, assign their position to the remaining cells.
				</ul>
			</div>

			<div class="example">

				Example showing how the previous algorithm creates the various alignment lines of a row.

				<figure>
					<a href="http://www.w3.org/TR/CSS2/images/longdesc/cell-align-desc.html"><img alt="[see-caption-below]" src="images/cell-align-explainer.png" width="375" height="241"></a>
					<figcaption>
						Diagram showing the effect of various values of 'vertical-align' on table cells.
						Cell boxes 1 and 2 are aligned at their baselines. Cell box 2 has the largest height above the baseline, so that determines the baseline of the row.
					</figcaption>
				</figure>
			</div>

			Since during row layout the specified heights of cells in the row were ignored
				and cells that were spanning more than one row have not been sized correctly,
				their height will need to be eventually distributed to the set of rows they spanned.
			This is done by running the same algorithm as the <a href="#computing-column-measures">column measurement</a>,
				with the span=1 value being initialized (for min-content) with the largest of
				the resulting height of the previous row layout,
				the height specified on the corresponding table-row (if any),
				and the largest height specified on cells that span this row only
				(the algorithm starts by considering cells of span 2 on top of that assignment).

			<div class="issue">
				EDITORIAL. Import the relevant section of [[#computing-column-measures]] here.
			</div>

			Rows that see their size increase as a result of applying these steps
				adjust by lowering their bottom.

			<div class="advisement">

				The cells whose position depended on the bottom of any updated row
					must be positioned correctly again in their respective rows.

				At this point, cell boxes that are smaller than the collective height of the rows they span
					receive extra top and/or bottom padding
					such that their content does not move vertically
					but their top/bottom edges meet the ones of the first/last row they span.

			</div>

			<div class="note">
				Please note that heights being defined on row groups are being ignored by this algorithm
			</div>

			<wpt>
				dynamic-table-cell-height.html
				percent-height-overflow-auto-in-restricted-block-size-cell.html
				height-distribution/percentage-sizing-of-table-cell-007.html
				height-distribution/percentage-sizing-of-table-cell-children-003.html
				height-distribution/percentage-sizing-of-table-cell-children-004.html
				height-distribution/percentage-sizing-of-table-cell-children-005.html
				height-distribution/percentage-sizing-of-table-cell-children-006.html
			</wpt>

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="row-relayout">Row layout (second pass)</h4>

			Once the table height has been determined, a second row layout pass will be performed, if necessary,
				to assign the correct minimum height to table rows, by taking percentages used in rows/cells specified 'height' into account.
				Other than that, all instructions for the first-pass row layout apply <a href="#row-layout">(see above)</a>.
							
			<div class="note">
				Please note that this second-pass minimum height therefore still treats percentage heights of table-cell descendants as advised for the first pass
					<a href="#row-layout">(see above)</a>. 
				For this reason, it is not required to relayout the content of table-cells to compute the new row minimum height.
				If necessary, table-cell content will undergo a relayout later,
					after table height distribution has concluded
					<a href="#table-cell-content-relayout">(see below)</a>.
			</div>

			Then, if the sum of the new heights of the table rows after this second pass
			is different from what is needed to fill the table height previously determined,
				the height distribution algorithm defined <a href="#height-distribution-algorithm">below</a> is applied
				(either to shrink rows by sizing them intermediately between their first-pass minimum height and their second-pass one,
				or to increase the heights of all rows beyond their second-pass minimum height to fill the available space;
				in neither case, this will have an impact on the baseline of the rows).

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="height-distribution-principles">Core distribution principles</h4>

			<div class="issue">
				EDITORIAL. TODO. For current proposal, skip to [[#height-distribution-algorithm]].
			</div>

			<details class="note">
				<summary tabindex="0" style="font-weight: bold; font-size: 120%;">
					Investigations on height distribution
				</summary>
				<aside>

					Initial analysis shows that there are indeed similarities between width and height distribution.
					There are also differences which I described here below:

					In many case, all browsers apply a distribution algorithm that favors percentages over pixels over auto.
					<span class="hint"><a href="https://jsfiddle.net/xg2ss965/2/">Case 6</a></span>.

					A difference with the width distribution algorithm is that
						if the sum of all rows' heights is higher than 100%,
						then all browsers enter a completely different mode.
						<a href="https://jsfiddle.net/6ec0hxgx/">Case 7</a>.
						<span class="hint">
							NOTE: The sum counts as well percentage heights and pixels heights,
							since at this point you can safely resolve percentages.
						</span>
						<br/>

					In this case, pixel-tracks are sized properly first.
					Then, percentage tracks get the remaining space proportionally to their height percentage up to their height percentage.
					Finally, auto tracks get to fill the remaining space, if there is any auto track.
					If there is none, percentage tracks continue growing above their height percentage until all the space is filled.
					<a href="https://jsfiddle.net/xg2ss965/1/">Case 9</a>.

					The height distribution algorithm also caps the sum of percentage heights to 100% in all browsers but Edge.
					That means that some rows get an arbitrary 0% height.
					<a href="https://jsfiddle.net/xg2ss965/">Case 8</a>.

					In Edge and Firefox, empty tracks do not get an increased size by this distribution if there are filled auto tracks.
					In Chrome, empty tracks count as distributable tracks as well even if there are other auto tracks.

					<ul class="inline hint">
						<li>Case 1: <a href="https://jsfiddle.net/Lh9shm8p/">height</a> vs <a href="https://jsfiddle.net/wza8huh7/">width</a>
						<li>Case 2: <a href="https://jsfiddle.net/Lh9shm8p/1/">height</a> vs <a href="https://jsfiddle.net/wza8huh7/1/">width</a>
						<li>Case 3: <a href="https://jsfiddle.net/Lh9shm8p/2/">height</a> vs <a href="https://jsfiddle.net/wza8huh7/2/">width</a>
						<li>Case 4: <a href="https://jsfiddle.net/Lh9shm8p/3/">height</a> vs <a href="https://jsfiddle.net/wza8huh7/3/">width</a>
						<li>Case 5: <a href="https://jsfiddle.net/Lh9shm8p/4/">height</a> vs <a href="https://jsfiddle.net/wza8huh7/4/">width</a>
					</ul>

					<style>
						ul.inline { display: inline; margin: 0; padding: 0; }
						ul.inline > li { display: inline; margin: 0; padding: 0; }
						ul.inline > li::after { content:", "; display: inline; }
						ul.inline > li:last-of-type::after { content:""; display: none; }
					</style>

					<p id="min-content-and-percentages">
						Interesting test cases about min-content and content using percentage sizes:
						<ul class="compact">
							<li><a href="https://jsfiddle.net/gzapbyeg/1/">Case 10</a>.
							<li><a href="https://jsfiddle.net/gzapbyeg/2/">Case 11</a>.
						</ul>
						<br/>
						Chrome and Edge apply percentages on the final layout.
						All browsers work around them during the first pass
							by considering them 0% (Chrome) or
							by ignoring the declaration (Edge, Firefox).
						The difference of choice is visible in
						<a href="https://jsfiddle.net/vmfrLzke/1/">Case 12</a>.
						<a href="http://codepen.io/FremyCompany/pen/obdYjv?editors=1100">Case 13</a>.

				</aside>
			</details>

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="height-distribution-algorithm">Distribution algorithm</h4>

			The first step is to attribute to each row its base size and its reference size.

			Its <strong>base size</strong> is the size it would have got
				if the table didn’t have a specified height
				(the one it was assigned when ROWMIN was evaluated).

			Its <strong>reference size</strong> is the largest of
			<ul><li>its initial base height and
				<li>its new base height
					(the one evaluated during the second layout pass,
					where percentages used in rowgroups/rows/cells' specified heights
					were resolved according to the table height,
					instead of being ignored as 0px).</ul>

			The second step is to compute the final height of each row based on those sizes.

			If the table height is equal or smaller than sum of reference sizes,
				the final height assigned to each row will be
				the weighted mean of the base and the reference size
				that yields the correct total height.

			Else, if the table owns any “auto-height” row
				(a row whose size is only determined by its content size and none of the specified heights),
				each non-auto-height row receives its reference height
				and auto-height rows receive their reference size plus some increment
				which is equal to the height missing to amount to the specified table height
				divided by the amount of such rows.

			Else, all rows receive their reference size plus some increment
				which is equal to the height missing to amount to the specified table height
				divided by the amount of rows.

			<div class="advisement">

				The cells whose position depended on the bottom of any updated row
					must be positioned correctly again in their respective rows.

				At this point, cell boxes that are smaller than the collective height of the rows they span
					receive extra top and/or bottom padding
					such that their content does not move vertically
					but their top/bottom edges meet the ones of the first/last row they span.

			</div>

			<wpt>
				height-distribution/extra-height-given-to-all-row-groups-001.html
				height-distribution/extra-height-given-to-all-row-groups-002.html
				height-distribution/extra-height-given-to-all-row-groups-003.html
				height-distribution/extra-height-given-to-all-row-groups-004.html
				height-distribution/extra-height-given-to-all-row-groups-005.html
				height-distribution/td-different-subpixel-padding-in-same-row-vertical-rl.html
				height-distribution/td-different-subpixel-padding-in-same-row.html
			</wpt>

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="table-cell-content-relayout">Table-cell content layout (second pass)</h4>

			Once table-height distribution has concluded, and the sum of row heights plus spacing/border is equal to the table height,
				the content of table-cells which contained descendants whose percentage heights were ignored
				or treated as 0px by the first-pass row layout rules <a href="#row-layout">(see above)</a>
				must undergo a second layout pass, as defined below.

			<div class="note">
			Note that this means UAs are either required to keep track of the usage of percentages
				in the properties of any direct child of the table-cell including (but not limited to)
				the 'height' and 'min-height' properties for horizontal flows and 
				the 'width' and 'min-width' properties for vertical flows, 
				or else required to perform this second layout pass on table-cell content in all cases.
			</div>

			<dfn id="resolving-percentages-heights-in-table-cell-content">
			Resolve percentage heights in table-cell content:</dfn>
			Once the final size of the table and the rows has been determined,
				after height distribution has concluded,
				the content of the table-cells must also go through a second layout pass,
				where, if <a href="#appropriateness-of-child-percentage-resolution">appropriate</a>, percentage-based heights are this time resolved
				against their parent cell used height.

			<dfn id="appropriateness-of-child-percentage-resolution">
			It is appropriate to resolve percentage heights on direct children of a table-cell</dfn>
				if the cell is considered to have its height specified explicitly
				or the child is absolutely positioned, see <a href="http://www.w3.org/TR/CSS2/visudet.html#the-height-property">CSS 2</a>.

			For compat reasons, it is further clarified that
				a cell is considered to have its height specified explicitly
				if the computed height of the cell is a length, or 
				if the computed height of its table-root ancestor is a length or percentage,
				regardless of whether that percentage does <a>behave as auto</a> or not.

			<div class="example">
				To clarify the preceding statements, here is a table of the resulting "A" div height based on the value being used:
				<xmp>
					<section style="height: var(--wrapper-height)">
						<table style="height: var(--table-height)">
							<tr>
								<td style="height: var(--table-cell-height)">

									<div style="height:100%; background:yellow">A</div>

								</td>
								<td style="height: var(--other-table-cell-height)">

									B<br>C

								</td>
							</tr>
						</table>
					</section>
				</xmp>

				<style>
					.border-1 td, .border-1 th { border: 1px solid black; }
					.rules-all { border-collapse: collapse; }
				</style>
				<table class="border-1 rules-all" style="margin: auto; font-family: 'Consolas', monospace">
					<thead>
						<tr>
							<th>--table-cell-height&nbsp;&nbsp;</th>
							<th>--table-height&nbsp;&nbsp;</th>
							<th>result&nbsp;&nbsp;</th>
						</tr>
					</thead>

					<tbody>
						<tr>
							<td>&lt;length&gt;</td>
							<td><i style="opacity:0.5">&lt;any&gt;</i></td>
							<td><img src="images/percentage-heights-hundred-percent.png" width="23" height="29" style="vertical-align: middle" alt="100%" title="Percentage honored during second layout pass"></td>
						</tr>
						<tr>
							<td><i style="opacity:0.5">&lt;any&gt;</i></td>
							<td>&lt;length&gt;</td>
							<td><img src="images/percentage-heights-hundred-percent.png" width="23" height="29" style="vertical-align: middle" alt="100%" title="Percentage honored during second layout pass"></td>
						</tr>
						<tr>
							<td><i style="opacity:0.5">&lt;any&gt;</i></td>
							<td>&lt;percentage&gt;</td>
							<td><img src="images/percentage-heights-hundred-percent.png" width="23" height="29" style="vertical-align: middle" alt="100%" title="Percentage honored during second layout pass"></td>
						</tr>
						<tr>
							<td>auto</td>
							<td>auto</td>
							<td><img src="images/percentage-heights-auto.png" width="23" height="29" style="vertical-align: middle" alt="auto" title="Percentage ignored; no second layout pass"></td>
						</tr>
						<tr>
							<td>&lt;percentage&gt;</td>
							<td>auto</td>
							<td><img src="images/percentage-heights-auto.png" width="23" height="29" style="vertical-align: middle" alt="auto" title="Percentage ignored; no second layout pass"></td>
						</tr>
					</tbody>
				</table>

				Note that neither <code>--other-table-cell-height</code> nor <code>--wrapper-height</code> do influence the algorithm's outcome.

				A previous version of this specification incorrectly stated that <code>--wrapper-height</code> was taken into account when the table had a percentage height,
				but compat issues appeared when an implementation landed, and the behavior was then special-cased.

			</div>

			<div class="note">
				It is possible that this second layout pass (where height percentages are being resolved)
					will make some cell contents overflow their parent cell,
					for instance if the sum of all percentages used is superior to 100%.
				This is by design.
			</div>

			<wpt>
				percent-height-replaced-in-percent-cell-002.html
				percent-height-replaced-in-percent-cell-003.html
				percent-height-replaced-in-percent-cell-004.html
				percent-height-table-cell-child.html
			</wpt>

	<!--——————————————————————————————————————————————————————————————————————————-->
	<h3 id="bounding-box-assignment">Positioning of cells, captions and other internal table boxes</h3>

		<wpt>
			border-spacing-included-in-sizes-001.html
			bounding-box-computation-1.html
			bounding-box-computation-2.html
			bounding-box-computation-3.html
			table-cell-overflow-auto-scrolled.html
		</wpt>

		ISSUE(478): We need a resolution on what visibility:collapse does.

		Once the width of each column and the height of each row of the table grid has been determined,
			the final step of algorithm is to assign to each table-internal box its final position.

		The width/height/left/top calculated below define the dimensions of the CSS Layout Box, 
			which means that they are accessible via the <a href="https://drafts.csswg.org/cssom-view/#extensions-to-the-htmlelement-interface">offset* properties</a> defined in CSSOM-VIEW,
			(currently limited to css boxes for which you can obtain a corresponding HTMLElement reference).

		The <a>table-wrapper</a> box is then sized such that
			it contains the margin box of all <a>table-non-root</a> boxes
			as well as the <a>table-root</a> border-box.

		<div class="note">
			The position defined here is the position of the children
			inside the space reserved for the table-wrapper, which excludes only its margins.
			This is because the captions of the table are located outside the border-box area of the table-root.
		</div>

		The <b>position of any table-caption having "top" as 'caption-side'</b> within the table is defined as the rectangle whose:

		<ul class="compact">
			<li>width/height is:
				<ul><li>the width/height assigned to the caption during layout</ul>
			<li>top location is the sum of:
				<ul><li>the height reserved for previous top captions (including margins), if any
					<li>any necessary extra top margin remaining after collapsing margins with the previous caption, if any.</ul>
			<li>left location is the sum of:
				<ul><li>the margin left of the caption
					<li>half of (the table width minus the width of caption and its total horizontal margin).</ul>
		</ul>

		The <b>position of any table-cell, table-track, or table-track-group box</b> within the table is defined as the rectangle whose:

		<ul class="compact">
			<li>width/height is the sum of:
				<ul><li>the widths/heights of all <a href="#span">spanned</a> <a href="#visible-track">visible</a> columns/rows
					<li>the horizontal/vertical 'border-spacing' times the amount of <a href="#span">spanned</a> <a href="#visible-track">visible</a> columns/rows minus one
				</ul>
			<li>left/top location is the sum of:
				<ul><li>for top: the height reserved for top captions (including margins), if any
					<li>the padding-left/padding-top and border-left-width/border-top-width of the table
					<li>the widths/heights of all previous <a href="#visible-track">visible</a> columns/rows
					<li>the horizontal/vertical 'border-spacing' times the amount of previous <a href="#visible-track">visible</a> columns/rows plus one
				</ul>
		</ul>

		<div class="note">
			<b>Reminder:</b>
			For table-track and table-track-group boxes,
				all tracks of the opposite direction to the grouping are considered spanned.
			For instance, a table-header-group is considered to span all the columns,
				and a table-column-group is considered to span all the rows.
		</div>

		<div class="note">
			The above formula takes into account 'border-spacing', and it might not be directly obvious what the effect of these mean, so here are a couple of properties of those formula:
			<ul>
				<li> the border-spacing before the first track or after the last track in a direction is not included in any track's or track-group's breadth.
				<li> the border-spacing between tracks is not included in any track's breadth, but is included in the breadth of track-groups spanning both tracks.
			</ul>
		</div>

		The <b>position of any table-caption having "bottom" as 'caption-side'</b> within the table is defined as the rectangle whose:

		<ul class="compact">
			<li>width/height is:
				<ul><li>the width/height assigned to the caption during layout</ul>
			<li>top location is the sum of:
				<ul><li>the height reserved for top captions (including margins), if any
					<li>padding-top and border-top-width of the table
					<li>the height of all <a href="#visible-track">visible</a> rows
					<li>padding-bottom and border-bottom-width of the table
					<li>the height reserved for previous bottom captions (including margins), if any
					<li>any necessary extra top margin remaining after collapsing margins with the previous bottom caption, if any.</ul>
			<li>left location is the sum of:
				<ul><li>the margin left of the caption
					<li>half of (the table width minus the width of caption and its total horizontal margin).</ul>
		</ul>

		<div class="advisement">
			<strong>Cell overflow: </strong>
			If the table is laid out <a>in fixed mode</a>,
			if the content of some cell has grown more than the cell during its second layout pass
			or if some tracks spanned by visible cells are deemed not <a href="#visible-track">visible</a>,
				the content of some cells may exceed the available space,
				and cause an overflow.
			Such overflow should behave exactly
				like if the cell was an absolutely positioned display:block box
				with the appropriate alignment in place to keep its content in place relative to its inline-start block-start corner (usually top left).
			<a class="hint" href="https://jsfiddle.net/24bz3Lp1/">!Testcase</a>
			<a class="hint" href="https://jsfiddle.net/24bz3Lp1/1/">!Testcase</a>
			<a class="hint" href="https://jsfiddle.net/24bz3Lp1/3/">Testcase</a>
		</div>

		<div class="advisement">
			<strong>Visible tracks: </strong>
			For the purpose of this algorithm, a column or row
			is considered a <dfn id="visible-track">visible track</dfn>
			if neither its corresponding table-track nor its table-track-group parent (if any) have 'visibility' set to <code>collapse</code>.</div>

		<div class="example">
			<figure>
				<img alt="A table with a caption above it, showing how the caption margins are totally nested inside the table margins, but are outside the border-box of the table nonetheless." src="images/table_container.png" width="533" height="483">
				<figcaption>Diagram of a table with a caption above it.</figcaption>
			</figure>
		</div>

		<div class="note">
			<a id="spanning-ghost-rows" class="hint" href="https://jsfiddle.net/3pox7b4f/">~Testcase</a>
			<a class="hint" href="https://jsfiddle.net/3pox7b4f/1/">!!Testcase</a>
			<a class="hint" href="https://jsfiddle.net/3pox7b4f/3/">!!Testcase</a>
			<a class="hint" href="https://jsfiddle.net/3pox7b4f/4/">!!Testcase</a>
			<a class="hint" href="https://jsfiddle.net/3pox7b4f/5/">Testcase</a>
		</div>

<!--
   ███    ████████   ██████  ████████   ███████   ██████
  ██ ██   ██     ██ ██    ██ ██     ██ ██     ██ ██    ██
 ██   ██  ██     ██ ██       ██     ██ ██     ██ ██
██     ██ ████████   ██████  ████████  ██     ██  ██████
█████████ ██     ██       ██ ██        ██     ██       ██
██     ██ ██     ██ ██    ██ ██        ██     ██ ██    ██
██     ██ ████████   ██████  ██         ███████   ██████
-->

<h2 id="abspos">
Absolute Positioning</h2>

<h3 id="abspos-boxes-in-table-root">
With a table-root as containing block</h3>

	If an absolutely positioned element's <a>containing block</a>
	is generated by a <a>table-wrapper</a> box,
	the containing block corresponds to the area around which the table margins are applied,
	including the area where the table border is drawn and the margin area of any table-caption.
	The offset properties ('top'/'right'/'bottom'/'left')
	then indicate offsets inwards from the corresponding edges
	of this <a>containing block</a>, as normal.

	Absolute positioning occurs after layout of the <a>table</a> and its <a>in-flow</a> contents,
	and does not contribute to the sizing of any table grid tracks
	or affect the size/configuration of the table grid in any way.

	<div class='example'>

		<figure style="margin: 0">
			<figcaption style="text-align: left; font-style: normal;">
				The figure below shows how a box absolutely-positioned relative to a table should be rendered. <br/><br>
				The <b>yellow</b> area is the table content edge, yellow arrows the table margins. <br/>
				The <b>green</b> area is the table caption, green arrows the caption margins. <br/>
				The <b>blue</b> area is the table background area, and the darker blue area where the table border area. <br/>
				The <b>black</b> area is the descendant positioned relative to the table, the arrows represent the top/left/bottom/right displacements.
			</figcaption>
			<img alt="[see-caption-above]" src="images/css-tables-abspos.svg" width="702" height="402">
		</figure>

	</div>

	<wpt>
		absolute-tables-012.html
		absolute-tables-013.html
		absolute-tables-014.html
		absolute-tables-015.html
		absolute-tables-016.html
	</wpt>

<h3 id="abspos-boxes-in-table-internal">
With a table-internal as containing block</h3>

	If an absolutely positioned element's <a>containing block</a>
	is generated by a <a>table-internal</a>,
	the containing block corresponds to the area starting at the top left corner of the <a href="#bounding-box-assignment">the area that would be assigned to the box during layout</a>
	but whose size is computed to be  the one of <a href="#bounding-box-assignment">the area that would be assigned to the box during layout</a> 
		if all tracks were considered visible (irrespective of 'visibility' being set co collapse on some boxes),
	not including borders and paddings as appropriate.

	<div class="note">
	This is done so that hiding column does not trigger a layout in the absolutely-positioned boxes, and the content being clipped doesn't seem to be moving.
	<a class="hint" href="https://wptest.center/#/uxin57">!!Testcase</a>
	<a class="hint" href="https://wptest.center/#/vcmy48">!!Testcase</a>
	</div>

	The offset properties ('top'/'right'/'bottom'/'left')
	then indicate offsets inwards from the corresponding edges
	of this <a>containing block</a>, as normal.

	ISSUE(858): This only works in Firefox. It would make it easier to implement position:sticky in the future, though.
	<a href="https://bugs.chromium.org/p/chromium/issues/detail?id=417223">[Chrome bug]</a>
	<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1289682">[Interop risk: Firefox bug]</a>

	<wpt>
		abspos-container-change-dynamic-001.html
		internal-containing-block-001.html
	</wpt>

<h3 id="static-position">
With a table-internal box as non-containing block parent</h3>

	The only influence of non-containing block parent of an absolutely-positioned box is to define its static position,
	in case both top+bottom and/or left+right end up being auto.

	For table-cells, the absolutely-positioned content is positioned follows the rules for block layout as usual.

	Due to <a href="#fixup">table fixup</a>,
	it is not possible to create an absolutely-positioned box 
	that is the child of a table-internal box that is not a table-cell 
	(see note about float and position for more details).

<!--
████████  ████████ ██    ██ ████████  ████████ ████████  ████ ██    ██  ██████
██     ██ ██       ███   ██ ██     ██ ██       ██     ██  ██  ███   ██ ██    ██
██     ██ ██       ████  ██ ██     ██ ██       ██     ██  ██  ████  ██ ██
████████  ██████   ██ ██ ██ ██     ██ ██████   ████████   ██  ██ ██ ██ ██   ████
██   ██   ██       ██  ████ ██     ██ ██       ██   ██    ██  ██  ████ ██    ██
██    ██  ██       ██   ███ ██     ██ ██       ██    ██   ██  ██   ███ ██    ██
██     ██ ████████ ██    ██ ████████  ████████ ██     ██ ████ ██    ██  ██████
-->
<h2 id="rendering">Rendering</h2>

	<wpt>
		row-group-margin-border-padding.html
		row-margin-border-padding.html
	</wpt>

	<!--——————————————————————————————————————————————————————————————————————————-->
	<h3 id="paint-order">Paint order of cells</h3>

	Table cells are painted in a table-root in DOM order as usual,
		independently of where cells end up actually being drawn.

	<!--——————————————————————————————————————————————————————————————————————————-->
	<h3 id="empty-cell-rendering">Empty cell rendering (separated-borders mode)</h3>

		<pre class="propdef">
			Name: empty-cells
			Value: show | hide
			Initial: show
			Applies to: <a>table-cell</a> boxes
			Inherited: yes
			Computed value: specified keyword
			Animation type: discrete
		</pre>

		<wpt>
			parsing/empty-cells-computed.html
			parsing/empty-cells-invalid.html
			parsing/empty-cells-valid.html
		</wpt>

		<a>In collapsed-borders mode</a>,
			this property has no effect.

		<a>In separated-borders mode</a>,
			when this property has the value <code>hide</code>,
			no borders or backgrounds are drawn around/behind <a>empty cells</a>.

		An <dfn id="empty-cell">empty cell</dfn> is a table-cell containing neither:
		<ul><li>floating content, nor
			<li>in-flow content (other than white space that has been collapsed away by the 'white-space' property handling).</ul>

		<!--REMOVED BUT KEPT IN SOURCE JUST IN CASE<p>
			Furthermore, if all the cells in a row have a value of <code>hide</code> and have no visible content,
				then the row has zero height and the vertical border-spacing applies to one side of the row only.-->

		ISSUE(605): Can we simplify empty-cells:hide?

		<div class="example">

			For example, take the following markup and css:

			<xmp class="lang-markup">
				<table>
					<td><span></span></td>
					<td></td>
					<td><span></span></td>
				</table>
			</xmp>
			<xmp class="lang-css">
				table {
				  width: 500px; height: 300px;
				  empty-cells: hide;
				}

				table { background: black; border: 10px solid black; }
				td { background: white; }

				table { border-spacing: 0px; }
				td { padding: 0; }
			</xmp>

			The correct rendering of this code snippet is depicted here:

			<figure>
				<img alt="[see-caption-below]" src="images/empty-cells-example.gif" width=500 height=300>
				<figcaption>Rendering of three columns whose middle one is hidden by empty-cells:hide</figcaption>
			</figure>
		</div>

	<!--——————————————————————————————————————————————————————————————————————————-->
	<h3 id="drawing-backgrounds-and-borders">Drawing backgrounds and borders</h3>

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="drawing-table-backgrounds-and-borders">Drawing table backgrounds and borders</h4>

			Unlike other boxes types, table and inline-table boxes
				do not paint their background and borders around their entire client rect.
			Indeed, the table captions are to be visually positioned between the table margins and its borders,
				which means the drawing areas of various effects applied to the table-root need to be modified.

			<b>Painting areas:</b>

			<ul>
				<li>Backgrounds, borders and outlines painted relative to the content-box of a table-root are painted relative to the rectangular area occupied by the table grid and its border spacings.
				<li>Backgrounds, borders and outlines painted relative to the padding-box of a table-root are painted relative to the rectangular area occupied by the table grid and its border spacings, extended on each side by the table-root padding.
				<li>Backgrounds, borders and outlines painted relative to the border-box of a table-root are painted relative to the rectangular area occupied by the table grid and its border spacings, extended on each side by the table-root padding and border-width.
			</ul>

			<div class="note">
				This does not affect other uses of these concepts, like <a href="#abspos">absolute positioning</a>.
			</div>

			<a class="hint" href="https://wptest.center/#/6xd2b3">!Testcase</a>

			<wpt>
				out-of-order-elements-collapsed-border.html
			</wpt>

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h5 id="drawing-collapsed-borders-1">Changes in collapsed-borders mode</h5>

			When a table is laid out <a>in collapsed-borders mode</a>,
				the rendering of its borders on and those of its table-cells is modified.
			The following rules describe in which way.

			<p class="note">
				The rules for background and borders painting defined in [[#drawing-backgrounds-and-borders]]
					still apply if they are not overridden.

			Borders of a non-<a href="#empty-table">empty</a> <a>table-root</a> are not painted <a>in collapsed-borders mode</a>,
				except if the 'border-image' property is set.

			In this latter case, the border is drawn as if the table border was twice as big as its used value specify,
				and as if that excess was rendered inside the padding area of the <a>table-root</a>.

			<p class="note">
				Even if they are not drawn by the table, the table borders still occupy their space in the layout.
					Cells will <a href="#drawing-cell-borders">render those shared borders</a>.

			<wpt>
				collapsed-border-paint-phase-001.html
				collapsed-border-paint-phase-002.html
				collapsed-border-partial-invalidation-001.html
				collapsed-border-partial-invalidation-002.html
				collapsed-border-partial-invalidation-003.html
				collapsed-border-positioned-tr-td.html
			</wpt>

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="drawing-cell-backgrounds">Drawing cell backgrounds</h4>

			<div class="advisement">
				Anonymous table-cells added by the <a href="#missing-cells-fixup">missing cells fixup</a> step
					do not render any of their backgrounds.

			In addition to its own 'background', <a>table-cell</a> boxes also
				render the backgrounds of the <a>table-track</a> and <a>table-track-group</a> boxes in which they belong.
			This is actually different from simply inheriting their background
				because the 'background-origin' and 'background-size' computations will actually be done
				on the bounds of the grouping boxes, and not on those of the cell.

			For the purposes of finding the background of each table cell,
				the different table boxes may be thought of as being on six superimposed layers.
			The background set in one of the layers will only be visible
				if the layers above it have a transparent background.

			<figure>
				<img alt="[see-caption-below]" src="images/tbl-layers.png" width=518>
				<figcaption>Schema of table layers.</figcaption>
			</figure>
			</div>

			<ol start="0">
				<li>The table background is being rendered by the table,
					and does not affect the cell background.

				<li>The first background drawn by a cell is the background of its originating table-column-group (if any).
					For the purpose of background-positioning,
						it is expected that a column group occupies
						the largest possible area a single cell could occupy in the row/column grid
						while originating in the column group and not entering any column not part of the column group.

				<li>The second background drawn by a cell is the background of its originating table-column (if any).
					For the purpose of background-positioning,
						it is expected that a column occupies
						the largest possible area a single cell could occupy in the row/column grid
						while originating in the column and not entering any other column.

				<li>The third background drawn by a cell is the background of its originating table-row-group (if any).
					For the purpose of background-positioning,
						it is expected that a row group occupies
						the largest possible area a single cell could occupy in the row/column grid
						while originating in the row group and not entering any row not part of the row group.

				<li>The fourth background drawn by a cell is the background of its originating table-row (if any).
					For the purpose of background-positioning,
						it is expected that a row occupies
						the largest possible area a single cell could occupy in the row/column grid
						while originating in the row and not entering any other row.

				<li>The fifth background drawn by a cell is its own background.
					This is the one that appears on top once all backgrounds have been rendered.
			</ol>

			As the figure above shows, although all rows contain the same number of cells,
				not every cell may have specified content.
			<a>In separated-borders mode</a>, if the value of their 'empty-cells' property is <code>hide</code>,
				these <a>empty cells</a> are not rendered at all,
				as if <code>visibility: hidden</code> was specified on them,
				letting the table background show through.

		<wpt>
			paint/col-change-span-bg-invalidation-001.html
			paint/col-change-span-bg-invalidation-002.html
			paint/col-paint-htb-rtl.html
			paint/col-paint-vrl-rtl.html
			paint/row-background-paint-remove-last-cell.html
			table-row-group-color-inheritance-001.html
		</wpt>

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="drawing-cell-borders">Drawing cell borders</h4>

			In separated-borders mode, borders of table cells are rendered as usual.

			<!--——————————————————————————————————————————————————————————————————————————-->
			<h5 id="drawing-collapsed-borders-2">Changes in collapsed-borders mode</h5>

			Borders of a <a>table-cell</a> are rendered <a>in collapsed-borders mode</a>
				as if the cell border was twice as big as its used value specify,
				and as if that excess was rendered in the margin area of the cell,
				with the added constraint that
					for each side of the border which isn’t located at one of the table edges,
					the border is actually clipped to the border-box drawing area as its real used value define
					except if the 'border-image' property is set.

			If applying the previously-mentioned clipping behavior results in clipping a border over a non-integer amount of device pixels,
				browsers may decide to snap the clipping area to a device pixel instead by ceiling the x- and y-values of the clipping area.
			Ceiling the values ensures that in a normal writing mode,
				the cell which gets the contested pixels between multiple cells is actually the most top left one,
				which has a greater specificity than the other ones according to this spec.
				<span class="hint">See [[#paint-order]] and [[#border-conflict-resolution-algorithm]].</span>

			<wpt>
				border-writing-mode-dynamic-001.html
				collapsed-border-sideways-rl-rtl-overflow.html
				collapsed-border-vertical-lr-rtl-overflow.html
				collapsed-border-vertical-rtl-overflow.html
			</wpt>

		<!--——————————————————————————————————————————————————————————————————————————-->
		<h4 id="border-style-overrides">Border styles (collapsed-borders mode)</h4>

			Some of the values of the 'border-style' have different meanings for tables <a>in collapsed-borders mode</a> than usual.
			Those definitions override the default behavior for 'border-style' values.

			: hidden
			:: Same as <code>none</code>, but also inhibits any other border (see [[#border-specificity]]).
			: inset
			:: Same as <code>ridge</code>.
			: outset
			:: Same as <code>groove</code>.

	<!--——————————————————————————————————————————————————————————————————————————-->
	<h3 id="visibility-collapse-rendering">Rendering for visibility: collapse</h3>

	When a table part has <a href="http://www.w3.org/TR/CSS22/visufx.html#visibility">visibility: collapse</a> set, the rendering is handled
	differently depending if it is on a <a>table-cell</a>, spanning <a>table-cell</a>, or a <a>table-track</a>/<a>table-track-group</a>.

	<wpt>
		visibility-collapse-border-spacing-001.html
		visibility-collapse-border-spacing-002.html
		visibility-hidden-collapsed-borders.html
	</wpt>

		<h4 id="visibility-collapse-cell-rendering">Rendering a visibility: collapse table cell</h4>
		As stated in CSS 2.2, if a <a>table-cell</a> has its visibility set to that of collapse, it is rendered the same as
		if it had <a href="http://www.w3.org/TR/CSS22/visufx.html#visibility">visibility: hidden</a> set.

		<div class="note">

			This happens when you set visibility:collapse on a table-row that contains a table-cell.
			If you want to hide a row but continue to display its cells that span other rows, 
			set visibility:visible on those cells to prevent them from inheriting their value.

		</div>

		If the <a>table-cell</a> is spanning more than one <a>table-track</a>, and at least one of those <a>table-track</a> is set to 
		<a href="http://www.w3.org/TR/CSS22/visufx.html#visibility">visibility: collapse</a> then clip the content
		to the <a>table-cell</a>'s border-box. This means that the top left (top right in rtl) content of the cell will continue to show,
		regardless of which of the tracks the cell spans has been collapsed.

		<h4 id="visibility-collapse-track-rendering">Rendering a visibility: collapse table-track or table-track-group</h4>
		When a <a>table-track</a> or <a>table-track-group</a> has <a href="http://www.w3.org/TR/CSS22/visufx.html#visibility">visibility: collapse</a>, 
		all the backgrounds, borders or outlines that are contributed by the cells within the given <a>table-track</a> or
		<a>table-track-group</a> will continue to be painted on cells that have not been fully collapsed
		(because they spanned multiple tracks).

		<wpt>
			visibility-collapse-colspan-003.html
			visibility-collapse-colspan-crash.html
			visibility-collapse-rowspan-002-border-separate.html
			visibility-collapse-rowspan-002.html
			visibility-collapse-rowspan-004-dynamic.html
			visibility-collapse-rowspan-005.html
			visibility-collapse-rowspan-crash.html
		</wpt>

<!--
████████ ████████     ███     ██████   ██     ██ ████████ ██    ██ ████████    ███    ████████ ████  ███████  ██    ██
██       ██     ██   ██ ██   ██    ██  ███   ███ ██       ███   ██    ██      ██ ██      ██     ██  ██     ██ ███   ██
██       ██     ██  ██   ██  ██        ████ ████ ██       ████  ██    ██     ██   ██     ██     ██  ██     ██ ████  ██
██████   ████████  ██     ██ ██   ████ ██ ███ ██ ██████   ██ ██ ██    ██    ██     ██    ██     ██  ██     ██ ██ ██ ██
██       ██   ██   █████████ ██    ██  ██     ██ ██       ██  ████    ██    █████████    ██     ██  ██     ██ ██  ████
██       ██    ██  ██     ██ ██    ██  ██     ██ ██       ██   ███    ██    ██     ██    ██     ██  ██     ██ ██   ███
██       ██     ██ ██     ██  ██████   ██     ██ ████████ ██    ██    ██    ██     ██    ██    ████  ███████  ██    ██
-->
<h2 id="fragmentation">Fragmentation</h2>

	<!--——————————————————————————————————————————————————————————————————————————-->
	<h3 id="breaking-rules">Breaking across fragmentainers</h3>

		When fragmenting a table, user agents must attempt
			to preserve the table rows unfragmented
			if the cells spanning the row do not span any subsequent row, and
			their height is at least twice smaller than both the fragmentainer height and width.
		Other rows are said <dfn id="freely-fragmentable">freely fragmentable</dfn>.

		When a table doesn't fit entirely in a fragmentainer,
			at least one row did fit entirely in the fragmentainer,
			and the first row that does not fit in the fragmentainer is not <a>freely fragmentable</a>.
			the user agent has to insert some vertical gap
			between the rows located before and at the overflow point
			such that the two rows end up separated in sibling fragmentainers.
		If the fragmentation requires repeating headers and footers, and the footer is repeated,
			then the footer must come directly after the last row in the fragmentainer
			and the vertical gap must be inserted after the repeated footer.

		<figure>
			<img alt="[see-caption-below]" src="./images/CSS-Tables-Fragmentation-1.svg" width=500 style="width:100%; max-width: 500px;">
			<figcaption>Expected rendering of table fragmented across two pages</figcaption>
		</figure>

		When there is no row fitting entirely in the current fragmentainer
		or when the first row that does not fit in the fragmentainer is <a>freely fragmentable</a>,
			user agents must attribute all the remaining height in the fragmentainer to the cells
			of that row, and fit as much content as it can in each of the cells independently,
			then break to the next fragment and start the content of each cell where it was stopped
			in its previous fragment (top borders must not be repainted in continuation fragments).

		<figure>
			<img alt="[see-caption-below]" src="./images/CSS-Tables-Fragmentation-2.svg" width=500 style="width:100%; max-width: 500px;">
			<figcaption>Expected rendering of table containing a tall row fragmented across two pages</figcaption>
		</figure>

		When 'break-before' or 'break-after' is applied
		to a <a>table-row-group</a> or a <a>table-row</a> box,
			the user agent has to insert some vertical gap
			between the rows located before and after the breaking point
			such that the two rows end up separated in sibling fragmentainers
			as required by the property value.
		If the fragmentation requires repeating headers and footers, and the footer is repeated,
			then the footer must come directly after the last row in the fragmentainer
			and the vertical gap must be inserted after the repeated footer.

	<!--——————————————————————————————————————————————————————————————————————————-->
	<h3 id="repeated-headers">Repeating headers across pages</h3>

		When rendering the document into a [=paged media=],
			user agents must repeat
				<a href="#table-header-group">header rows</a> and
				<a href="#table-footer-group">footer rows</a>
			on each page spanned by a table
			if the page is the table's fragmentainer,
			if the header/footer has avoid 'break-inside' applied to it,
			if the height required to do so is inferior to
				two quarters of the page height
				(up to one quarter for header rows, and
				up to one quarter for footer rows), and
			if that doesn't cause a row to be displayed twice
				on that page.

		When the header rows are being repeated, user agents must
			leave room and if needed render the table top border.
		The same applies for footer rows and the table bottom border.

		<figure>
			<img alt="[see-caption-below]" src="./images/CSS-Tables-Repeating-Headers.svg" width=500 style="width:100%; max-width: 500px;">
			<figcaption>Expected rendering of table with headers and footers fragmented across two pages</figcaption>
		</figure>

		<p class="advisement">
			User agents may decide to extend this behavior to more fragmentation contexts,
				for instance repeat headers/rows across columns in addition to pages.
			User-agents that are rendering static documents are more likely to adopt this behavior,
				though this is not required per spec.

<!--——————————————————————————————————————————————————————————————————————————-->
<h2 id="security">Security Considerations</h2>

Using CSS Tables does not incur any security risk to mitigate.

<!--——————————————————————————————————————————————————————————————————————————-->
<h2 id="privacy">Privacy Considerations</h2>

Using CSS Tables does not incur any privacy risk to mitigate.

<!--——————————————————————————————————————————————————————————————————————————-->
<h2 id="bug-list">List of bugs being tracked</h2>

<p style="font-style: italic">
	This section is not normative.

<ul class="bug-list">

	<li>
		<details><summary tabindex="0">
			<a href="http://codepen.io/FremyCompany/pen/jWzpjq?editors=1100">
				Align=center attribute overrides css margins in Edge
			</a>
		</summary><aside>
			Chrome and Firefox let CSS win.<br/>
			Edge hides every border + table/row-group/row background.<br/>
			<br/>
			This specification says that Chrome and Firefox are right.<br/>
			[[#mapping]]
		</aside></details>
	</li>

	<li>
		<details><summary tabindex="0">
			<a href="http://codepen.io/FremyCompany/pen/ZQxVMo?editors=1100">
				Chrome applies nowrap quirks mode fix in DOCTYPE documents too
			</a>
		</summary><aside>
			Edge and Firefox do not apply the fix in normal mode.<br/>
			Chrome also applies it for css widths, which is not what the spec says to do.<br/>
			<br/>
			The WHATWG spec says that Chrome is wrong.<br/>
			This spec is aiming to state the same thing.<br/>
			[[#mapping]]
		</aside></details>
	</li>

	<li>
		<details><summary tabindex="0">
			<a href="http://codepen.io/FremyCompany/pen/RrMvPR?editors=1100">
				Edge does not account for widths of spanned cells
			</a>
		</summary><aside>
			Chrome and Firefox merge the two columns so are not affected.<br/>
			Edge does not then is confused about what to do.<br/>
			<br/>
			The specs says that Edge is wrong.<br/>
			[[#dimensioning-the-row-column-grid]]
		</aside></details>
	</li>

	<li>
		<details><summary tabindex="0">
			<a href="https://jsfiddle.net/6L94pxgn/1/#6188753">
				Chrome and Gecko do not apply display:table-cell on &lt;button>
			</a>
		</summary><aside>
			Also <a href="https://jsfiddle.net/6L94pxgn/3/">@lt;fieldset></a>.
			This specification says that Chrome and Firefox are wrong.<br/>
			[[#style-overrides]]
		</aside></details>
	</li>

	<li>
		<details><summary tabindex="0">
			<a href="http://codepen.io/FremyCompany/pen/xZWmXy?editors=1100">
				Edge's table-cell width unexplainably low due to percentage-max-width on content and colspan
			</a>
		</summary><aside>
			Edge has issues with percentage widths.<br/>
			<br/>
			This specification should say that Chrome and Firefox are right, I guess.<br/>
			[[#computing-cell-measures]]
		</aside></details>
	</li>

	<li>
		<details><summary tabindex="0">
			<a href="http://codepen.io/FremyCompany/pen/PZRdzo?editors=1100">
				Table wrapper boxes should be wide enough to contain the caption
			</a>
		</summary><aside>
			Chrome uses the CSS21 algorithm that fulfill this.<br/>
			Firefox and Edge use David Baron's algorithm that doesn't.<br/>
			<br/>
			This specification has no opinion yet on the matter.<br/>
			Chrome behavior is simpler to spec but not intuitive.<br/>
			[[#computing-the-table-width]]
			<br/>
			<br/>
			This may be solved by <a href="https://lists.w3.org/Archives/Public/www-style/2010Sep/0186.html">
				www-list</a> on the width of the table boxes in relation to their table captions
		</aside></details>
	</li>

	<li>
		<details><summary tabindex="0">
			<a href="http://codepen.io/FremyCompany/pen/VeXVwz?editors=1100">
				Tables containing no row cannot have height in Chrome, but can in Edge/Firefox
			</a>
		</summary><aside>
			Chrome has table height = 0px.<br/>
			Firefox and Edge have table height = specified height.<br/>
			<br/>
			This specification has no opinion yet on the matter.<br/>
			Firefox and Edge match author intentions better.<br/>
			[[#computing-the-table-height]]
		</aside></details>
	</li>

	<li>
		<details><summary tabindex="0">
			<a href="http://codepen.io/FremyCompany/pen/yeKRGW?editors=1100">
				Table-layout:fixed causes different width distribution in Chrome
			</a>
		</summary><aside>
			Chrome starts to value px then percentages.<br/>
			Others continue to value percentage then px.<br/>
			<br/>
			This specification has no opinion yet on the matter.<br/>
			It is intended to specify the Edge/Firefox behavior.<br/>
			[[#width-distribution]]
		</aside></details>
	</li>

	<li>
		<details><summary tabindex="0">
			<a href="http://codepen.io/FremyCompany/pen/XXEoWe?editors=1100">
				Chrome distributes the height to each row differently then IE and firefox
			</a>
		</summary><aside>
			Chrome distributes rather equally.<br/>
			Edge and Firefox work more similarly to width distribution.<br/>
			<br/>
			This specification has no opinion yet on the matter.<br/>
			I think it makes sense to behave similarly for width and height, though.<br/>
			[[#height-distribution]]
		</aside></details>
	</li>

	<li>
		<details><summary tabindex="0">
			<a href="http://codepen.io/FremyCompany/pen/PZRdOP?editors=1100">
				Height of rows which can overflow varies in Chrome vs Edge
				(percentage heights during min-height computation)
			</a>
		</summary><aside>
			Chrome chooses table constraints over the no-scroll constraint.<br/>
			Edge and Firefox do the opposite.<br/>
			<br/>
			This specification has no opinion yet on the matter.<br/>
			Edge's behavior is right by default due to CSS Sizing, though.<br/>
			It would make sense to do what Chrome is doing when elements have non-visible overflow-y.<br/>
			[[#height-distribution]] <a href="#min-content-and-percentages">#REF</a>
		</aside></details>
	</li>

	<li>
		<details><summary tabindex="0">
			<a href="http://codepen.io/FremyCompany/pen/MKVPGR?editors=1100">
				Height specified on row groups is not interoperable
			</a>
		</summary><aside>
			Chrome ignores the height.<br/>
			Firefox respects the height.<br/>
			IE applies the height to each cell.<br/>
			<br/>
			This specification has no opinion yet on the matter.<br/>
			An author would expect the Firefox behavior.<br/>
			[[#height-distribution]]
		</aside></details>
	</li>

	<li>
		<details><summary tabindex="0">
			<a href="http://codepen.io/FremyCompany/pen/MKVPGR?editors=1100">
				Min-Height specified on rows is not interoperable
			</a>
		</summary><aside>
			Chrome and Firefox ignore the height.<br/>
			Edge applies the height.<br/>
			<br/>
			The working group resolved on Edge behavior.<br/>
			An author would expect the Edge behavior.<br/>
			[[#height-distribution]]
		</aside></details>
	</li>

	<li>
		<details><summary tabindex="0">
			<a href="http://jsfiddle.net/ArtyomShegeda/Ffjhn/1/">
				Table with interleaved td[rowspan] rendered wrong in IE (145069)
			</a>
		</summary><aside>
			Edge height-sizing has issues with this crossed-rowspan table.<br/>
			<br/>
			There is no doubt this is a bug, but it is a good test case for the algorithm.<br/><br/>
			[[#height-distribution]]
		</aside></details>
	</li>

	<li>
		<details><summary tabindex="0">
			<a href="http://codepen.io/FremyCompany/pen/MKVqXQ?editors=1100">
				Row with explicit 'visibility:visible' lose background color
				when parent table has 'visibility: hidden'
			</a>
		</summary><aside>
			Chrome only hides table background + border.<br/>
			Firefox hides table background + border, and row-group background.<br/>
			Edge hides every border + table/row-group/row background.<br/>
			<br/>
			This specification currently says that Chrome is right.<br/>
			[[#drawing-cell-backgrounds]]<br/>
			<div class="issue">
				Should we hide the row-group background
					by saying cells only draw the backgrounds
					of visibility:visible grouping elements?
			</div>
		</aside></details>
	</li>

</ul>

<style>

	ul.bug-list {
		list-style-type: none;
		padding: 0;
		font-size: 80%;
	}
	ul.bug-list > li {
		margin: 0; margin-bottom: 10px;
	}
	ul.bug-list > li > details {
		background: #efefef;
		padding: 10px;
	}
	ul.bug-list > li > details > aside {
		background: #f7f7f7;
		padding: 10px; font-weight: normal;
	}
	ul.bug-list > li > details > summary > a {
		border-bottom-color: transparent;
	}

</style>

<!--——————————————————————————————————————————————————————————————————————————-->
<h2 id="appendices">Appendices</h2>

	<!--——————————————————————————————————————————————————————————————————————————-->
	<h3 id="mapping">Mapping between CSS &amp; HTML attributes</h3>

		The default style sheet for HTML4 illustrates how its model maps to css properties and values:

		<div class="note">
			Some extensions to CSS have been used for constraints not mappable to current CSS constructs
			</div>

		<pre class="lang-css">

	table    { display: table }
	thead    { display: table-header-group }
	tbody    { display: table-row-group }
	tfoot    { display: table-footer-group }
	tr       { display: table-row }
	td, th   { display: table-cell }
	colgroup { display: table-column-group }
	col      { display: table-column }
	caption  { display: table-caption }
	table, thead, tbody, tfoot, tr, td, th, colgroup, col, caption { box-sizing: border-box; }
	thead, tfoot { break-inside: avoid }

<!--
	Non-border built-ins
-->
	table {
		box-sizing: border-box;
		border-spacing: 2px;
		border-collapse: separate;
		text-indent: initial;
	}

	thead, tbody, tfoot, table > tr { vertical-align: middle; }
	tr, td, th { vertical-align: inherit; }

	td, th { padding: 1px; }
	th { font-weight: bold;	}

	table, td, th { border-color: gray; }
	thead, tbody, tfoot, tr { border-color: inherit; }

<!--
	Border built-ins
-->


<!--
	FRAME (part 1/2)
	http://www.w3schools.com/tags/tryit.asp?filename=tryhtml_table_frame
-->
	table[frame=box i], table[frame=border i], table[frame=hsides i], table[frame=above i], table[frame=below i], table[frame=vsides i], table[frame=lhs i], table[frame=rhs i] {
		border: 1px solid inset;
	}


<!--
	RULES (part 1/3)
	http://codepen.io/FremyCompany/pen/GopJMp
-->
	table:is([rules=all i], [rules=rows i], [rules=cols i], [rules=groups i], [rules=none i]) {
		border-collapse: collapse;
		border-style: hidden;
	}

	table:is([rules=all i], [rules=rows i], [rules=cols i], [rules=groups i], [rules=none i]),
	table:is([rules=all i], [rules=rows i], [rules=cols i], [rules=groups i], [rules=none i]) > :is(thead,tbody,tfoot) > tr > :is(th,td) {
		border-color: black;
	}

<!--
	BORDER
	http://codepen.io/FremyCompany/pen/EPVjNp
-->
	table[border=$border] /* if(parseInt($border) > 0) */ {
		border: /*(parseInt($border) * 1px)*/ outset rgb(128, 128, 128);
	}
	table[border=$border] > :is(thead,tbody,tfoot) > tr > :is(th,td) /* if(parseInt($border) > 0) */ {
		border: 1px inset rgb(128, 128, 128);
	}

<!--
	RULES (part 2/3)
	http://codepen.io/FremyCompany/pen/GopJMp
-->
	table[rules=all i] > :is(thead,tbody,tfoot) > tr > :is(th,td) {
		border: 1px solid grey;
	}
	table[rules=rows i] > :is(thead,tbody,tfoot) > tr > :is(th,td) {
		border: 1px solid grey;
		border-left: none;
		border-right: none;
	}
	table[rules=cols i] > :is(thead,tbody,tfoot) > tr > :is(th,td) {
		border: 1px solid grey;
		border-top: none;
		border-bottom: none;
	}
	table[rules=none i] > :is(thead,tbody,tfoot) > tr > :is(th,td) {
		border: none;
	}

<!--
	RULES (part 3/3)
	http://codepen.io/FremyCompany/pen/jWbPXY
	https://jsfiddle.net/ewv08n0r/
-->
	table[rules=groups i] > :is(thead,tbody,tfoot) {
		border-top-width: 1px; border-top-style: solid;
		border-bottom-width: 1px; border-bottom-style: solid;
	}
	table[rules=groups i] > colgroup {
		border-left-width: 1px; border-left-style: solid;
		border-right-width: 1px; border-right-style: solid;
	}

<!--
	FRAME (part 2/2)
	http://www.w3schools.com/tags/tryit.asp?filename=tryhtml_table_frame
-->
	table[frame=box i], table[frame=border i], table[frame=hsides i], table[frame=above i], table[frame=below i], table[frame=vsides i], table[frame=lhs i], table[frame=rhs i] {
		border-style: outset;
	}
	table[frame=below i], table[frame=vsides i], table[frame=lhs i], table[frame=rhs i] {
		border-top-style: hidden;
	}
	table[frame=above i], table[frame=vsides i], table[frame=lhs i], table[frame=rhs i] {
		border-bottom-style: hidden;
	}
	table[frame=hsides i], table[frame=above i], table[frame=below i], table[frame=rhs i] {
		border-left-style: hidden;
	}
	table[frame=hsides i], table[frame=above i], table[frame=below i], table[frame=rhs i] {
		border-right-style: hidden;
	}

<!--
	Others:
-->
	table[cellpadding=$x] > :is(thead,tbody,tfoot) > tr > :is(th,td) /* if(parseInt($x)>0) */ {
		padding: /*(parseInt($x) * 1px)*/;
	}
	table[cellspacing=$x] /* if(parseInt($x)>0) */ {
		border-spacing: /*(parseInt($x) * 1px)*/;
	}


	table[width=$w] /* if(parseInt($w) > 0) */ {
		width: /*(parseInt($w) * 1px)*/;
	}
	table[width=$w] /* if($w matches /(+|-|)(&#91;0-9&#93;+(&#91;.&#93;&#91;0-9&#93;+|)|(&#91;.&#93;&#91;0-9&#93;+))&#91;%&#93;/) */ {
		width: /*(parseInt($w) * 1px)*/;
	}
	table[height=$h] /* if(parseInt($h) > 0) {
		height: /*(parseInt($h) * 1px)*/;
	}
	table[height=$h] /* if($h matches /(+|-|)(&#91;0-9&#93;+(&#91;.&#93;&#91;0-9&#93;+|)|(&#91;.&#93;&#91;0-9&#93;+))&#91;%&#93;/) */ {
		height: /*(parseInt($h) * 1px)*/;
	}


	table[bordercolor=$color] {
		border-color: /*parseHTMLColor($color)*/;
	}
	table[bordercolor] > :is(tbody, thead, tfoot, tr, colgroup, col),
	table[bordercolor] > :is(tbody, thead, tfoot) > tr,
	table[bordercolor] > :is(tbody, thead, tfoot) > tr > :is(td, th),
	table[bordercolor] > tr > :is(td, th)
	table[bordercolor] > colgroup > col
	) {
		border-color: inherit;
	}
	table[bgcolor=$color] {
		background-color: /*parseHTMLColor($color)*/;
	}
	table[align=left i] {
		float: left;
	}
	table[align=right i] {
		float: right;
	}
	table[align=center i] {
		margin-left: auto;
		margin-right: auto;
	}

<!--
	NON-TABLE ATTRIBUTES:
-->
	caption[align=bottom i] { caption-side: bottom; }
	:is(thead,tbody,tfoot,tr,td,th)[valign=top i] {
		vertical-align: top;
	}
	:is(thead,tbody,tfoot,tr,td,th)[valign=middle i] {
		vertical-align: middle;
	}
	:is(thead,tbody,tfoot,tr,td,th)[valign=bottom i] {
		vertical-align: bottom;
	}
	:is(thead,tbody,tfoot,tr,td,th)[valign=baseline i] {
		vertical-align: baseline;
	}

	:is(thead,tbody,tfoot,tr,td,th)[align=absmiddle i] {
		text-align: center;
	}

	:is(colgroup,col,thead,tbody,tfoot,tr,td,th)[hidden] {
		visibility: collapse;
	}

	:is(td,th)[nowrap] { white-space: nowrap; }
	:is(td,th)[nowrap][width=$w] /* if(quirksMode && parseInt($w) > 0) */ {
		white-space: normal;
	}

</pre>

	<wpt>
		html-to-css-mapping-1.html
		html-to-css-mapping-2.html
		table-has-box-sizing-border-box-001.html
		table-has-box-sizing-border-box-002.html
		rules-groups.html
	</wpt>

	<div class="note">
		Some of the content here came from the WHATWG spec on the
		<a href="https://html.spec.whatwg.org/#tables-2">HTML to CSS mapping of tables</a>.
		However, since they include <a href="https://jsfiddle.net/8t78exf1/">things which are not true</a> in most browsers, this is not a simple copy.
		Investigations are therefore required for each and any merge being made from one source to another!
	</div>


<!--——————————————————————————————————————————————————————————————————————————-->
<h2 id="TODO">(link here for missing sections)</h2>

<!--——————————————————————————————————————————————————————————————————————————-->
<h2 id="changes">Changes</h2>

Significant changes since the <a href="https://www.w3.org/TR/2019/WD-css-tables-3-20190727/">27 July 2019 Working Draft</a>:

<ul>

	<li>Referenced the terms [=paged media=] and [=continuous media=] from [[!MEDIAQUERIES-5]].
	<li>Replaced mentions of '':matches()'' pseudo-class with '':is()''.
	<li>Clarified that outer table elements behave according to their outer display type.
	<li>Allowed ''overflow/clip'' to apply to [=table-root=] and [=table-wrapper=] boxes.
	<li>Added Web Platform Test coverage.

</ul>

<style>

	.hint { opacity: 0.5; transition: opacity 0.25s; }
	.hint:hover { opacity: 1; }

	.highlight { background: yellow; }

	/* fallback for summary/details */
	details { display: block; font-weight: normal !important; }
	details:not([open]) > aside { display: none; }
	details:not([open]) > summary { display: block; }
	details:not([open]) > summary:focus + aside { display: block; }
	#if-css-supports ::-webkit-details-marker, details:not([open]) > aside { display: block; }
	#if-css-supports ::-moz-details-marker,    details:not([open]) > aside { display: block; }
	#if-css-supports ::-ms-details-marker,     details:not([open]) > aside { display: block; }
	/* THIS IS COMMENTED BECAUSE IT FAILS VALIDATION * /
	#if-css-supports ::details-marker,         details:not([open]) > aside { display: block; }
	/* END OF COMMENT */

</style>

<wpt hidden title="Tentative tests">
	tentative/baseline-table.html
	tentative/baseline-td.html
	tentative/border-collapse-spanning-cells-001.html
	tentative/border-collapse-spanning-cells-002.html
	tentative/border-collapse-spanning-cells-003.html
	tentative/border-collapse-spanning-cells-004.html
	tentative/caption.html
	tentative/col-collapse-table-size.html
	tentative/colgroup-col.html
	tentative/collapsed-borders-painting-order-001.html
	tentative/collapsed-borders-painting-order-002.html
	tentative/collapsed-borders-painting-order-003.html
	tentative/collapsed-borders-painting-order-004.html
	tentative/collapsed-borders-painting-order-005.html
	tentative/collapsed-borders-painting-order-006.html
	tentative/collapsed-borders-painting-order-007.html
	tentative/collapsed-borders-painting-order-008.html
	tentative/collapsed-borders-painting-order-009.html
	tentative/collapsed-borders-painting-order-010.html
	tentative/collapsed-borders-painting-order-011.html
	tentative/collapsed-borders-painting-order-012.html
	tentative/collapsed-borders-painting-order-013.html
	tentative/colspan-redistribution.html
	tentative/column-widths.html
	tentative/element-sizing.html
	tentative/padding-percentage.html
	tentative/paint/background-image-column-collapsed.html
	tentative/paint/background-image-column.html
	tentative/paint/background-image-row-collapsed.html
	tentative/paint/background-image-row.html
	tentative/paint/collapsed-border-large-cell.html
	tentative/paint/overflow-hidden-table.html
	tentative/position-sticky-container.html
	tentative/rowspan-height-redistribution.html
	tentative/section-no-tbody-fixed-distribution.html
	tentative/section-no-tbody-percent-distribution.html
	tentative/table-fixed-minmax.html
	tentative/table-height-redistribution.html
	tentative/table-limited-quirks.html
	tentative/table-minmax.html
	tentative/table-quirks.html
	tentative/table-rows-with-zero-columns.html
	tentative/table-width-redistribution-fixed-padding.html
	tentative/table-width-redistribution-fixed.html
	tentative/table-width-redistribution.html
	tentative/tbody-height-redistribution.html
	tentative/td-box-sizing-001.html
	tentative/td-box-sizing-002.html
	tentative/td-box-sizing-003.html
</wpt>
