为什么我不能正确包装这个跨度?

时间:2017-03-13 20:04:54

标签: html css css3 flexbox

在下面的HTML(JSFiddle here)中,文本“为什么不会这个文本换行”只有在宽度太小以至于它已经开始剪切文本的一部分时才会换行。然后它包裹起来。

注意我想要的行为是包含要作为单个项目包装的文本的块,而不是文本开始逐字包装。请注意,它实际上确实有效 - 但只有当宽度足够小以至于没有前导图像时它才会被包裹,它才起作用。如果我删除了前导图像,它会按预期工作。

有没有办法在前导图像就位的情况下获得所需的包装行为?

#main-toolbar {  
    height: 140px;
    white-space: nowrap; 
    overflow:hidden;
    width: 100%;

}

#main-toolbar-text{
    height: initial;
    display:inline-block;
    color: #2196f3;
    line-height: 70px;
}

.test{
    border: solid red 1px;
}
.profile-toolbar-user-wordmark{
    display: inline-block;
    white-space: normal;
    overflow: initial;

}

.profile-toolbar-wordmark{
    width: 90px;
}

.profile-toolbar-logoicon{
    width: 90px;
}

.profile-toolbar-icon{
    display: inline-block;
    vertical-align: top;
    overflow: visible;
    white-space: nowrap;
}
<div id="main-toolbar" class="test" >
    
    <span class="profile-toolbar-icon test"><img class="profile-toolbar-logoicon" src="https://pixy.org/images/placeholder.png"></span>
    <span class="profile-toolbar-user-wordmark test">
        <span class="profile-toolbar-icon">
            <img class="profile-toolbar-wordmark" src="https://pixy.org/images/placeholder.png">
        </span> 
        <span id="main-toolbar-text">
            Why won't this text wrap?
        </span>
    </span>       
</div>

2 个答案:

答案 0 :(得分:1)

这里最简单的解决方案是使用display: flex。这是一个guide to flexbox。您应该了解flex在使用之前的工作原理,因为它带有许多与块和内联显示不同的内置行为。

如果你不想使用flex和/或你只是想知道为什么这个问题仍在发生,请继续阅读:

由于您没有在包含文本的块上设置任何宽度(或最小/最大宽度)并使用display: inline-block,因此块的宽度隐式为100%。由于前导图像宽度为90px,因此将包含文本的块向右偏移90px。

基本上,前导图像+包含文本的块占用的宽度实际上等于100%+ 90px,因此浏览器认为在应该包含包含文本的块之前还有额外的90px空间,实际上额外的90px被削减,因为它超过了外部div的100%宽度。这就是为什么包装仅在宽度足够小以至于包裹时没有前导图像时才起作用的原因。

为了解决这个问题(没有flex),你可以设置max-width来减去前导图像的额外宽度,在这种情况下是90px:

.profile-toolbar-user-wordmark {
    display: inline-block;
    white-space: normal;
    overflow: initial;
    max-width: calc(100% - 90px); /* 90px in this case, in general it should be whatever the width of the leading image is */
}

一个微妙的警告:取决于在前导图像周围是否有边框/边距/填充,您可能需要调整减去的宽度以解决该问题。即如果前导图像的边距为8px,则需要将max-width设置为calc(100% - 98px)。如果前导图像的边距为8px,边距为8px,则max-width需要为calc(100% - 106px)。左/右边框,边距和填充都会影响这一点。

由于上述情况,您可能会注意到,在您的情况下将max-width设置为calc(100% - 90px),当您调整大小时,仍然会发生一点点剪裁(几个像素值)在文本开始包装之前。这是因为你应用了红色边框,增加了2px(左边1px,右边1px),以及前导图像和包含文本的块之间的空间(由代码中的换行符引起)两个跨度)。不幸的是,没有什么好方法可以知道空格字符的宽度是什么,因为它因浏览器和字体大小而异。因此,要将包装修复为像素完美,您需要将max-width设置为calc(100% - 92px)并删除空格(remove spaces between inline block elements有多种方式)。如果您仍然希望元素之间有一些空白区域,那么您可以设置一个边距(只需记住在max-width计算中考虑该边距)。

最后:如果不使用flex或上面的硬编码CSS,你可以用JQuery来动态设置CSS,如果你真的需要(即如果你不能硬编码前导图像元素的宽度,或者如果你真的不想摆脱那个空间):

<span id="your-id" class="profile-toolbar-user-wordmark test">...</span>

let $yourElement = $("#your-id");
let offsetLeft = $yourElement.offset().left - $yourElement.parent().offset().left;
$yourElement.css("max-width", `calc(100% - ${offsetLeft}px)`);

答案 1 :(得分:1)

我四处乱转,发现没有HTML解决方案。

但是如果你可以改变HTML结构,你可以使用flexbox实现所需的结果:

&#13;
&#13;
#main-toolbar {
  display: flex;
  align-items: start;
  min-height: 90px;
  width: 100%;
}

.test {
  border: solid red 1px;
}

.profile-toolbar-wordmark,
.profile-toolbar-logoicon {
  width: 90px;
  height: 90px;
  margin-right: 5px;
  flex: 0 0 initial;
}

.wrap_right {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
}

#main-toolbar-text {
  display: inline-block;
  color: #2196f3;
}
&#13;
<div id="main-toolbar" class="test">

  <img class="profile-toolbar-logoicon" src="https://pixy.org/images/placeholder.png">
  <div class="wrap_right">
    <img class="profile-toolbar-wordmark" src="https://pixy.org/images/placeholder.png">
    <span id="main-toolbar-text">
    Why won't this text wrap?
  </span>
  </div>
</div>
&#13;
&#13;
&#13;