如何使包裹的文字的背景准确跨过该文字的像素距离?

时间:2018-09-16 15:38:52

标签: html css

我认为这是一个简单的问题,现代CSS可以解决,现在我真的很困惑。我想使父文本的背景准确地跨过最长的文本行左右之间的距离,并均匀地分布在侧面上(这与span元素不同)

很明显,block元素会自动变为100%的宽度,如果不是文本的自动换行机制的行为,则内联块就可以了,这将使边界框的大小为100%,因为它第一次将其换行到下面的行

我模拟了所需的效果,但是这种解决方法有些难看。我对更简单的本机解决方案感兴趣。

提琴+模拟:https://jsfiddle.net/sxmkonLp/20/

普通块元素文字

<div class="container normal">
  <h1 class="fill">Gonna wrap my text around</h1>
</div>

父元素显示:“内联块”(稍微靠近一点)

<div class="container">
  <h1 class="fill inl-blk">Gonna wrap my text around</h1>
</div>

“ span”元素中的文本(更接近我的需要,但没有均匀分布在侧面,取决于每行的长度)

<div class="container">
  <h1>
    <span>Gonna wrap my text around</span>
  </h1>
</div>

所需的结果(使用br和类模拟文本中断)

<div class="container text-span">
  <h1 class="fill2 inl-blk">Gonna<br class="sm4"> wrap<br class="sm3"> my<br class="sm2 sm4"> text<br class="sm1 sm3 sm4"> around</h1>
</div> 

有用于标记的CSS

html, body {
  text-align: center;
  margin: 0;
  padding: 0;
}

.container {
  padding: 10px;
  width: auto;
  background: orange;
  margin: 10px;
}

.container span {
  background: lightgreen;
  padding: 5px;
}

.inl-blk {
  display: inline-block;
}

.fill {
  background: yellow;
}
.fill2 {
  background: blueviolet;
  color: white;
}

.sm1,.sm2,.sm3,.sm4 {display: none;}

@media screen and (max-width: 470px) {
  .sm2 {display: none;}
  .sm3 {display: none;}
  .sm4 {display: none;}
  .sm1 {display: block;}
}
@media screen and (max-width: 350px) {
  .sm1 {display: none;}
  .sm3 {display: none;}
  .sm4 {display: none;}
  .sm2 {display: block;}
}
@media screen and (max-width: 295px) {
  .sm1 {display: none;}
  .sm2 {display: none;}
  .sm4 {display: none;}
  .sm3 {display: block;}
}
@media screen and (max-width: 242px) {
  .sm1 {display: none;}
  .sm2 {display: none;}
  .sm3 {display: none;}
  .sm4 {display: block;}
}

如您在最后一个示例(紫色框)中所见,背景恰好占据了文本边界的空间。问题是在文本自动换行到下面的行中时会发生这种情况

最近我发现了一些发现,例如CSS属性“ box-decoration-break:clone;”。这使span的内容更像是单独的块线,但仍然跨越了单独的线长,因此无法满足我当前的需求。如果我们确切地拥有一些CSS属性,那就太好了。

1 个答案:

答案 0 :(得分:0)

我已经为这个问题开发了非常简单的JS解决方案。最后,几乎每个站点最终都有大量的javascript,因此我认为它是可以忍受的。我们需要的只是这个令人惊叹的包“ css-element-queries”中的“ ResizeSensor”

因此,我们得到一个简单的容器,该容器将h1和div保留在标题内,并带有“ title-bg”类,这将是标题的“虚拟响应背景”。它从显示设置为嵌入式的h1中获取确切的文本宽度。

<div class="container">
  <div class="title">
    <h1>Should I learn Scratch before programming?</h1>
    <div class="title-bg"></div>
  </div>
</div>

CSS出现了,请注意,“。title-bg”是绝对定位的,因此需要transform-50%解决方案以保持居中。另外z-index:h1的1必须是可见的。

.container {
  max-width: 800px;
  min-height: 320px;
  padding: 20px;
  background: #ccc;
  margin: auto;
  text-align: center;
}

.title {
  overflow: hidden;
}

.title h1 {
  display: inline;
  /* background: orange; */
  position: relative;
  z-index: 1;
}

.title-bg {
  background: teal;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

对于JS,我们需要设置ResizeSensor来监听事件。由于某种原因,我无法使其直接与h1元素一起使用(当设置为显示时:inline),因此我将其附加到title div。其余的是从h1.offsetWidth中获取值,这些值正是文本长度的值。 Voilà,准备工作了!

let title = document.querySelector('.title')
let h1 = document.querySelector('.title h1')
let titleBg = document.querySelector('.title-bg')

// fire once on start
titleBg.style.width = `${h1.offsetWidth}px`
titleBg.style.height = `${h1.offsetHeight}px`

// init so it auto fires on element resize
new ResizeSensor(title, ()=> {
    titleBg.style.width = `${h1.offsetWidth}px`
  titleBg.style.height = `${h1.offsetHeight}px`
})

自行尝试:http://jsfiddle.net/ktdfqhzo/52/