这是具有
align-items: center
属性的眼睛。它们对于单行文本是可以的,对于多行文本是失败的:
这是带有
align-items: baseline
(或 flex-start
)的眼睛。它们更适合多行文本,但并不适合所有文本,因为我想将眼睛与文本第一行的中心对齐:
我想要实现的是:
看到眼睛图像如何居中于文本的第一行吗?
是否可以使用 Flexbox 属性优雅地做到这一点,而不使用填充或边距?
(这是一个简化的例子,在实际问题中我不想引入padding,因为它会影响其他项目。)
这里是 jsfiddle 可以玩:http://jsfiddle.net/sqp1wdap/
我找到了解决方案:http://jsfiddle.net/sqp1wdap/3/
flex-start
line-height
与眼高相同 这是编辑后的代码:
.LegendItem_Eye {
width: $slotWidth;
display: flex;
justify-content: center;
align-items: flex-start; // ← edit (1)
background: #eee;
}
.LegendItem_Text {
padding: 0 3px;
flex: 1;
align-self: flex-start; // ← edit (1)
background: #eaa;
line-height: $fontSize; // ← edit (2)
}
当然,如果图标高度等于行高,它将与第一行“对齐”。
通常,这两件事会有所不同。实际上,您无法在不影响视觉设计的情况下更改行高或图标高度。
因此,解决方案是用高度等于文本行高的弹性容器包裹图标。该容器将使图标垂直居中。如果图标比容器大,那么它只会从顶部和底部溢出。
因此,在您的示例中(为了清楚起见,我只是夸大了高度,您也可以尝试使用非常小的值,例如 8px 并查看它在两种情况下的工作原理)
.LegendItem_Eye {
width: $slotWidth;
display: flex;
justify-content: center;
align-items: center;
background: #eee;
height: 100px; /* <-- set this */
}
.LegendItem_Text {
padding: 0 3px;
flex: 1;
background: #eaa;
line-height: 100px; /* <-- equal to this, no need to set this, just use right value above */
}
请注意,您实际上不需要更改文本行高,只需将眼睛容器高度设置为该值即可。
Fiddle 适用于行高大于图标的情况:http://jsfiddle.net/ofdwemva/
Fiddle 适用于行高小于图标的情况:http://jsfiddle.net/ofdwemva/1/
我找到了解决方案,无需更改文本的
line-height
属性。
flex-start
。center
对齐,这将对齐眼睛本身和我们创建的伪元素。这里是JSFiddle的链接以及我所做的总结:
.LegendItem {
min-height: $itemHeight;
font-size: $fontSize;
margin: 2px 0;
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
align-items: flex-start; // <-- Change this
}
.LegendItem_Eye {
width: $slotWidth;
display: flex;
justify-content: center;
align-items: center;
background: #bbb;
}
.LegendItem_Eye::before { // <-- Add this
content: "A";
width: 0px;
visibility: hidden;
}
.LegendItem_Text {
padding: 0 3px;
flex: 1;
background: #eaa; // <-- Remove align-self
}
这里的很多答案将取决于您的情况 - 当前(错误地)接受的答案只有在您的设计师不介意您破坏行高的情况下才有效,这对大多数人来说都没有好处。
如果您想这样做,最终您的目标是使图标容器与一行文本的高度相同,然后将该容器内的图标对齐以居中。
执行此操作的一个不错的方法是使用与要居中的文本相同的 css 复制一些文本,然后将其隐藏,这将确保容器现在与文本的高度相同。现在您只需将图标居中对齐即可。
这是一个react示例(CSS是相同的)
export function CheckmarkListItem({ point }: Iprops) {
return (
<Div>
<IconContainer>
<SvgWrap size={20} mixin={svgMix}>
<Checkmark />
</SvgWrap>
<HiddenDiv>
<Typo tag="p">Mock text</Typo>
</HiddenDiv>
</IconContainer>
<PointDiv>
<Typo tag="p">{point}</Typo>
</PointDiv>
</Div>
);
}
const Div = styled.div`
display: flex;
text-align: left;
gap: 15px;
${(props) => props.theme.breakpoints.up.md} {
gap: 30px;
}
align-items: flex-start;
`;
const PointDiv = styled.div``;
const IconContainer = styled.div`
display: flex;
align-items: center;
`;
const svgMix = css`
margin: 0;
`;
const HiddenDiv = styled.div`
visibility: hidden;
width: 0;
`;
.LegendItem_Eye {
width: $slotWidth; // keep width
float:left; // float left
line-height:1.3; // define line height
}
这应该是您所需要的全部。 演示。
您可以使用 ufefftransform 属性以及基于存储的图标高度和可以自由选择的无单位文本行高的计算。
.parent {
--text-line-height: 1.5;
--icon-height: 24px;
display: flex;
align-items: flex-start;
}
.icon {
height: var(--icon-height);
width: var(--icon-height); // Just assuming it's a square icon
}
.text {
line-height: var(--text-line-height);
transform: translateY(calc(var(--icon-height) / 2 - 0.5em * var(--text-line-height)))
}
translateY()
中的计算通过从图标高度中减去文本实际高度(当前font-size
与em
单位和line-height
的组合)并将其除以2来确保正确对齐。
通过这种方法,您还可以更改
--text-line-height
属性或调整文本 font-size
,而不影响垂直对齐。
请记住,这会将文本元素稍微移动到其父元素之外。
我不确定是否有一种优雅的方法来做到这一点
flex
但我可以为您提供相同的破解,据我猜测,这不会影响任何其他元素:
您可以为 font-awesome.css 添加自定义样式
.fa{
position: absolute;
top: 0;
left: 0;
text-align:center;
padding:3px;
}
对于您的自定义样式,您可以这样做:
.LegendItem_Eye {
width: $slotWidth;
display: flex;
justify-content: center;
align-items: center;
background: #eee;
position: relative; /* Added this new rule */
}
我知道这不是正确的解决方案,但你可以尝试一下,除非它会损害其他元素。 :)