Skip to content

Commit 0f1701d

Browse files
authored
Merge pull request #1207 from openkraken/fix/align-self-of-positioned-element
fix: align-self not work for positioned flex item
2 parents 051dacd + 9ebe2d0 commit 0f1701d

File tree

7 files changed

+127
-6
lines changed

7 files changed

+127
-6
lines changed
Loading
Loading
Loading
Loading

integration_tests/specs/css/css-flexbox/align-self.ts

+101
Original file line numberDiff line numberDiff line change
@@ -1695,4 +1695,105 @@ describe('align-self', () => {
16951695
done();
16961696
});
16971697
});
1698+
1699+
it('stretch should not work with positioned child of no top bottom', async () => {
1700+
let item = createElement('div', {
1701+
style: {
1702+
display: 'flex',
1703+
flexDirection: 'row',
1704+
height: '50px',
1705+
backgroundColor: 'coral',
1706+
}
1707+
}, [
1708+
createElement('div', {
1709+
style: {
1710+
position: 'absolute',
1711+
alignSelf: 'stretch',
1712+
backgroundColor: 'lightblue',
1713+
}
1714+
}, [
1715+
createText('stretch')
1716+
]),
1717+
]);
1718+
1719+
BODY.appendChild(item);
1720+
1721+
await snapshot();
1722+
});
1723+
1724+
it('flex-start should work with positioned child of no top bottom', async () => {
1725+
let item = createElement('div', {
1726+
style: {
1727+
display: 'flex',
1728+
flexDirection: 'row',
1729+
alignItems: 'center',
1730+
height: '50px',
1731+
backgroundColor: 'coral',
1732+
}
1733+
}, [
1734+
createElement('div', {
1735+
style: {
1736+
position: 'absolute',
1737+
alignSelf: 'flex-start',
1738+
backgroundColor: 'lightblue',
1739+
}
1740+
}, [
1741+
createText('flex-start')
1742+
]),
1743+
]);
1744+
1745+
BODY.appendChild(item);
1746+
1747+
await snapshot();
1748+
});
1749+
1750+
it('center should work with positioned child of no top bottom', async () => {
1751+
let item = createElement('div', {
1752+
style: {
1753+
display: 'flex',
1754+
flexDirection: 'row',
1755+
height: '50px',
1756+
backgroundColor: 'coral',
1757+
}
1758+
}, [
1759+
createElement('div', {
1760+
style: {
1761+
position: 'absolute',
1762+
alignSelf: 'center',
1763+
backgroundColor: 'lightblue',
1764+
}
1765+
}, [
1766+
createText('center')
1767+
]),
1768+
]);
1769+
1770+
BODY.appendChild(item);
1771+
1772+
await snapshot();
1773+
});
1774+
1775+
it('flex-end should work with positioned child of no top bottom', async () => {
1776+
let item = createElement('div', {
1777+
style: {
1778+
display: 'flex',
1779+
flexDirection: 'row',
1780+
height: '50px',
1781+
backgroundColor: 'coral',
1782+
}
1783+
}, [
1784+
createElement('div', {
1785+
style: {
1786+
position: 'absolute',
1787+
alignSelf: 'flex-end',
1788+
backgroundColor: 'lightblue',
1789+
}
1790+
}, [
1791+
createText('flex-end')
1792+
]),
1793+
]);
1794+
1795+
BODY.appendChild(item);
1796+
1797+
await snapshot();
1798+
});
16981799
});

kraken/lib/src/css/render_style.dart

+9
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,15 @@ class CSSRenderStyle
833833
bool isFlexNoWrap = false;
834834
bool isChildStretchSelf = false;
835835
if (isParentFlex) {
836+
// The absolutely-positioned box is considered to be “fixed-size”, a value of stretch
837+
// is treated the same as flex-start.
838+
// https://www.w3.org/TR/css-flexbox-1/#abspos-items
839+
bool isPositioned = renderStyle.position == CSSPositionType.absolute
840+
|| renderStyle.position == CSSPositionType.fixed;
841+
if (isPositioned) {
842+
return false;
843+
}
844+
836845
isHorizontalDirection = CSSFlex.isHorizontalFlexDirection(parentRenderStyle.flexDirection);
837846
isFlexNoWrap = parentRenderStyle.flexWrap != FlexWrap.wrap &&
838847
parentRenderStyle.flexWrap != FlexWrap.wrapReverse;

kraken/lib/src/rendering/flex.dart

+17-6
Original file line numberDiff line numberDiff line change
@@ -291,13 +291,16 @@ class RenderFlexLayout extends RenderLayoutBox {
291291
}
292292

293293
AlignSelf _getAlignSelf(RenderBox child) {
294-
// Flex shrink has no effect on placeholder of positioned element.
295-
if (child is RenderPositionPlaceholder) {
296-
return AlignSelf.auto;
294+
RenderBoxModel? childRenderBoxModel;
295+
if (child is RenderBoxModel) {
296+
childRenderBoxModel = child;
297+
} else if (child is RenderPositionPlaceholder) {
298+
childRenderBoxModel = child.positioned;
299+
}
300+
if (childRenderBoxModel != null) {
301+
return childRenderBoxModel.renderStyle.alignSelf;
297302
}
298-
return child is RenderBoxModel
299-
? child.renderStyle.alignSelf
300-
: AlignSelf.auto;
303+
return AlignSelf.auto;
301304
}
302305

303306
double _getMaxMainAxisSize(RenderBox child) {
@@ -1992,6 +1995,14 @@ class RenderFlexLayout extends RenderLayoutBox {
19921995
// Position placeholder and BR element has size of zero, so they can not be stretched.
19931996
if (child is RenderPositionPlaceholder || child is RenderLineBreak) return false;
19941997

1998+
// The absolutely-positioned box is considered to be “fixed-size”, a value of stretch
1999+
// is treated the same as flex-start.
2000+
// https://www.w3.org/TR/css-flexbox-1/#abspos-items
2001+
final RenderLayoutParentData childParentData = child.parentData as RenderLayoutParentData;
2002+
if (child is RenderBoxModel && childParentData.isPositioned) {
2003+
return false;
2004+
}
2005+
19952006
AlignSelf alignSelf = _getAlignSelf(child);
19962007
bool isChildAlignmentStretch = alignSelf != AlignSelf.auto
19972008
? alignSelf == AlignSelf.stretch

0 commit comments

Comments
 (0)