CSS 怎么实现两个 div 一个固定宽另一个填充剩余空间?

当年这可能是一个典型的CSS面试题:“两列布局”。很多年前(大约是10年前吧),有过这样的一个面试题:

两列布局,左侧列宽度是20%,右侧列是80%,两列之间的间距是20px,CSS怎样实现这样的一个布局,而且不会出现滚动条!

对于题主这个问题,早在当年可能会较为蛋疼一点,或许很多开发者会采用 JavaScript 来辅助完成。但对于今天而言,这个布局效果再简单不过了。而且方案很多。

假设构建这样的一个布局,它的 HTML像下面这样:

<body>
<aside>侧边栏,固定宽度</aside>
<main>主内容,填充剩余空间</main>
</body>

这个布局最大的特点是:

两列布局,其中一列固定尺寸(比如说侧边栏),另外一列自适应,能随着容器宽度调整!

接下来,分不同方案来构建这样的一个布局。

calc()方案

在Flexbox和Grid还没出现的时候,如果不借助 JavaScript 的话,calc() 应该是最简单的了吧 :

body {
display: flow-root; /*清除浮动*/
}
aside {
float: left;
width: 220px;
}
main {
float: left;
width: calc(100% - 220px);
}

如果你还希望列与列之间有一定的间距,还可以像下面样写:

body {
display: flow-root; /*清除浮动*/
}
aside {
float: left;
width: 220px;
}
main {
float: left;
margin-left: 20px;
width: calc(100% - 220px - 20px);
}

结合 CSS 自定义属性,灵活性会更好:

:root {
--fixed-width: 220px;
--gap: 20px;
}
body {
display: flow-root; /*清除浮动*/
}
aside {
float: left;
width: var(--fixed-width);
}
main {
float: left;
margin-left: var(--gap);
width: calc(100% - var(--fixed-width) - var(--gap));
}

如果效果要更完美一点,可以考虑在 body 上添加一个 min-width 的设置。

在这个示例中,用到了两个关键点,第一个 CSS 函数中的 calc() 函数的功能,它可以做四则运算,第二个就是 CSS 值中的 % ,当百分比% 运用于 width 时,它的计算是相对于其父容器的 width 来计算。

Flexbox方案

Flexbox 方案就更简单了:

body {
display: flex;
gap: var(--gap)
}
aside {
width: var(--fixed-width);
}
main {
flex: 1;
}

里使用了 CSS Flexbox 布局,很简单。将body 声明为一个 Flexbox 容器(使用 display) ,在侧边栏设置固定宽度,主列使用 flex:1 ,他会扩展Flexbox容器的剩余空间。如果只是要现这样的一个效果,到此就可以了。

Grid 方案

Grid 方案和 Flexbox 很相似:

body {
display: grid;
gap: var(--gap);
grid-template-columns: var(--fixed-width) 1fr;
}

使用Grid 是最简单的!不过要掌握 Grid 就不简单了。这里关键是使用 grid-template-columns 定义了一个两列网格,其中第一列列宽是 --fixed-width ,第二列列宽是 1fr 。这个 fr 是 Grid 中独有的特性。

fr单位代表网格容器中可用空间的一等份

从这个描述中不难发现,在CSS网格布局中使用fr单位确定尺寸的网格轨道被称为 弹性网格轨道 ,因为它们会根据网格容器剩余空间进行对网格轨道进行弹性缩放,这个有点类似于 Flexbox 布局中的 flex 有点类似。

一般情况之下,网格轨道使用fr单位时,网格容器的可空间会按下面的公式来计算网格轨道尺寸:

对于fr设置弹性网格轨道理解起来还是有一定的困惑,不过我们可以将其和%结合起来,会更易于理解。简单地说:

1fr(即1fr)就是100%网格容器可用空间;2fr(即2fr)是各50%网格容器可用空间,即1fr50%网格容器可用空间。以此类似,要是你有25fr(即25fr),那么每个fr1fr)就是1/254%

使用饼图可以很形象的描述fr

注意,一个饼图(圆)就相当于网格容器的可用空间,分割的份数就相当于设置了弹性系数的网格轨道

上面三个方案效果都是一致的

 

posted @   蓦然JL  阅读(58)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
历史上的今天:
2021-12-30 echarts 如何结合百度地图使用
2021-12-30 echarts 主题颜色更换
2021-12-30 uniapp 拨打电话 - uni.makePhoneCall(tel)
2021-12-30 echarts 随屏幕大小改变大小(resize)
2021-12-30 uniapp 飞入购物车的商品
  1. 1 唯一 G.E.M.邓紫棋
  2. 2 他只是经过 白敬亭 魏大勋
  3. 3 Uptown Funk Mark Ronson / Bruno Mars
  4. 4 在你的身边 盛哲
  5. 5 Edge of My Life Manafest
  6. 6 凄美地 郭顶
  7. 7 Wonderful Tonight Boyce Avenue
  8. 8 心如止水 Ice Paper
  9. 9 Sugar Maroon 5
  10. 10 静谧时光 JIAxNING
  11. 11 Right Now (Na Na Na) Aamir
  12. 12 Dangerously Charlie Puth
  13. 13 Someone You Loved Madilyn Paige
  14. 14 Shape of My Heart Boyce Avenue
  15. 15 We Can't Stop Boyce Avenue / Bea Miller
  16. 16 Perfect Boyce Avenue
  17. 17 Love Me Like You Do Boyce Avenue
  18. 18 Thank You Boyce Avenue
  19. 19 Don’t Wanna Know Boyce Avenue / Sarah Hyland
他只是经过 - 白敬亭 魏大勋
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

Not available

访问主页
关注我
关注微博
私信我
返回顶部
点击右上角即可分享
微信分享提示

目录导航