将图标垂直对齐第一行文本的中心
Posted
技术标签:
【中文标题】将图标垂直对齐第一行文本的中心【英文标题】:Align icon vertically to the center of the first line of text 【发布时间】:2015-11-14 01:57:54 【问题描述】:这是具有align-items: center
属性的眼睛。它们适用于单行文本,适用于多行文本:
这是align-items: baseline
(或flex-start
)的眼睛。它们更适合多行文本,但并不适合所有人,因为我想将眼睛对准文本第一行的中心:
我想要实现的是:
看到眼睛图像如何在文本的第一行居中?
是否可以使用 flexbox 属性优雅地做到这一点,而不使用填充或边距?
(这是一个简化的例子。在真正的问题中我不想引入填充,因为它会影响其他项目。)
这里是 jsfiddle 玩:http://jsfiddle.net/sqp1wdap/
【问题讨论】:
【参考方案1】:这里的很多答案将取决于您的情况 - 当前(并且错误地)接受的答案只有在您的设计师不介意您砍掉对大多数人不利的行高时才有效。
如果你想最终做到这一点,你的目标是让图标容器与一行文本的高度相同,然后将此容器内的图标对齐以居中。
这样做的一个不错的方法是复制一些与您想要居中的文本具有相同 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;
`;
【讨论】:
【参考方案2】:当然,如果图标高度等于行高,它将与第一行“对齐”。
通常,这两件事会有所不同。在不影响视觉设计的情况下,您实际上无法更改行高或图标高度。
因此,解决方案是使用高度等于文本行高的 flex 容器包装图标。这个容器将做图标的垂直居中。如果图标比容器大,那么它就会从顶部和底部溢出。
所以在你的例子中(我只是为了清楚起见夸大了高度,你也可以尝试使用非常小的值,比如 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/
小提琴适用于行高小于图标的情况:http://jsfiddle.net/ofdwemva/1/
【讨论】:
最佳答案...其他解决方案非常长,但我不知道为什么必须设置高度,你不能只使用 flex-direction 列吗?【参考方案3】:我找到了解决方案,而无需更改文本的 line-height
属性。
-
与之前的oluckyman's answer 相同,将眼睛和文本都对齐到
flex-start
。
在 Eye 上添加隐藏的伪元素,类似于文本的高度。
对 Eye 使用 center
对齐,这将对齐 Eye 本身和我们创建的伪元素。
这是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
它看起来像this。
【讨论】:
这不是只有在图标小于行高时才有效吗?【参考方案4】:.LegendItem_Eye
width: $slotWidth; // keep width
float:left; // float left
line-height:1.3; // define line height
这应该是您需要的全部。 Demo.
【讨论】:
【参考方案5】:(2017 年 7 月)虽然解决方案(和其他答案)起到了作用,但他们都错过了最直接、最容易修改的答案。
首先将* outline: 1px dashed
添加到您原始的、未修改的Fiddle 中,您几乎可以看到解决方案正盯着您,因为元素.LegendItem_Eye
占据了父容器的整个高度。
由于 眼睛 图标是方形的,您只需将 height: $slotWidth
添加到 .LegendItem_Eye
和 flex 即可。
因为图标现在被限制在一个小方块内,flex 根本没有空间在它的容器中放置 center
它并根据父规则 @987654328 将其显示在 start
@。
Fiddle。
加法
实际上,图标仍以.LegendItem_Eye
为中心,因为它有$slotWidth = $itemHeight = $fontSize * 1.3;
可移入,但我们将其限制在$slotWidth
正方形而不是整个父高度。
逻辑
-
flexed 项目的默认值为
align-self: stretch
父.LegendItem
有规则align-items: stretch
父.LegendItem
有规则justify-content: flex-start
子 align-self
优先于父 align-items
子 .LegendItem_Eye
没有设置高度值
子.LegendItem_Eye
有规则align-items: center
眼睛-icon 是孩子.LegendItem_Eye
的孩子
eye-icon 是一个字体字符,就像字母表中的任何其他字符一样,所以它只占用给定的$fontSize
空间并采用fa fa-eye
字体设置
导致
-
child
.LegendItem_Eye
因为 1, 2, 4 而增长到父高度
和 5
眼睛-图标位于.LegendItem_Eye
的中心,因为是 6、7 和 9
解决方案
用值$slotWidth
约束孩子.LegendItem_Eye
的高度
因为.LegendItem_Eye
的3个孩子眼睛-图标会向上移动
所有规则 1 到 8(规则 5 除外)仍然有效,只是由 $slotWidth
【讨论】:
但是justify-content
是水平对齐图标,而不是垂直对齐,所以我不确定这是否解决了问题。
检查小提琴。并且图标位于“row nowrap”元素内,所以它可以做的就是“向上”...
之前图标在自己的元素空间中居中,这是整个父级高度,但现在它在父级内部移动,这就是区别。
为什么是 $fontSize * 1.3? 1.3从何而来?
这是在元素周围添加一些“填充”的巧妙技巧。您现在所要做的就是将其居中。 (不是我的作品,顺便说一句,在原版中)【参考方案6】:
我找到了解决办法: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)
下面是它的样子:
【讨论】:
假设您可以确定行高与文本的高度相同,但对于 99% 而言,这不是设计的内容...... 不是一个很好的解决方案。 line-height 不应该依赖于 icon 的大小,应该留给设计师来决定。请参阅@gztomas 的回答以获得更灵活的解决方案。如果您的图标是字体大小的两倍,则此解决方案根本不起作用。【参考方案7】:我不确定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 */
我知道这不是正确的解决方案,但您可以尝试一下,除非它会损害其他元素。 :)
jSFiddle
【讨论】:
感谢您的回答。有趣的解决方案。但我找到了我需要的东西:***.com/a/32119917/823778以上是关于将图标垂直对齐第一行文本的中心的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Bootstrap 4 中将 Font-Awesome 图标与一行文本垂直对齐?