【问题标题】:How to set the margin or padding as percentage of height of parent container?如何将边距或填充设置为父容器高度的百分比?
【发布时间】:2011-06-26 07:57:36
【问题描述】:

我一直在绞尽脑汁想使用以下方法在 css 中创建垂直对齐

.base{
        background-color:green;
	    width:200px;
	    height:200px;
	    overflow:auto;
	    position:relative;
	}

    .vert-align{
		padding-top:50%;
		height:50%;
	}
<!-- and used the following div structure. -->

    <div class="base">
       <div class="vert-align">
    	   Content Here
       </div>
    </div>

虽然这似乎适用于这种情况,但令我惊讶的是,当我增加或减少基本 div 的宽度时,垂直对齐会突然对齐。我期待当我设置 padding-top 属性时,它会将填充作为父容器高度的百分比,在我们的例子中是基础,但是上面的 50% 的值被计算为百分比宽度。 :(

有没有办法将填充和/或边距设置为高度的百分比,而无需使用 JavaScript?

【问题讨论】:

    标签: html css vertical-alignment


    【解决方案1】:

    修复是,是的,垂直填充和边距是相对于宽度的,但 topbottom 不是。

    所以只需将一个 div 放在另一个 div 中,并在内部 div 中使用类似top:50% 的东西(记住position 很重要,如果它仍然不起作用)

    【讨论】:

    • top 非常适合根据浏览器/窗口高度调整大小。在那个div下面有一个div怎么样?你怎么能 clear 第二个 div 在被 top:50% 向下移动的 div 下??
    • 学习新东西。以前不知道垂直填充和边距是相对于宽度的。谢谢。
    • 也可以添加一个具有设定百分比高度的'spacer' div。看起来有点脏,但它有效。见this answer
    • 什么是永恒的@%!^?为什么垂直边距和内边距相对于 width?什么?为什么会做出这个决定?
    • 与下面的 alain 的回答相比,您的回答得到了极其不成比例的支持,这给出了一个通用的解决方案,我发现它非常有帮助,几乎没有看到它。 top: 50% 如果您需要按自己的中心对齐内容,则不是很有用。
    【解决方案2】:

    一个稍微不同的问题的答案:您可以使用vh 单位将元素填充到视口的中心:

    .centerme {
        margin-top: 50vh;
        background: red;
    }
    
    <div class="centerme">middle</div>
    

    【讨论】:

    • 为什么这个答案的票数不高?使用 vh 有什么问题吗?
    • 这是因为它不是针对原始问题量身定制的答案,它是一个有用的技巧,仅适用于少数相关情况。
    • 使用vh 与百分比几乎相同......在某些情况下甚至更糟。这个答案与问题无关
    【解决方案3】:

    这里有两个选项可以模拟所需的行为。不是通用解决方案,但在某些情况下可能会有所帮助。这里的垂直间距是根据外部元素的大小计算的,而不是它的父元素,但是这个大小本身可以是相对于父元素的,这样间距也是相对的。

    <div id="outer">
        <div id="inner">
            content
        </div>
    </div>
    

    第一个选项:使用伪元素,这里垂直和水平间距是相对于外部的。 Demo

    #outer::before, #outer::after {
        display: block;
        content: "";
        height: 10%;
    }
    #inner {
        height: 80%;
        margin-left: 10%;
        margin-right: 10%;
    }
    

    将水平间距移动到外部元素使其相对于外部元素的父级。 Demo

    #outer {
        padding-left: 10%;
        padding-right: 10%;
    }
    

    第二个选项:使用绝对定位。 Demo

    #outer {
        position: relative;
    }
    #inner {
        position: absolute;
        left: 10%;
        right: 10%;
        top: 10%;
        bottom: 10%;
    }
    

    【讨论】:

      【解决方案4】:

      要使子元素相对于其父元素绝对定位,您需要在父元素上设置相对位置和在子元素上设置绝对位置。

      那么在子元素上'top'是相对于父元素的高度。因此,您还需要将孩子向上“平移”其自身高度的 50%。

      .base{
          background-color: green;
          width: 200px;
          height: 200px;
          overflow: auto;
          position: relative;
      }
          
      .vert-align {
          position: absolute;
          top: 50%;
          transform: translate(0, -50%);
      }
          <div class="base">
              <div class="vert-align">
                  Content Here
              </div>
          </div>

      还有一个使用弹性盒子的解决方案。

      .base{
          background-color:green;
          width: 200px;
          height: 200px;
          overflow: auto;
          display: flex;
          align-items: center;
      }
      <div class="base">
          <div class="vert-align">
              Content Here
          </div>
      </div>

      你会发现两者的优点/缺点。

      【讨论】:

      • 使用 translate 是相对于其自身大小垂直移动元素的唯一真正方法。
      • 谢谢。这应该是选择的答案。
      【解决方案5】:

      这可以通过writing-mode 属性来实现。如果将元素的writing-mode 设置为垂直书写模式,例如vertical-lr,则其后代在两个维度上的内边距和外边距百分比值都将相对于高度而不是宽度。

      来自spec

      。 . . margin 和 padding 属性的百分比,在 CSS2.1 中总是根据包含块的宽度计算,在 CSS3 中是根据包含块的行内大小计算的。

      inline size的定义:

      行内尺寸的测量:在水平书写模式下是指物理宽度(水平尺寸),在垂直书写模式下是指物理高度(垂直尺寸)。

      示例,具有可调整大小的元素,其中水平边距相对于宽度,垂直边距相对于高度。

      .resize {
        width: 400px;
        height: 200px;
        resize: both;
        overflow: hidden;
      }
      
      .outer {
        height: 100%;
        background-color: red;
      }
      
      .middle {
        writing-mode: vertical-lr;
        margin: 0 10%;
        width: 80%;
        height: 100%;
        background-color: yellow;
      }
      
      .inner {
        writing-mode: horizontal-tb;
        margin: 10% 0;
        width: 100%;
        height: 80%;
        background-color: blue;
      }
      <div class="resize">
        <div class="outer">
          <div class="middle">
            <div class="inner"></div>
          </div>
        </div>
      </div>

      在您希望元素的纵横比保持不变,但又希望其大小与其高度而不是宽度相关的情况下,使用垂直书写模式特别有用。

      【讨论】:

      • 这是,IMO,将是更优雅的解决方案,但是(截至 2018-05-05),vertical writing modes aren't well supported。希望这种情况很快就会改变。
      • @zanerock 我相当肯定 MDN 兼容表已经过时。例如,它说 Safari 需要 -webkit- 前缀,但根据 caniuse 它自 Safari 11 以来就不需要前缀。您是否尝试过任何无法使用的浏览器?
      • 不,我不得不承认我只是认为它很好,甚至是自动化的。
      【解决方案6】:

      另一种使一行文本居中的方法是:

      .parent{
        position: relative;
      }
      
      .child{
         position: absolute;
         top: 50%;
         line-height: 0;
      }
      

      或者只是

      .parent{
        overflow: hidden; /* if this ins't here the parent will adopt the 50% margin of the child */
      }
      
      .child{
         margin-top: 50%;
         line-height: 0;
      }
      

      【讨论】:

        【解决方案7】:

        50% 的填充不会使您的孩子居中,它会将其置于中心下方。我认为你真的想要一个 25% 的 padding-top。也许您只是因为内容变高而空间不足?您是否也尝试过设置 margin-top 而不是 padding-top?

        编辑:没关系,w3schools 网站说

        % 以包含元素宽度的百分比指定填充

        所以也许它总是使用宽度?我从来没有注意到。

        您正在做的事情可以使用 display:table 来实现(至少对于现代浏览器而言)。 The technique is explained here.

        【讨论】:

        • 谢谢斯普利夫。我知道我的 50% 不会以 div 的内容为中心。我实际上只有一行需要垂直居中的文本。非常感谢您的链接!
        • 如果只是一行文字,您是否考虑过使用大得离谱的line-height,即行高为200px?
        • @Ryan 用于垂直居中文本,请参阅 stackoverflow.com/questions/8865458/…
        • 您的链接已损坏
        【解决方案8】:

        这是一个非常有趣的错误。 (在我看来,这是一个错误)很好的发现!

        关于 如何 设置它,我会推荐 Camilo Martin 的回答。但至于为什么,如果你们不介意的话,我想稍微解释一下。


        the CSS specs我发现:

        'padding'
        百分比:指包含块的宽度

        ……这很奇怪,但没关系。

        因此,对于父 width: 210px 和子 padding-top: 50%,我得到 padding-top: 96.5px 的计算/计算值 - 这不是预期的 105px

        这是因为在 Windows 中(我不确定其他操作系统),常用滚动条的大小默认为 17px × 100%(或水平条为 100% × 17px)。那些17px 在计算50% 之前被减去,因此是50% of 193px = 96.5px

        【讨论】:

        猜你喜欢
        • 2013-04-25
        • 2013-08-23
        • 2021-01-12
        • 2012-05-09
        • 1970-01-01
        • 2011-08-25
        • 2012-01-27
        • 1970-01-01
        • 2012-06-30
        相关资源
        最近更新 更多