两栏布局之左侧固定,右侧自适应的实现方法

实现左侧固定,右侧自适应的两栏布局的方法有很多。其中经常用到的有float方法、BFC方法、CSS3的flex布局及grid布局。并非所有的布局都会在开发中使用,但是其中也会涉及一些知识点。

实现左侧固定,右侧自适应的两栏布局的方法有很多。其中经常用到的有float方法、BFC方法、CSS3的flex布局及grid布局。并非所有的布局都会在开发中使用,但是其中也会涉及一些知识点。

常用的宽度自适应的方法通常是利用了block水平的元素宽度能随父容器调节的流动特性。另外一种思路是利用CSS的calc()方法来动态设定宽度。还有一种思路是,利用CSS中的新型布局flex layout与grid layout。

首先创建基本的HTML布局和最基本的样式。

<div class="wrapper" id="wrapper">
  <div class="left">
    左边固定宽度,高度不固定 </br> </br></br></br>高度有可能会很小,也可能很大。
  </div>
  <div class="right">
    这里的内容可能比左侧高,也可能比左侧低。宽度需要自适应。</br>
    基本的样式是,两个div相距20px, 左侧div宽 120px
  </div>
</div>

基本的样式是,两个盒子相距20px,左侧盒子宽120px,右侧盒子宽度自适应。基本的CSS样式如下:

.wrapper {
    padding: 15px 20px;
    border: 1px dashed #ff6c60;
}
.left {
    width: 120px;
    border: 5px solid #ddd;
}
.right {
    margin-left: 20px;
    border: 5px solid #ddd;
}

下面的代码都是基于这套基本代码做覆盖,通过给容器添加不同的类来实现效果。

双inline-block方法

.wrapper-inline-block {
    box-sizing: content-box;
    font-size: 0;    // 消除空格的影响
}

.wrapper-inline-block .left,
.wrapper-inline-block .right {
    display: inline-block;
    vertical-align: top;    // 顶端对齐
    font-size: 14px;
    box-sizing: border-box;
}

.wrapper-inline-block .right {
    width: calc(100% - 140px);
}

这种方法是通过width:calc(100% – 140px)来动态计算右侧盒子的宽度。需要知道右侧盒子距离左边的距离,以及左侧盒子具体的宽度(content + padding + border),以此计算父容器宽度的100%需要减去的数值。同时,还需要知道右侧盒子的宽度是否包含border的宽度。

在这里,为了简单的计算右侧盒子准确的宽度,设置了元素的box-sizing:border-box;以及父元素的box-sizing:content-box;。

同时,作为两个inline-block的盒子,必须设置vertical-align来使其顶端对齐。

另外,为了准确地应用计算出来的宽度,需要消除div之间的空格,需要通过设置父容器的font-size:0;,或者用注释消除html中的空格等方法。

总之,要使用好这种方法,需要注意以下三点:

  • 需要知道左侧盒子的宽度,两个盒子的距离,还要设置各个元素的box-sizing
  • 需要消除空格字符的影响
  • 需要设置vertical-align:top满足顶端对齐。

双float方案

.wrapper-double-float {
    overflow: auto;        // 清除浮动
    box-sizing: content-box;
}

.wrapper-double-float .left,
.wrapper-double-float .right {
    float: left;
    box-sizing: border-box;
}

.wrapper-double-float .right {
    width: calc(100% - 140px);
}

本方案和双float方案原理相同,都是通过动态计算宽度来实现自适应。但是,由于浮动的block元素在有空间的情况下会依次紧贴,排列在一行,所以无需设置display: inline-block;,自然也就少了顶端对齐,空格字符占空间等问题。

不过由于应用了浮动,父元素需要清除浮动。

总之,使用这种布局方法,需要注意以下两点:

  • 需要知道左侧盒子的宽度,两个盒子的距离,还要设置各个元素的box-sizing。
  • 父元素需要清除浮动。

float+margin-left方案

.wrapper-float {
    overflow: hidden;        // 清除浮动
}

.wrapper-float .left {
    float: left;
}

.wrapper-float .right {
    margin-left: 150px;
}

上面两种方案都是利用了CSS的calc()函数来计算宽度值。下面两种方案则是利用了block级别的元素盒子的宽度具有填满父容器,并随着父容器的宽度自适应的流动特性。

但是block级别的元素都是独占一行的,所以要想办法让两个block排列到一起。

我们知道,block级别的元素会认为浮动的元素不存在,但是inline级别的元素能识别到浮动的元素。这样,block级别的元素就可以和浮动的元素同处一行了。

为了让右侧盒子和左侧盒子保持距离,需要为左侧盒子留出足够的距离。这个距离的大小为左侧盒子的宽度以及两个盒子之间的距离之和。然后将该值设置为右侧盒子的margin-left。

使用此方法布局,需要注意以下两点:

  • 需要清除浮动
  • 需要计算右侧盒子的margin-left

absolute+margin-left方法

另外一种让两个block排列到一起的方法是对左侧盒子使用position:absolute的绝对定位。这样,右侧盒子也能无视掉它。

.wrapper-absolute .left {
    position: absolute;
}

.wrapper-absolute .right {
    margin-left: 150px;
}

使用这种布局方法,需要主要以下两点:

  • 使用了绝对定位,若是用在某个div中,需要更改父容器的position。
  • 没有清除浮动的方法,若左侧盒子高于右侧盒子,就会超出父容器的高度。因此只能通过设置父容器的min-height来放置这种情况。

上面的方法都需要通过左侧盒子的宽度,计算某个值,下面三种方法都是不需要计算的。只需要设置两个盒子之间的间隔。

float+BFC方法

.wrapper-float-bfc {
    overflow: auto;
}

.wrapper-float-bfc .left {
    float: left;
    margin-right: 20px;
}

.wrapper-float-bfc .right {
    margin-left: 0;
    overflow: auto;
}

这个方案同样是利用了左侧浮动,但是右侧盒子通过overflow:auto;形成了BFC,因此右侧盒子不会与浮动的元素重叠。

这种情况下,只需要为左侧的浮动盒子设置margin-right,就可以实现两个盒子的距离了。而右侧盒子是block级别的,所以宽度能实现自适应。

使用好这个方法,需要注意父元素要清除浮动

flex方案

.wrapper-flex {
    display: flex;
    align-items: flex-start;
}

.wrapper-flex .left {
    flex: 0 0 auto;
}

.wrapper-flex .right {
    flex: 1 1 auto;
}

flex可以说是最好的方案了,代码少,使用简单。有朝一日,大家都改用现代浏览器,就可以使用了。换言之,使用这种方法,需要注意浏览器的兼容性。flex容器的一个默认属性值:align-item:stretch;这个属性导致了列等高的效果。为了让两个盒子高度自动,需要设置:align-item:flex-start;

grid方案

这是一个新型的布局方式。可以满足需求,但这并不是它发挥用处的真正地方。

.wrapper-grid {
    display: grid;
    grid-template-columns: 120px 1fr;
    align-items: start;
}

.wrapper-grid .left,
.wrapper-grid .right {
    box-sizing: border-box;
}

.wrapper-grid .left {
    grid-column: 1;
}

.wrapper-grid .right {
    grid-column: 2;
}

使用这种方案,需要注意以下两点:

  • grid布局也有列等高的默认效果。需要设置:align-items:start;
  • grid布局还有一个值得注意的小地方和flex不同:在使用margin-left的时候,grid布局默认是box-sizing设置的盒宽度之间的位置。而flex则是使用两个div的border或者padding外侧之间的距离。

极限情况

最后可以再看一下再父容器极限小的情况下,不同方案的表现。主要分成四种情况:

  • 动态计算宽度的情况:可以使用双inline-block方案和双float方案。宽度极限小时,右侧的div宽度会非常小,由于遵循流动布局,所以右侧div会移动到下一行。
  • 动态计算右侧margin-left的情况:可以使用float+margin-left方案和absolute+margin-left方案。宽度极限小时,由于右侧的div忽略了文档流中左侧div的存在,所以其依旧会存在于这一行,并被隐藏。
  • float+BFC方案的情况:这种情况下,由于BFC与float的特殊关系,右侧div在宽度减小到最小后,也会掉落到下一行。
  • flex和grid的情况:这种情况下,默认两种布局方式都不会放不下的div移动到下一行。不过flex布局可以通过flex-flow:wrap;来设置多余的div移动到下一行。grid布局暂不支持。

原创文章,作者:ZERO,如若转载,请注明出处:https://www.edu24.cn/course/two-column-layout.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
ZEROZERO
上一篇 2018年10月8日
下一篇 2018年12月6日

相关推荐

  • Java自学之类结构扩展

    面向对象中的核心组成是类与接口,在项目中会利用【包】进行一组相关类的管理,这样适合于程序代码的部分更新,也更加符合面向对象封装性的概念,同时合理地使用封装也可以方便地实现实例化对象…

    2020年12月10日
    1.5K
  • 创建vue3 + typescript项目说明

    创建项目 选择Manually select features【手动配置】 如上图选择配置项,并在下一步,选择3.x 接下来,按照推荐设置,进行选择【推荐设置都已英文字母大写的形式…

    2023年11月23日
    763
  • STS插件mybatis-generator安装及使用

    断断续续学习Java也有好长时间了,没有师傅带,没有项目练手,学习超级慢,也很烦。视频、书籍翻看了一大推,还是没有目标。 相信滴水成海,外加条条大路通罗马,只要坚持,自己终能达成目…

    2019年12月27日
    2.4K
  • Webpack入门,模块打包原理分析

    面对工程中成百上千个模块,Webpack究竟是如何将它们有序地组织在一起,并按照开发者预想的顺序运行在浏览器上的呢?本篇文章将通过一个简单的示例。分析一下Webpack模块打包的原…

    2022年11月14日
    914
  • 前端遍历树形数据,返回满足条件的树形数据

    在一次做手机端小程序项目中,有一个机构表单项,需要在页面展示是树形层级结构,但是后端开发人员返回的数据却是一维数组,而且还要在前端做过滤筛选功能。但是在使用的手机端组件库中,却没有…

    2022年11月8日
    563
  • css晦涩难懂的点都在这啦

    CSS大家肯定都是会的但是每个人所撑握的情况都不一样,特别是已经工作几年的前辈(这里指的是我司)很多CSS玩法都不知道,可能他们已经习惯了用组件, 但是面试的时候又不可避免问,所以…

    2021年1月20日
    1.5K
  • spring boot练习篇之用户登录系统【接口篇】

    写在前面 抛弃JSP,只做纯粹的前后端分离项目。 作为一个资深前端工作者,想要转JavaWeb开发,无论是书籍,还是网上视频、资料,竟然没有一篇能清楚明白地讲解怎样搭建一个前后端分…

    2021年5月25日
    1.8K
  • 回调函数散记

    今天被将要入职的公司的开发人员询问了一个项目中遇到的问题,关于函数内访问外部函数的情况。大致现象如下:js文件中有两个同级函数FnA和FnB,想在函数FnA中调用FnB。 一看就是…

    2019年8月16日
    1.6K
  • Java自学之String类

    在实际项目开发中,String是一个必须使用的程序类,可以说是项目的核心组成类。在Java程序里所有的字符串都要求使用【’‘】进行定义,同时也可以利用【+】实现字符串的连接处理。 …

    2020年11月30日
    1.5K
  • JAVA基础知识整理

    终于下定决心2020年转JAVA开发,自学之路坎坷曲折。俗话说的话,好记性不如烂笔头。如果有小伙伴们也像我一样在JAVA自学之路上徘徊,那就关注一下我的博客网站。我会不定期更新一下…

    2020年1月11日
    1.9K

发表回复

登录后才能评论