在浮动元素旁边垂直居中

问题描述 投票:0回答:2

我想知道是否有一个纯粹优雅的CSS解决方案,当浮动元素的高度高于浮动元素时,它可以在其下方获取浮动元素旁边的文本,但当其高度低于浮动元素时,也可以居中。接下来的两张图片展示了我想要获得的内容:

这两种情况都有编码版本:

.float {
  float: right;
  height: 80px;
  width: 500px;
  background-color: blue;
}

#with_text_centered {
  height: 80px;
  position: relative;
}

#with_text_centered p {
  position: relative;
  top: 50%;
  transform: translate(0, -50%);
}
<h1>WITH TEXT UNDER THE FLOAT</h1>

<div class=ctn>
  <div class=float></div>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>

<h1>WITH TEXT CENTERED</h1>

<div id="with_text_centered">
  <div class=float></div>
  <p>Lorem ipsum.</p>
</div>

我可以分别执行每个操作,但无法找到同时执行这两个操作的方法(出于响应式设计目的)。我目前找到的唯一解决方案需要 js(使用 ResizeObserver),在这种情况下必须使用一些 js,这对我来说很奇怪,而且接缝非常简单。

此外,我肯定不希望在任何地方都很难定义高度。在我的示例中,不幸的是,我定义了 80px 的高度。事实上,在我使用 js 的版本中,当文本低于浮动元素时,我会切换到 Flexbox。在我看来,将文本居中更容易、更优雅。当我这样做时,浮动将被忽略(使 Flex 忽略浮动)。

css css-float
2个回答
0
投票

我将为那些面临类似问题的人提供答案 - 没有 css 解决方案。因为具有

float
属性的元素会从普通流中删除。
正如提问者指出的,一个简单的 javascript 解决方案 - 观察浮动的高度和内容。像这样的东西:

window.addEventListener('load', centeContent);
window.addEventListener('resize', centeContent);

function centeContent() {
  document.querySelectorAll('.container').forEach(el => {
    const imgHeight = el.querySelector('img')?.clientHeight || 0;
    el.style.removeProperty('--display');
    el.style.setProperty('--min-height', imgHeight);
    if(el.offsetHeight <= imgHeight) {
      el.style.setProperty('--display', 'flex');
    }
  })
}
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.container {
  display: flow-root;
  max-width: 400px;
  margin-bottom: 16px;
}

.container img {
  float: right;
  max-width: 50%;
  margin-left: 16px;;
}

.content {
  display: var(--display, block);
  min-height: calc(var(--min-height) * 1px);
  flex-direction: column;
  justify-content: center;
}
<div class="container">
  <img src="https://picsum.photos/200/120" alt="">
  <div class="content">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugit, a asperiores officia amet rerum nesciunt!
  </div>
</div>
<div class="container">
  <img src="https://picsum.photos/200/120" alt="">
  <div class="content">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia, dolores id odit. Deserunt, quae iste doloremque eligendi earum provident tenetur aperiam necessitatibus cumque nemo mollitia voluptas et aliquid veritatis reiciendis veniam ab odio repellat accusamus modi quasi nam corrupti eum? Dolor, nesciunt repellat voluptas eos nostrum quasi ipsum! Veritatis, quo!
  </div>
</div>


0
投票

使用容器查询,您可以接近这种行为。然而,仅根据内容高度来调整元素是不可能的。为此,先生,您需要一些 js。

更多信息:https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_containment/Container_queries

<section>
<div class="wrapper">
  <div class="section-right">
    <p>Fixed height block.</p>
  </div>
  <div class="section-left">
    <p>The way they make shows is, they make one show. That show's called a pilot. Then they show that show to the people who make shows, and on the strength of that one show they decide if they're going to make more shows. Some pilots get picked and become television programs. Some don't, become nothing. She starred in one of the ones that became nothing. Your bones don't break, mine do. That's clear. Your cells react to bacteria and viruses differently than mine. You don't get sick, I do. That's also clear. But for some reason, you and I react the exact same way to water. We swallow it too fast, we choke. We get some in our lungs, we drown. However unreal it may seem, we are connected, you and I. We're on the same curve, just on opposite ends.</p>
  </div>
</div>
</section>
section {
  margin: 0;
  padding: 0;
  container-type: inline-size;
  container-name: section;
}
.wrapper {
  background-color: #eee;
  display: flex;
  align-items: center;
  padding: 1em;
}
.wrapper::after {
  content:"";
  clear: both;
  display: block;
}
.section-left {
  flex: 1;
  order: 1;
  container-type: inline-size;
  container-name: section-left;
}
.section-right {
  background-color: #ddd;
  display: flex;
  flex-direction: column;
  align-content: center;
  justify-content: center;
  min-height: 30vh;
  min-width: 30vw;
  margin: 0 0 .5em .5em;
  padding: 0 2em;
  order: 2;
  container-type: inline-size;
  container-name: section-right;
}
.section-right p {
  margin: 0 auto;
  text-align: center;
}
/* do the things when the things change size */
@container section (width < 825px) {
  .wrapper {
    display: block !important;
  }
  .section-left {
    flex: none;
    width: 100%;
    container-type: normal;
  }
  .section-right {
    float: right;
  }
}

section {
  margin: 0;
  padding: 0;
  container-type: inline-size;
  container-name: section;
}
.wrapper {
  background-color: #eee;
  display: flex;
  align-items: center;
  padding: 1em;
}
.wrapper::after {
  content:"";
  clear: both;
  display: block;
}
.section-left {
  flex: 1;
  order: 1;
  container-type: inline-size;
  container-name: section-left;
}
.section-right {
  background-color: #ddd;
  display: flex;
  flex-direction: column;
  align-content: center;
  justify-content: center;
  min-height: 30vh;
  min-width: 30vw;
  margin: 0 0 .5em .5em;
  padding: 0 2em;
  order: 2;
  container-type: inline-size;
  container-name: section-right;
}
.section-right p {
  margin: 0 auto;
  text-align: center;
}
/* do the things when the things change size */
@container section (width < 825px) {
  .wrapper {
    display: block !important;
  }
  .section-left {
    flex: none;
    width: 100%;
    container-type: normal;
  }
  .section-right {
    float: right;
  }
}
<section>
<div class="wrapper">
  <div class="section-right">
    <p>Fixed height block.</p>
  </div>
  <div class="section-left">
    <p>The way they make shows is, they make one show. That show's called a pilot. Then they show that show to the people who make shows, and on the strength of that one show they decide if they're going to make more shows. Some pilots get picked and become television programs. Some don't, become nothing. She starred in one of the ones that became nothing. Your bones don't break, mine do. That's clear. Your cells react to bacteria and viruses differently than mine. You don't get sick, I do. That's also clear. But for some reason, you and I react the exact same way to water. We swallow it too fast, we choke. We get some in our lungs, we drown. However unreal it may seem, we are connected, you and I. We're on the same curve, just on opposite ends.</p>
  </div>
</div>
</section>
© www.soinside.com 2019 - 2024. All rights reserved.