Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: align-self not work for positioned flex item #1207

Merged
merged 1 commit into from Mar 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
101 changes: 101 additions & 0 deletions integration_tests/specs/css/css-flexbox/align-self.ts
Expand Up @@ -1695,4 +1695,105 @@ describe('align-self', () => {
done();
});
});

it('stretch should not work with positioned child of no top bottom', async () => {
let item = createElement('div', {
style: {
display: 'flex',
flexDirection: 'row',
height: '50px',
backgroundColor: 'coral',
}
}, [
createElement('div', {
style: {
position: 'absolute',
alignSelf: 'stretch',
backgroundColor: 'lightblue',
}
}, [
createText('stretch')
]),
]);

BODY.appendChild(item);

await snapshot();
});

it('flex-start should work with positioned child of no top bottom', async () => {
let item = createElement('div', {
style: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
height: '50px',
backgroundColor: 'coral',
}
}, [
createElement('div', {
style: {
position: 'absolute',
alignSelf: 'flex-start',
backgroundColor: 'lightblue',
}
}, [
createText('flex-start')
]),
]);

BODY.appendChild(item);

await snapshot();
});

it('center should work with positioned child of no top bottom', async () => {
let item = createElement('div', {
style: {
display: 'flex',
flexDirection: 'row',
height: '50px',
backgroundColor: 'coral',
}
}, [
createElement('div', {
style: {
position: 'absolute',
alignSelf: 'center',
backgroundColor: 'lightblue',
}
}, [
createText('center')
]),
]);

BODY.appendChild(item);

await snapshot();
});

it('flex-end should work with positioned child of no top bottom', async () => {
let item = createElement('div', {
style: {
display: 'flex',
flexDirection: 'row',
height: '50px',
backgroundColor: 'coral',
}
}, [
createElement('div', {
style: {
position: 'absolute',
alignSelf: 'flex-end',
backgroundColor: 'lightblue',
}
}, [
createText('flex-end')
]),
]);

BODY.appendChild(item);

await snapshot();
});
});
9 changes: 9 additions & 0 deletions kraken/lib/src/css/render_style.dart
Expand Up @@ -833,6 +833,15 @@ class CSSRenderStyle
bool isFlexNoWrap = false;
bool isChildStretchSelf = false;
if (isParentFlex) {
// The absolutely-positioned box is considered to be “fixed-size”, a value of stretch
// is treated the same as flex-start.
// https://www.w3.org/TR/css-flexbox-1/#abspos-items
bool isPositioned = renderStyle.position == CSSPositionType.absolute
|| renderStyle.position == CSSPositionType.fixed;
if (isPositioned) {
return false;
}

isHorizontalDirection = CSSFlex.isHorizontalFlexDirection(parentRenderStyle.flexDirection);
isFlexNoWrap = parentRenderStyle.flexWrap != FlexWrap.wrap &&
parentRenderStyle.flexWrap != FlexWrap.wrapReverse;
Expand Down
23 changes: 17 additions & 6 deletions kraken/lib/src/rendering/flex.dart
Expand Up @@ -291,13 +291,16 @@ class RenderFlexLayout extends RenderLayoutBox {
}

AlignSelf _getAlignSelf(RenderBox child) {
// Flex shrink has no effect on placeholder of positioned element.
if (child is RenderPositionPlaceholder) {
return AlignSelf.auto;
RenderBoxModel? childRenderBoxModel;
if (child is RenderBoxModel) {
childRenderBoxModel = child;
} else if (child is RenderPositionPlaceholder) {
childRenderBoxModel = child.positioned;
}
if (childRenderBoxModel != null) {
return childRenderBoxModel.renderStyle.alignSelf;
}
return child is RenderBoxModel
? child.renderStyle.alignSelf
: AlignSelf.auto;
return AlignSelf.auto;
}

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

// The absolutely-positioned box is considered to be “fixed-size”, a value of stretch
// is treated the same as flex-start.
// https://www.w3.org/TR/css-flexbox-1/#abspos-items
final RenderLayoutParentData childParentData = child.parentData as RenderLayoutParentData;
if (child is RenderBoxModel && childParentData.isPositioned) {
return false;
}

AlignSelf alignSelf = _getAlignSelf(child);
bool isChildAlignmentStretch = alignSelf != AlignSelf.auto
? alignSelf == AlignSelf.stretch
Expand Down