垂直对齐位于浮动同级旁边的 Div 中的多行文本

Posted

技术标签:

【中文标题】垂直对齐位于浮动同级旁边的 Div 中的多行文本【英文标题】:Vertically Align Multi-line Text in a Div Sitting Next to Floated Sibling 【发布时间】:2019-07-28 19:14:26 【问题描述】:

我有两个兄弟 div。一个占据父级的 70% 的宽度并浮动到左侧。它有一个clip-path 来创建一个不规则的多边形。同级 div 的宽度为父级的 100%。我在浮动 div 上放置了一个 shape-outside 属性,以允许同级中的文本以遵循多边形对角线的方式换行。

我无法解决的问题是非浮动兄弟中的文本是动态的,可以是单行或多行。我想确保文本在非浮动 div 中保持垂直居中,并遵循shape-outside 行。

Flex、网格和表格似乎破坏了文本跟随shape-outside 行的能力。 Here is a link to a code pen with what is currently set up.

main 
  height: 25rem;
  width: 95vw;
  margin: auto;


#main-left 
  background-image: url('https://drive.google.com/uc?id=1NeUyxUgp7I56mTpmzYIUXbQilRnd0dAK');
  background-size: cover;
  background-position: center;
  width: 75%;
  height: 100%;
  float: left;
  -webkit-clip-path: polygon(0 0, 95% 0, 50% 100%, 0% 100%);
  clip-path: polygon(0 0, 95% 0, 50% 100%, 0% 100%);
  shape-outside: polygon(0 0, 97% 0, 50% 100%, 0% 100%);


#main-right 
  width: 100%;
  height: 100%;
<main>
  <div id="main-left"></div>
  <div id="main-right">
    <p>Play with the angles. This is unplanned it really just happens. A fan brush is a fantastic piece of equipment. Use it. Make friends with it. We have no limits to our world. We're only limited by our imagination. The very fact that you're aware of
      suffering is enough reason to be overjoyed that you're alive and can experience it. We don't have anything but happy trees here. This painting comes right out of your heart. Any little thing can be your friend if you let it be. Learn when to stop.
      You can create beautiful things - but you have to see them in your mind first. There's not a thing in the world wrong with washing your brush. These little son of a guns hide in your brush and you just have to push them out.</p>
  </div>
</main>

【问题讨论】:

【参考方案1】:

我们可以考虑使用position:absolute 的技巧,但使用relative 因为绝对不会起作用,而相对会在这里做同样的事情,因为你的元素已经放在顶部,所以当使用top:50%;transform:translateY(-50%) 时,我们将有一个部分垂直居中如下:

main 
  height: 25rem;
  margin: auto;


#main-left 
  background-image: url('https://drive.google.com/uc?id=1NeUyxUgp7I56mTpmzYIUXbQilRnd0dAK');
  background-size: cover;
  background-position: center;
  width: 75%;
  height: 100%;
  float: left;
  -webkit-clip-path: polygon(0 0, 95% 0, 50% 100%, 0% 100%);
  clip-path: polygon(0 0, 95% 0, 50% 100%, 0% 100%);
  shape-outside: polygon(0 0, 97% 0, 50% 100%, 0% 100%);


#main-right 
  width: 100%;
  height: 100%;


p 
  position:relative;
  top:50%;
  transform:translateY(-50%);
<main>
  <div id="main-left"></div>
  <div id="main-right">
    <p>Play with the angles. This is unplanned it really just happens. A fan brush is a fantastic piece of equipment. Use it. Make friends with it. We have no limits to our world. We're only limited by our imagination. The very fact that you're aware of
      suffering is enough reason to be overjoyed that you're alive and can experience it. We don't have anything but happy trees here. This painting comes right out of your heart. Any little thing can be your friend if you let it be. Learn when to stop.
      You can create beautiful things - but you have to see them in your mind first. There's not a thing in the world wrong with washing your brush. These little son of a guns hide in your brush and you just have to push them out.</p>
  </div>
</main>

现在的问题是翻译会创建一个偏移量,您需要用另一个翻译来纠正它。这是一个插图,可以更好地理解如何解决问题以及我们需要应用什么翻译:

红色箭头是我们所做的翻译,由top:50%;transform:translateY(-50%) 完成。 top 相对于容器的高度 (25rem) 并转换为元素的高度,因此我们将拥有 12.5rem - h/2

如果我们考虑由蓝线定义的角度,我们将得到tan(angle) = G/R,其中G 是我们正在寻找的距离,R 是我们已经定义的距离。

对于相同的角度,我们还有tan(angle) = W / H,其中H 是容器高度,W 是由clip-path 移除的底部部分,即宽度的50%(稍微少一点,但让我们让它变得简单) 所以我们将拥有整个屏幕宽度的 75% 的 50%。我们可以将其近似为37.5vw 因此tan(angle) = 37.5vw / 25rem

所以G = (37.5vw/25rem)*(12.5rem - h/2) = 18.75vw - (18.75vw/25rem)*h = 18.75vw*(1 - h/25rem)

很明显,我们无法使用纯 CSS 来表示这个值,因此您需要考虑 JS 来动态更新 translateX 的值以纠正对齐:

// to make it easy we will consider font-size: 16px thus 25rem = 400px
var p= document.querySelector('p');
var h = (p.offsetHeight/400 - 1); /*we need a negative translation*/
var translateX = "calc(18.75vw * "+h+")";  
p.style.transform="translate("+translateX+",-50%)";

window.onresize = function(event) 
   
  h = (p.offsetHeight/400 - 1);
  translateX = "calc(18.75vw * "+h+")";  
  p.style.transform="translate("+translateX+",-50%)";
  
;
main 
  height: 25rem;
  margin: auto;


#main-left 
  background-image: url('https://drive.google.com/uc?id=1NeUyxUgp7I56mTpmzYIUXbQilRnd0dAK');
  background-size: cover;
  background-position: center;
  width: 75%;
  height: 100%;
  float: left;
  -webkit-clip-path: polygon(0 0, 95% 0, 50% 100%, 0% 100%);
  clip-path: polygon(0 0, 95% 0, 50% 100%, 0% 100%);
  shape-outside: polygon(0 0, 97% 0, 50% 100%, 0% 100%);


#main-right 
  width: 100%;
  height: 100%;


p 
  position:relative;
  top:50%;
  transform:translateY(-50%);
<main>
  <div id="main-left"></div>
  <div id="main-right">
    <p>Play with the angles. This is unplanned it really just happens. A fan brush is a fantastic piece of equipment. Use it. Make friends with it. We have no limits to our world. We're only limited by our imagination. The very fact that you're aware of
      suffering is enough reason to be overjoyed that you're alive and can experience it. We don't have anything but happy trees here. This painting comes right out of your heart. Any little thing can be your friend if you let it be. Learn when to stop.
      You can create beautiful things - but you have to see them in your mind first. There's not a thing in the world wrong with washing your brush. These little son of a guns hide in your brush and you just have to push them out.</p>
  </div>
</main>

【讨论】:

感谢您为此所做的工作,@TemaniAfif。随着我继续努力,最好的解决方案似乎根本不是弄乱 CSS,而是通过在我的 JS 中添加一个函数 function mainSpacing() let mainHeight = document.querySelector('#landscape').offsetHeight; let rightMainPar = document.querySelector('#rightMainP').offsetHeight; document.querySelector('#main-right').style.padding = $(mainHeight - rightMainPar)/2px 0 0 0@987654346 @ 然后在正文调整大小时添加对该函数的调用。 @JohnMeade 是的,还有一个关于填充的想法;)顺便说一下,你只能设置 paddingTop。 @JohnMeade 只需注意调整填充可能会导致性能问题,因为您将在每次调整大小时更改 DOM,使用转换时不喜欢。这就是我采用这种方式的原因

以上是关于垂直对齐位于浮动同级旁边的 Div 中的多行文本的主要内容,如果未能解决你的问题,请参考以下文章

如何垂直对齐浮动图像旁边的文本?

根据浮动图像的高度垂直对齐div中的文本

在浮动 div 附近垂直对齐文本

CSS 使用css在浮动div中垂直对齐文本

在 Flutter 中对齐多行 TextField 中的提示文本

垂直居中 <span> 文本,位于更大的 <span> 旁边,都在 <div> 内