【问题标题】:Change text alignement upon flex break在 flex 中断时更改文本对齐方式
【发布时间】:2019-09-17 02:42:58
【问题描述】:

我正在编写一个应该是响应式的表单,也就是说,当浏览器窗口很小时,左侧标签“跳”到顶部(请参阅下面的示例,删除text-align 属性并调整浏览器大小)。

现在,标签文本左对齐时效果很好。 对于可用性问题,我希望标签右对齐(我不希望它们离输入框太远)但是一旦 flex 包装好,我不希望它们再右对齐。

示例代码:https://jsfiddle.net/xhtfqbzL/

.cont {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}
span
{
  flex: 1 0 20vw;
  text-align: right;
  display: inline-block;
  padding-right: 0.5em;
}
input
{
  flex: 1 1 20rem;
  display: inline-block;
}
<div class='cont'>
<span>Label</span>
<input type="text" placeholder="content">
</div>

那么如何实现这个效果呢?

【问题讨论】:

  • 媒体查询可能吗?
  • 我想避免使用媒体查询,因为我不知道要打破什么大小(并且它会改变),我想动态设置大小。

标签: css flexbox text-alignment


【解决方案1】:

这是一个hack要谨慎使用(或根本不使用......)

.cont {
  display: flex;
  flex-wrap: wrap;
  overflow: hidden;
}

.cont:before {
  content: "";
  flex: 1 0 20vw;
  height: 1.2em;
}

span {
  flex: 1 1 20rem;
  position: relative;
}

span:before,
span:after {
  content: attr(data-text);
  position: absolute;
  padding-right: 0.5em;
}

span:before {
  left: 0;
  bottom: 100%;
}

span:after {
  top: 0;
  right: 100%;
}

input {
  width: 100%;
}
<div class='cont'>
  <span data-text="Label">
  <input type="text" placeholder="content">
  </span>
</div>

【讨论】:

  • 我不太喜欢由属性和溢出规则组成的双重标签,因为它会破坏可访问性。感谢您提供的方法,它非常聪明。
【解决方案2】:

现在,我最好的尝试是这样的:

   html, body { padding: 0; margin: 0 }
   .cont
{
    display: flex;
    flex-wrap: wrap;
    flex-direction: row;
}

.cont span, .cont input
{
    display: inline-block;
}

.cont span
{
    box-sizing: border-box;
    text-align: right;
    background: blue;
    flex: 1 0 20rem;
}
@media screen and (max-width: 40rem) { 
    .cont span { text-align: left; }
}

.cont input
{
    background: green;
    flex: 1 1 50vw;
    box-sizing: border-box;
}
<div class='cont'>
    <span>Some Label</span>
    <input type="text" value="Text here">
</div>

我不想进行媒体查询,因为找到断点总是很痛苦(这可能会根据设计更改或设备演变而演变)。在这里,我仍然使用了媒体查询,但 40rem 魔法值是计算出来的,而不是手动选择的。 通常,表单的行项目之一具有固定大小,另一个是相对于视口大小的。在本例中,固定大小为20rem

由于它们是 flex 项目,当它们不能再适合该行时,它们将被换行,即当它们的宽度达到它们的 flex-basis 属性时。

因此,行的宽度为span_width[20rem] + input_width[50% * w] = 100% * w 我推断他们会在100% w = 50% w + 20rem =&gt; 50%w = 20rem =&gt; w = 40rem

所以当视口的宽度小于40rem时,它们会自动换行。

这样做的主要问题是您必须知道此类项目周围的确切边距和填充大小,维护起来确实很痛苦。

另一个不使用媒体查询的解决方案:

   html, body { padding: 0; margin: 0 }
#test
{
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    flex-direction: row;
}
#test p
{
    flex: 0 1 20rem;
    padding:0;
    margin:0;
}
#test p s
{
    width: calc((48vw - 100%) * 5000);
    min-width: 1%;
    max-width: 16rem;
    
    display: inline-block;
    background: salmon;
    height: 1rem;
}
#test p span
{
    background: red;
    padding-right: 0.5rem;
}
#test b
{
    flex: 1 0 50vw;
    background: yellow;
}
<div id="test">
    <p>
        <s></s>
        <span>First</span>
    </p>
    <b>Second</b>
</div>

这样工作:

  1. 标签分为 2 个内联元素、一个分隔符和标签本身。
  2. 垫片使用 Fab Four 技巧,即 width 属性被计算为在 +infinite-infinite 之间振荡,以便受到 min-widthmax-width 的约束。
  3. 断点由 flex 行中的第二项设置(在示例中为window_width:100vw - input_width:50vw):当标签的剩余大小小于行的最小宽度时,使用其max-width 属性并这增加了一个“空格”,将标签元素推到右侧。当 flex 行换行时,左边的大小现在非常大并且高于断点,因此选择了min-width(在我的示例中,我使用了1%,但它可以是0%,也就是说,几乎标签左侧没有“边距”)。

此技术的注意事项是您必须添加一个元素(可能在这里使用::before 伪元素来完成)并且您必须将max-width 设置为小于parent width - label width。 这一点使得这个解决方案很难维护。

【讨论】:

    猜你喜欢
    • 2023-03-24
    • 2018-09-03
    • 2016-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 2016-02-27
    相关资源
    最近更新 更多