`
zachary.guo
  • 浏览: 490093 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

有关 HTML 水平垂直居中问题的讨论

阅读更多
        关于 HTML 水平垂直居中问题,网上的讨论已经是相当地多了。这里,我把网上搜索的结果,并附加上解题思路,总结出来,希望对大家有所帮助。

        首先,我们需要明确一个概念,到底是谁要相对于谁水平垂直居中,相应的样式应该写在谁的里面。这里,我们统称为:inner element 相对于 outer element 水平垂直居中。下面首先讲到的是文字在 div 中居中,这个不属于这个范畴。因为盛放文字的 div 若是置于其它的 div(outer div) 中,而且文字 div 要整体相对于这个层居中,这才是我们要讨论的话题。这个时候,盛放文字的层就是 inner element,它所相对于的那个层居中的元素就是 outer element。

        我们首先先看看如何使得某段文字处于 div 水平和垂直方向的中间,下面分情况来讨论。

        1. 单行文字
        单行文字,有两种情况:① div 的高度显示指定;② div 的高度未指定。对于 ②,文字的字体大小就决定了 div 的高度,此种情况没有必要讨论。对于 ①,只需要将 line-height 的值设置的和 height 值一致即可。至于宽度,没指定,写多少字就多宽,指定了宽度,设置 text-align 为 center 即可。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<style>
  div {
    /* 为了看清 div 的轮廓,我给 div 加上边框 */
    border: 1px solid black;
    width: 400px;
    height: 100px;
    line-height: 100px;
    text-align: center;
    font-size: 12px;
  }
</style>

<div>我确保这段文字就只有一行。</div>


        2. 多行文字(div 的高度未知)
        这种情况,div 的高度是随文字的多少而变化的。只需设置 padding 值即可,看你需要 padding 多少了,比较随意。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<style>
  div {
    /* 为了看清 div 的轮廓,我给 div 加上边框 */
    border: 1px solid black;
    width: 400px;
    font-size: 12px;
    padding: 20px;
  }
</style>

<div>&nbsp;&nbsp;&nbsp;&nbsp;如果一段内容,它的高度是可变的那么我们就可以使用使得上下的 padding 值相同的方法即可。同样的,这也是一种 "看起来" 的垂直居中方式,它只不过是使文字把 div 完全填充的一种访求而已。</div>


        3. 多行文字(div 的高度指定,即固定高度的 div)
        CSS 中的 vertical-align 属性只会对拥有 valign 特性的 (X)HTML 标签起作用,但是在 CSS 中还有一个 display 属性能够模拟 <table>,所以我们可以使用这个属性来让 <div> 模拟 <table> 就可以使用 vertical-align了。注意,display:table 和 display:table-cell 的使用方法,前者必须设置在父元素上,后者必须设置在子元素上,因此我们要为需要定位的文本再增加一个 <div> 元素。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<style>
  div.outer {
    /* 为了看清 div 的轮廓,我给 div 加上边框 */
    border: 1px solid black;
    width: 400px;
    height: 300px;
    overflow: auto;
    font-size: 12px;
    display: table;
  }
  
  div.inner {
    display: table-cell;
    vertical-align: middle;
    padding: 20px;
  }
</style>

<div class="outer">
  <div class="inner">
    &nbsp;&nbsp;&nbsp;&nbsp;CSS 中的 vertical-align 属性只会对拥有 valign 特性的 (X)HTML 标签起作用,但是在 CSS 中还有一个 display 属性能够模拟 table,所以我们可以使用这个属性来让 div 模拟 table 就可以使用 vertical-align了。注意,display:table 和 display:table-cell 的使用方法,前者必须设置在父元素上,后者必须设置在子元素上,因此我们要为需要定位的文本再增加一个 div 元素。
  </div>
</div>

        这个方法应该是很理想了,但是不幸的是,只有标准浏览器中(FF,Opera, Safari,IE8 等)才能正确地理解 display:table 和 display:table-cell,因此这种方法在不支持 W3C 标准的浏览器(IE6 和 IE7)下是无效的。嗯,这让人很郁闷!不过我们还其它的办法。

        在不支持 W3C 标准的 IE 浏览器中,在高度的计算上存在着缺陷的。对父元素进行定位后,如果再对子元素进行百分比计算时,计算的基础似乎是有继承性的(如果定位的数值是绝对数值没有这个问题,但是使用百分比计算的基础将不再是该元素的高度,而从父元素继承来的定位高度)。例如,我们有下面这样一个(X)HTML代码段:
<div id="outer"> 
 <div id="inner"> 
   <div id="content"></div> 
  </div>
</div>

        现在,outer 层就是我们的大容器,在 Firefox,Chrome 等现代浏览器中,使用两个层(包括外围的容器层),并使用 display 和 vertical-align 属性即可垂直居中。这里,IE6 和 IE7 需要三个层(包括外围的容器层)。outer 层的宽高度已知,content 层的高度未知,因为我们不知道 content 层要写多少文字,所以我们引入了 inner 层,它将 content 层包裹起来,这样,content 层里有多少文字,那么,inner 层的高度就和 content 层的高度一样(这还依赖于它们各自 position 的设置),都为文字占用的高度。不过,我们仍然要记住,inner 层和 content 层的高度是未知的。我们使 inner 层的 position 为 absolute(若为 relative,那么 inner 层的宽度将继承 outer 层的宽度,这不是我们想要的效果,我们要的效果是和 content 层一致的宽高度),top 为 50%,那么,inner 层的左上角位于 outer 层垂直方向上的正中间(50% 是根据 outer 层的高度来计算的,计算的基础是它父亲元素的高度)。这个时候,我们只需要将 content 层的位置向上偏移 content 或 inner 层的高度的一半即可。可惜,我们并不知道它们的高度。这就是为什么我们要引入三个层的原因了。由于 innner 层的 position 为 absolute,如果 content 层的 position 也为 absolute,那么 inner 层将没有高宽度,我们只能使 content 层的 postion 为 relative,只有这样,inner 层和 content 层才会有相同的高宽度。在 content 层上设置 top 为 -50%,那么它就是按 outer 层的高度来计算了。这样就达到我们的目的了。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<style>
  div.outer {
    border: 1px solid black;
    width: 600px;
    height: 400px;
    font-size: 12px;
    /* 或者 position: absolute; */
    position: relative;
  }
  
  div.inner {
    /* 必须的 */
    position: absolute;
    top: 50%;
  }
  
  div.content {
    /* 必须的 */
  	position: relative;
  	top: -50%;
  }
</style>

<div class="outer"> 
 <div class="inner"> 
   <div class="content">
     &nbsp;&nbsp;&nbsp;&nbsp;现在,outer 层就是我们的大容器,在 Firefox,Chrome 等现代浏览器中,使用两个层(包括外围的容器层),并使用 display 和 vertical-align 属性即可垂直居中。这里,IE6 和 IE7 需要三个层(包括外围的容器层)。outer 层的宽高度已知,content 层的高度未知,因为我们不知道 content 层要写多少文字,所以我们引入了 inner 层,它将 content 层包裹起来,这样,content 层里有多少文字,那么,inner 层的高度就和 content 层的高度一样(这还依赖于它们各自 position 的设置),都为文字占用的高度。不过,我们仍然要记住,inner 层和 content 层的高度是未知的。我们使 inner 层的 position 为 absolute(若为 relative,那么 inner 层的宽度将继承 outer 层的宽度,这不是我们想要的效果,我们要的效果是和 content 层一致的宽高度),top 为 50%,那么,inner 层的左上角位于 outer 层垂直方向上的正中间(50% 是根据 outer 层的高度来计算的,计算的基础是它父亲元素的高度)。这个时候,我们只需要将 content 层的位置向上偏移 content 或 inner 层的高度的一半即可。可惜,我们并不知道它们的高度。这就是为什么我们要引入三个层的原因了。由于 innner 层的 position 为 absolute,如果 content 层的 position 也为 absolute,那么 inner 层将没有高宽度,我们只能使 content 层的 postion 为 relative,只有这样,inner 层和 content 层才会有相同的高宽度。在 content 层上设置 top 为 -50%,那么它就是按 outer 层的高度来计算了。这样就达到我们的目的了。
   </div>
  </div>
</div>

        为了将就 IE6 和 IE7,我们不得不使得支持 W3C 标准的浏览器(Firefox, Chrome)也使用三个层来实现居中的效果。我们也只能使用 CSS Hack 来兼容这若干个浏览器了。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<style>
  div.outer {
    border: 1px solid black;
    width: 600px;
    height: 400px;
    font-size: 12px;
    /* 或者 position: absolute; */
    _position: relative;
    
    display: table;
  }
  
  div.inner {
    /* 必须的 */
    _position: absolute;
    _top: 50%;
    
  	display: table-cell;
  	vertical-align: middle;
  }
  
  div.content {
    /* 必须的 */
  	_position: relative;
  	_top: -50%;
  }
</style>

<div class="outer"> 
 <div class="inner"> 
   <div class="content">
     &nbsp;&nbsp;&nbsp;&nbsp;为了将就 IE6 和 IE7,我们不得不使得支持 W3C 标准的浏览器(Firefox, Chrome)也使用三个层来实现居中的效果。我们也只能使用 CSS Hack 来兼容这若干个浏览器了。
   </div>
  </div>
</div>


        文字处于 div 的中间的问题我们已经讨论完了,现在,我们要将盛放文字的层视为 inner element。我们现在要使文字层处于这个页面的正中间,这个时候,body 就是我们的 outer element 了。

        这种情况,由于 inner element 的宽高度已知(其实,只是盛放文字的 div 高度被设定,文字到底有多少,还是不知道),我们首先使得 inner element 的左上角位于 outer element 的正中心。此时需要设置 inner element 的 position 为 absolute,使得其 top 和 left 均为 50%。再将 margin-top 设置为 -height/2,margin-left 设置为 -width/2。这样,就达到了我们所要的效果。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>
  <head>
    <style>
      html, body {
        margin: 0;
        padding: 0;
        width: 100%;
        height: 100%;
      }
      
      div.outer {
        /* 为了看清整个 inner element 的轮廓,这里设置 inner element 的边框为黑色,1px */
        border: 1px solid black;
        width: 600px;
        height: 400px;
        font-size: 12px;
        position: absolute;
        top: 50%;
        left: 50%;
        /* margin-left = -width/2 = -600/2 - -300 */
        margin-left: -300px;
        /* margin-top = -height/2 = -400/2 = -200 */
        margin-top: -200px;
        
        display: table;
      }
      
      div.inner {
        /* 必须的 */
        _position: absolute;
        _top: 50%;
        
        display: table-cell;
        vertical-align: middle;
        /* 水平居中 */
        text-align: center;
      }
      
      div.content {
        /* 必须的 */
        _position: relative;
        _top: -50%;
      }
    </style>
  </head>
  
  <body>
    <div class="outer"> 
      <div class="inner"> 
        <div class="content">
          &nbsp;&nbsp;&nbsp;&nbsp;这是一段文字,我要使得它们水平垂直居中于页面!这样的代码,在 IE6 和 IE7 下仍然不能很好的支持,而且在这两种浏览器下的效果还不一样,不管啦,只要能支持现代浏览器就行了,懒得为这些浏览器的 bug 折腾了。
        </div>
      </div>
    </div>
  </body>
</html>

        事实上,上述计算 margin-left 和 margin-top 的方法并不准确。以 margin-left 为例子,准确的计算方法为:-(border-left + padding-left + width + padding-right + border-right)/2。实际操作时,几像素的差距可以忽略不计,视觉上觉得是居中的即可。若 padding 或 border 设置的值很大的话,就应该考虑精确算法了。
分享到:
评论

相关推荐

    SNS单模无芯光纤仿真与传感器结构特性分析——基于Rsoft beamprop模块

    内容概要:本文主要探讨了SNS单模无芯光纤的仿真分析及其在通信和传感领域的应用潜力。首先介绍了模间干涉仿真的重要性,利用Rsoft beamprop模块模拟不同模式光在光纤中的传播情况,进而分析光纤的传输性能和模式特性。接着讨论了光纤传输特性的仿真,包括损耗、色散和模式耦合等参数的评估。随后,文章分析了光纤的结构特性,如折射率分布、包层和纤芯直径对性能的影响,并探讨了镀膜技术对光纤性能的提升作用。最后,进行了变形仿真分析,研究外部因素导致的光纤变形对其性能的影响。通过这些分析,为优化光纤设计提供了理论依据。 适合人群:从事光纤通信、光学工程及相关领域的研究人员和技术人员。 使用场景及目标:适用于需要深入了解SNS单模无芯光纤特性和优化设计的研究项目,旨在提高光纤性能并拓展其应用场景。 其他说明:本文不仅提供了详细的仿真方法和技术细节,还对未来的发展方向进行了展望,强调了SNS单模无芯光纤在未来通信和传感领域的重要地位。

    发那科USM通讯程序socket-rece

    发那科USM通讯程序socket-set

    嵌入式八股文面试题库资料知识宝典-WIFI.zip

    嵌入式八股文面试题库资料知识宝典-WIFI.zip

    JS+HTML源码与image

    源码与image

    物流行业车辆路径优化:基于遗传算法和其他优化算法的MATLAB实现及应用

    内容概要:本文详细探讨了物流行业中路径规划与车辆路径优化(VRP)的问题,特别是针对冷链物流、带时间窗的车辆路径优化(VRPTW)、考虑充电桩的车辆路径优化(EVRP)以及多配送中心情况下的路径优化。文中不仅介绍了遗传算法、蚁群算法、粒子群算法等多种优化算法的理论背景,还提供了完整的MATLAB代码及注释,帮助读者理解这些算法的具体实现。此外,文章还讨论了如何通过MATLAB处理大量数据和复杂计算,以得出最优的路径方案。 适合人群:从事物流行业的研究人员和技术人员,尤其是对路径优化感兴趣的开发者和工程师。 使用场景及目标:适用于需要优化车辆路径的企业和个人,旨在提高配送效率、降低成本、确保按时交付货物。通过学习本文提供的算法和代码,读者可以在实际工作中应用这些优化方法,提升物流系统的性能。 其他说明:为了更好地理解和应用这些算法,建议读者参考相关文献和教程进行深入学习。同时,实际应用中还需根据具体情况进行参数调整和优化。

    嵌入式八股文面试题库资料知识宝典-C and C++ normal interview_8.doc.zip

    嵌入式八股文面试题库资料知识宝典-C and C++ normal interview_8.doc.zip

    基于灰狼优化算法的城市路径规划Matlab实现——解决TSP问题

    内容概要:本文介绍了基于灰狼优化算法(GWO)的城市路径规划优化问题(TSP),并通过Matlab实现了该算法。文章详细解释了GWO算法的工作原理,包括寻找猎物、围捕猎物和攻击猎物三个阶段,并提供了具体的代码示例。通过不断迭代优化路径,最终得到最优的城市路径规划方案。与传统TSP求解方法相比,GWO算法具有更好的全局搜索能力和较快的收敛速度,适用于复杂的城市环境。尽管如此,算法在面对大量城市节点时仍面临运算时间和参数设置的挑战。 适合人群:对路径规划、优化算法感兴趣的科研人员、学生以及从事交通规划的专业人士。 使用场景及目标:①研究和开发高效的路径规划算法;②优化城市交通系统,提升出行效率;③探索人工智能在交通领域的应用。 其他说明:文中提到的代码可以作为学习和研究的基础,但实际应用中需要根据具体情况调整算法参数和优化策略。

    嵌入式八股文面试题库资料知识宝典-Intel3.zip

    嵌入式八股文面试题库资料知识宝典-Intel3.zip

    嵌入式八股文面试题库资料知识宝典-2019京东C++.zip

    嵌入式八股文面试题库资料知识宝典-2019京东C++.zip

    嵌入式八股文面试题库资料知识宝典-北京光桥科技有限公司面试题.zip

    嵌入式八股文面试题库资料知识宝典-北京光桥科技有限公司面试题.zip

    物理学领域十字形声子晶体的能带与传输特性研究及应用

    内容概要:本文详细探讨了十字形声子晶体的能带结构和传输特性。首先介绍了声子晶体作为新型周期性结构在物理学和工程学中的重要地位,特别是十字形声子晶体的独特结构特点。接着从散射体的形状、大小、排列周期等方面分析了其对能带结构的影响,并通过理论计算和仿真获得了能带图。随后讨论了十字形声子晶体的传输特性,即它对声波的调控能力,包括传播速度、模式和能量分布的变化。最后通过大量实验和仿真验证了理论分析的正确性,并得出结论指出散射体的材料、形状和排列方式对其性能有重大影响。 适合人群:从事物理学、材料科学、声学等相关领域的研究人员和技术人员。 使用场景及目标:适用于希望深入了解声子晶体尤其是十字形声子晶体能带与传输特性的科研工作者,旨在为相关领域的创新和发展提供理论支持和技术指导。 其他说明:文中还对未来的研究方向进行了展望,强调了声子晶体在未来多个领域的潜在应用价值。

    嵌入式系统开发_USB主机控制器_Arduino兼容开源硬件_基于Mega32U4和MAX3421E芯片的USB设备扩展开发板_支持多种USB外设接入与控制的通用型嵌入式开发平台_.zip

    嵌入式系统开发_USB主机控制器_Arduino兼容开源硬件_基于Mega32U4和MAX3421E芯片的USB设备扩展开发板_支持多种USB外设接入与控制的通用型嵌入式开发平台_

    e2b8a-main.zip

    e2b8a-main.zip

    少儿编程scratch项目源代码文件案例素材-火柴人跑酷(2).zip

    少儿编程scratch项目源代码文件案例素材-火柴人跑酷(2).zip

    【HarmonyOS分布式技术】远程启动子系统详解:跨设备无缝启动与智能协同的应用场景及未来展望

    内容概要:本文详细介绍了HarmonyOS分布式远程启动子系统,该系统作为HarmonyOS的重要组成部分,旨在打破设备间的界限,实现跨设备无缝启动、智能设备选择和数据同步与连续性等功能。通过分布式软总线和分布式数据管理技术,它能够快速、稳定地实现设备间的通信和数据同步,为用户提供便捷的操作体验。文章还探讨了该系统在智能家居、智能办公和教育等领域的应用场景,展示了其在提升效率和用户体验方面的巨大潜力。最后,文章展望了该系统的未来发展,强调其在技术优化和应用场景拓展上的无限可能性。 适合人群:对HarmonyOS及其分布式技术感兴趣的用户、开发者和行业从业者。 使用场景及目标:①理解HarmonyOS分布式远程启动子系统的工作原理和技术细节;②探索该系统在智能家居、智能办公和教育等领域的具体应用场景;③了解该系统为开发者提供的开发优势和实践要点。 其他说明:本文不仅介绍了HarmonyOS分布式远程启动子系统的核心技术和应用场景,还展望了其未来的发展方向。通过阅读本文,用户可以全面了解该系统如何通过技术创新提升设备间的协同能力和用户体验,为智能生活带来新的变革。

    嵌入式八股文面试题库资料知识宝典-C and C++ normal interview_1.zip

    嵌入式八股文面试题库资料知识宝典-C and C++ normal interview_1.zip

    少儿编程scratch项目源代码文件案例素材-激光反弹.zip

    少儿编程scratch项目源代码文件案例素材-激光反弹.zip

    COMSOL相控阵检测技术在有机玻璃斜楔中检测工件内部缺陷的应用研究

    内容概要:本文详细介绍了COMSOL相控阵检测技术在有机玻璃斜楔上放置16阵元进行工件内部缺陷检测的方法。首先阐述了相控阵检测技术的基本原理,特别是通过控制各阵元的激发时间和相位来实现声波的聚焦和扫描。接着,重点解析了横孔缺陷的反射接收波,解释了波的折射现象及其背后的物理原因。最后,通过实例展示了COMSOL模拟声波传播过程的成功应用,验证了该技术的有效性和准确性。 适合人群:从事固体力学、无损检测领域的研究人员和技术人员,尤其是对相控阵检测技术和COMSOL仿真感兴趣的读者。 使用场景及目标:适用于需要精确检测工件内部缺陷的研究和工业应用场景,旨在提高检测精度和效率,确保产品质量和安全。 其他说明:文中提到的声速匹配现象有助于理解波在不同介质间的传播特性,这对优化检测参数设置有重要意义。

    少儿编程scratch项目源代码文件案例素材-极速奔跑者.zip

    少儿编程scratch项目源代码文件案例素材-极速奔跑者.zip

    嵌入式八股文面试题库资料知识宝典-微软_interview.zip

    嵌入式八股文面试题库资料知识宝典-微软_interview.zip

Global site tag (gtag.js) - Google Analytics