Div扩展到某些内容的大小

Ben*_*ton 7 html javascript css jquery

我有一堆div,里面有一个内容div.在内容div中有3个元素,a h1,a p和a span,都是左对齐的.我想要发生的是以下内容:

  • 内容div应垂直和水平居中
  • 内容的div应该是完全一样宽文本h1文本span(以较长者为准),如果上述max-width这些应包
  • p应宽75%作为股利内容而不是对内容div的大小产生影响(实际上是75%一样宽的h1span,以较长者为准)

但是我遇到了以下问题:

  • 问题1:拥有一个long p元素会导致内容div扩展到它,max-width无论h1or 的大小如何span.我尝试使用绝对定位来解决这个问题,但它会破坏div的垂直居中
  • 问题2:有一个长h1元素留下一个空格,其中单词突破2行,使内容div不显示居中

请参阅下面的代码片段,以阐明我所追求的内容以及出现的问题,边界只是为了帮助您了解正在发生的事情.

有没有人知道这是如何可能的?我想坚持使用CSS,因为这些需要响应,尽管如果有一个简单的JS/jQuery解决方案,它将被考虑.

编辑:为了澄清我在这之后的视觉效果是为什么示例好或坏.我还添加了删除边框的功能,以展示我所说的视觉中心的意思:

1)好:内容div适合宽度h1,看起来居中,没有边框作为左右相等的空格h1

2)好:内容div适合宽度,span因为它比它更长h1,看起来居中而没有边界作为左右相等的空间span

问题1:

3)坏:p正在扩展内容div的宽度,看起来向右移动没有边框,因为右边比左边更多.如果p没有扩展div并保持在75%的宽度,这将不会发生

4)改进3但仍然不好:在各种SO问题中发现的潜在修复显示绝对定位会阻止p扩展内容div,但是现在它不是流程的一部分它会扰乱垂直居中

问题2:

5)坏:这里的问题是h1元素,因为它现在比max-width它分成2行更长.但是第一行的末尾和max-widthdiv 的末尾之间的额外空间是保留的,因此当删除边界时它看起来不居中,因为右侧有比左侧更多的空间.h1

6)修复5但不是解决方案:手动断开线(使用a <br>)实现了我需要的外观,因为h1它没有展开到max-width没有边框的中心.这在实际应用中是不可行的,因为div的宽度可能不同

替代JSFiddle链接

function toggleBorders() {
  $('h1, p, span').toggleClass('bordered');
  $('.content').toggleClass('content-bordered');
}
Run Code Online (Sandbox Code Playgroud)
.box-holder {
  display: flex;
  flex-flow: row wrap;
}
.box {
  flex: 0 0 380px;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 350px;
  border: 1px solid blue;
}
.content {
  max-width: 80%;
  position: relative;
}
.content-bordered {
  border: 1px solid red;
}
.bordered {
  border: 1px solid green;
}
p {
  width: 75%;
}
.abs {
  position: absolute;
}
button {
  position: fixed;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="toggleBorders()">Toggle Borders</button>
<div class="box-holder">
  <div class="box">
    <div class="content">
      <h1>1. Example Title</h1>
      <p>Good Example</p>
      <span>Example link to the article</span>
    </div>
  </div>
  <div class="box">
    <div class="content">
      <h1>2. Title</h1>
      <p>Min Width Good Example</p>
      <span>Example link to the article</span>
    </div>
  </div>
  <div class="box">
    <div class="content">
      <h1>3. Example Title</h1>
      <p>But when the description gets too long then it expands the content div</p>
      <span>Example link to the article</span>
    </div>
  </div>
   <div class="box">
    <div class="content">
      <h1>4. Example Title</h1>
      <p class="abs">Setting absolute position avoids expansion but messes up the vertical layout</p>
      <span class="abs">Example link to the article</span>
    </div>
  </div>
   <div class="box">
    <div class="content">
      <h1>5. Also Long Titles Leave White Space</h1>
      <p>This doesn't look centered, see 6</p>
      <span>Example link to the article</span>
    </div>
  </div>
   <div class="box">
    <div class="content">
      <h1>6. Also Long Titles<br>Leave White Space</h1>
      <p>Manually breaking lines fixes this</p>
      <span>Example link to the article</span>
    </div>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

Ben*_*ton 1

所以这两个问题的答案似乎是,如果没有 javascript,你就无法做到这一点。原因是 CSS 盒模型不能以这种方式工作。

为了解决第一个问题,您需要像我尝试的那样使用绝对定位,然后使用 javascript 使用 上的边距为元素创建一个空间h1,如下所示:

$(document).ready(function() {
    function alignDescriptions() {
    var pmargin = 10 * 2;
    $('.abs').each(function() {
      var pheight = $(this).height();
      $(this).css('bottom', pmargin);
      $(this).siblings('h1').css('margin-bottom', pheight + pmargin);
    });
  }
});
Run Code Online (Sandbox Code Playgroud)

这解决了使用时的垂直居中问题,absolute因此问题 1 得到解决。

为了解决第二个问题,以下答案提供了一种解决方案:/sf/answers/2327245511/

我相信简单地使用这个,但也使用 的宽度作为span最小值可能会解决这两个问题,因为我实际上会强制宽度为正确的大小,因此拥有 75% 宽度的p元素不会成为问题。

遗憾的是这种功能并不在 CSS 规范中。

编辑:正如怀疑的那样,第二个选项的改编实际上消除了元素绝对定位的需要p。这是适用于我的实际案例的 jQuery 代码:

$('h1').each(function() {
  // references to elements
  var hElem = $(this);
  var pElem = hElem.siblings('p');
  var sElem = hElem.siblings('span');
  // store starting values
  var sWidth = sElem.width();
  var hHeight = hElem.height();
  var hWidth = hElem.width();
  // reduce width until less than span width
  // or until height of h1 changes
  for (var testWidth = hWidth - 1; testWidth > 0; testWidth--) {
    if (testWidth <= sWidth) {
      testWidth = sWidth - 1;
      break;
    }
    hElem.width(testWidth);
    if (hElem.height() !== hHeight) break;
  }
  // set h1 width
  hElem.width(++testWidth);
  // if h1 still overflows (long word) use that instead
  if (hElem[0].scrollWidth > hElem.width()) {
    testWidth = hElem[0].scrollWidth;
    hElem.width(testWidth);
  }
  // set p element to 75% width
  pElem.width(testWidth * 0.75);
});
Run Code Online (Sandbox Code Playgroud)