CSS中的基本垂直中心在浮动元素上表现异常

Posted

技术标签:

【中文标题】CSS中的基本垂直中心在浮动元素上表现异常【英文标题】:Basic vertical center in CSS behaving strangely on floated element 【发布时间】:2017-07-07 13:14:35 【问题描述】:

所以我已经接受了这 3 个 CSS 规则,几乎总是垂直居中任何块级元素:

  .vertically-center 
    position: relative;
    top: 50%;
    transform: translateY( -50% );
  

它经常工作。但在我正在构建的这种特殊布局的情况下,它会将元素推得太高(部分离开屏幕),我不知道为什么。

这是网页的外观之前将我的vertically-center 类添加到我的portrait-container div:

而这段代码sn-p就是将vertically-center类添加到portrait-container div之后的样子:

.clearfix:after 
  content: "";
  display: block;
  clear: both;

.vertically-center 
  position: relative;
  top: 50%;
  transform: translateY( -50% );


body 
  overflow: hidden;

main 
  padding-top: 50px;
  background: #fafafa;
  text-align: left;

.portrait-container 
  float: left;

img 
  width: 150px;
  border-radius: 50%;

.about-container 
  width: 70%;
  float: right;
<main class="clearfix">
  <div class="portrait-container vertically-center">
    <img src="http://i.imgur.com/Eb5sRZr.jpg" >
  </div>

  <div class="about-container">
    <h3>About</h3>
    <p>
      Hi, I'm John Lesko! This is my art portfolio where I share all 
      of my favorite work. When I'm not creating things, I enjoy excercising,
      playing video games, drinking good Kool Aid, and more.
      
      <br><br> If you'd like to follow me on Twitter, my username is 
      <a href="http://twitter.com">@jletsgo</a>.
    </p>
  </div>
</main>

我只希望图像容器垂直居中,而不管其父级的高度如何。帮助?检查元素没有给我任何见解。

编辑:只是为了展示过去这对我来说是如何工作的。这是一个 jsfiddle:https://jsfiddle.net/9kyjt8ze/4/。为什么它在那儿对我有用而不在这儿对我有用?

相关问题:What does top: 50%; actually do on relatively positioned elements?

【问题讨论】:

【参考方案1】:

你的 CSS 还不错,但我没有接受它。所以这是另一种解决方法,也许它也有帮助。它始终将图像垂直居中,无论右侧的box 有多少文本。彩色边框只是为了帮助显示盒子大小的视觉效果。

* 
  box-sizing: border-box;


.portrait-container 
  position: relative;
  margin: 20px 0;


.portrait-container:after 
  content: '';
  display: block;
  clear: both;


.portrait-container img 
  position: absolute;
  top: calc(50% - 80px); /* 50% from top minus half img height*/
  width: 150px;
  height: 160px;
  border-radius: 50%;
  float: left;


.portrait-container 
  border: solid 2px orange;


.portrait-container .about-container 
  border: solid 2px green;
  padding: 0 50px;
  margin-left: 150px;        /* this elements should be at least 150px away from left side */
  width: calc(100% - 150px); /* the max width this element should have to be placed */
                             /* next to the image is the total width(100%) - the image width  */
<main>
  <div class="portrait-container">
    <img src="http://i.imgur.com/Eb5sRZr.jpg" >

    <div class="about-container">
      <h3>About</h3>
      <p>
        Hi, I'm John Lesko! This is my art portfolio where I share all 
        of my favorite work. When I'm not creating things, I enjoy excercising,
        playing video games, drinking good fruit punch, and more.

        <br><br> If you'd like to follow me on Twitter, my username is 
        <a href="http://twitter.com">@jletsgo</a>.
      </p>
    </div>
  </div>
</main>

<main>
  <div class="portrait-container">
    <img src="http://i.imgur.com/Eb5sRZr.jpg" >

    <div class="about-container">
      <h3>About</h3>
      <p>
        Hi, I'm John Lesko! This is my art portfolio where I share all 
        of my favorite work. When I'm not creating things, I enjoy excercising,
        playing video games, drinking good fruit punch, and more.

        <br><br> If you'd like to follow me on Twitter, my username is 
        <a href="http://twitter.com">@jletsgo</a>.
      </p>
      <p>
        Hi, I'm John Lesko! This is my art portfolio where I share all 
        of my favorite work. When I'm not creating things, I enjoy excercising,
        playing video games, drinking good fruit punch, and more.

        <br><br> If you'd like to follow me on Twitter, my username is 
        <a href="http://twitter.com">@jletsgo</a>.
      </p>
    </div>
  </div>
</main>

【讨论】:

【参考方案2】:

更新

编辑:只是为了展示这在过去一直对我有用。这是一个 jsfiddle:https://jsfiddle.net/9kyjt8ze/4/。为什么它在那儿对我有用而不在这儿呢?

黑色圆圈是 Fiddle 中唯一的元素,没有障碍物。在您遇到问题的代码中,您有许多元素阻碍或包裹在其他元素周围。如果您开始剥离层,您的规则集将起作用。或者您可以根据代码片段 1 添加一个属性并更改另一个属性。


一个重要提示 relative 元素实际上占据了原来的位置,所以如果给定一个 left:40px看起来向左移动了 40px,但实际上它仍然占据它所在位置右侧 40px 的空间。所以relative 元素并没有真正处于与static 元素不同的流程中。因此它们受到static 布局的影响和影响,它只是不明显通常因为它们与z-index 叠加。

Snippet 2 是一个交互式演示,我想这可能有助于更好地解释事情。


3 CSS 规则集是垂直对齐元素的常用方法,但它最初是position: absolute 而不是position:relative,如果我没记错的话,它必须在另一个positioned 元素中。

参考

Specific Ruleset

W3Schools

MDN

解决方案

.vertically-center 
  /* Changed to absolute from relative */
  position: absolute;
  top: 50%;
  transform: translateY( -50% );

main 
  /* Added position: relative */
  position: relative;
  padding-top: 50px;
  background: #fafafa;
  text-align: left;

片段 1

.vertically-center 
  position: relative;
  top: 50%;
  transform: translateY( -50%);


body 

main 
  padding-top: 50px;
  overflow: scroll;
  background: #fafafa;
  text-align: left;


img 
  width: 150px;
  border-radius: 50%;
  float: left;


.about 
  width: calc(100% - 150px);
  float: right;
<main class="clearfix">

  <img src="http://i.imgur.com/Eb5sRZr.jpg"  class="vertically-center">


  <article class="vertically-center about">
    <h3>About</h3>
    <p>
      Hi, I'm John Lesko! This is my art portfolio where I share all of my favorite work. When I'm not creating things, I enjoy excercising, playing video games, drinking good Kool Aid, and more.</p>

    <p>If you'd like to follow me on Twitter, my username is
      <a href="http://twitter.com">@jletsgo</a>.
    </p>
  </article>
</main>

片段 2

$('#b1').click(function() 
  $('body').toggleClass('R S');
);

$('#b2').click(function() 
  $('#N1,#N2,#N3').toggleClass('N M');
);

$('input[id$="2"]').on('input', function() 
  var grp = "." + $(this).attr('class');
  var num = parseInt($(this).val(), 10);
  grp !== '.S' ? $('section' + grp).css('left', num + '%') : $('section.S').css('margin-left', num + '%');
);

$('input[id$="3"]').on('input', function() 
  var grp = "." + $(this).attr('class');
  var num = parseInt($(this).val(), 10);
  grp !== '.S' ? $('section' + grp).css('top', num + '%') : $('section.S').css('margin-top', num + '%');
);
html,
body 
  height: 100%;
  width: 100%;


body 
  overflow: scroll;
  font: 400 12px/1.2 Consolas;


section 
  width: 50px;
  height: 150px;
  border: 2px dashed grey;
  text-align: center;
  color: white;


.R 
  position: relative;
  background: rgba(0, 0, 255, .3)


.A 
  position: absolute;
  background: rgba(255, 0, 0, .3)


.F 
  position: fixed;
  background: rgba(0, 255, 0, .3)


.S 
  position: static;
  background: rgba(122, 122, 0, .3)


.N 
  position: absolute;
  background: yellow;
  color: blue;


.M 
  position: relative;
  background: black;
  color: yellow;


#R1 
  left: 20%;
  top: 3%;
  z-index: 1;


#A1 
  left: 42%;
  top: 44%;
  z-index: 2;


#F1 
  right: 20%;
  top: 44%;
  z-index: 3;


#S1 
  margin-left: 0;
  margin-top: -28%;


#N1 
  bottom: 0;
  right: 0;
  width: 25px;
  height: 80px;
  z-index: 4;


input 
  width: 6ex;
  position: static !important;


button 
  font: inherit;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body class='S'>
  <fieldset>
    <button id='b1'>Body Relative/Static</button>
    <button id='b2'>Nested Absolute/Relative</button>
    <br><br> RLeft
    <input id='R2' class='R' type='number' value='20'> RTop
    <input id='R3' class='R' type='number' value='3'> ALeft
    <input id='A2' class='A' type='number' value='44'> ATop
    <input id='A3' class='A' type='number' value='44'><br> FLeft
    <input id='F2' class='F' type='number' value='64'> FTop
    <input id='F3' class='F' type='number' value='44'> SLeft
    <input id='S2' class='S' type='number' value='0'> STop
    <input id='S3' class='S' type='number' value='-28'><br> NLeft
    <input id='N2' class='N' type='number' value='45'> NTop
    <input id='N3' class='N' type='number' value='45'>

  </fieldset>

  <section id='R1' class='R'>RELATIVE
    <section id='N1' class='N'>N<br>E<br>S<br>T<br>E<br>D</section>
  </section>
  <section id='A1' class='A'><br><br><br>ABSOLUTE</section>
  <section id='F1' class='F'><br><br>FIXED</section>
  <section id='S1' class='S'><br><br><br><br><br>STATIC</section>
</body>

【讨论】:

有趣,谢谢。似乎可以工作,但我以前从未使用过absolute 定位或将其放入其他定位元素中。我的代码中有一些东西破坏了我原来的做法。 顶部有 50px 的内边距? 是的,但是当我在 chrome 开发工具中删除填充时,布局仍然损坏。 只要父级为position: relative,如果子级为position: absolute,则子级将相对于父级定位,而不是真正绝对定位。 是的,这有点用词不当。这是 Paulie_D 的内容:css-tricks.com/forums/topic/…【参考方案3】:

您可以通过使用flexbox 来实现这一点,并且代码少得多。下面的代码可以解决问题。

.clearfix 
  display: flex;
  align-items: center;

img 
  width: 150px;
  border-radius: 50%;

.about-container 
  width: 70%;
  padding-left: 30px;

在codepen中查看http://codepen.io/anon/pen/OWYxrb

【讨论】:

以上是关于CSS中的基本垂直中心在浮动元素上表现异常的主要内容,如果未能解决你的问题,请参考以下文章

css 中心浮动图像 - 在一些博客中的一个老技巧,中心浮动元素,使用这样的结构:

web前端练习30----Css,布局(文档流,浮动,清除浮动,浮动高度塌陷,垂直外边距重叠问题,定位,层级,居中,flex布局及练习)

web前端练习30----Css,布局(文档流,浮动,清除浮动,浮动高度塌陷,垂直外边距重叠问题,定位,层级,居中,flex布局及练习)

css基础 CSS 布局 – OverflowFloat 浮动CSS 布局 – 水平 垂直居中对齐

css定位之浮动定位

CSS:尽管旁边有浮动元素,如何使文本居中?