【译】CSS 中你须要知道 auto 的一切!

做者:shadeed 译者:前端小智 来源:css-trickscss

点赞再看,养成习惯html

本文 GitHub github.com/qq449245884… 上已经收录,更多往期高赞文章的分类,也整理了不少个人文档,和教程资料。欢迎Star和完善,你们面试能够参照考点复习,但愿咱们一块儿有点东西。前端

在CSS中,咱们有auto值,它能够用于像marginpositionheightwidth等属性。在本文中,会先解释auto的工做方式以及如何最大程度地利用auto的技术细节,固然,会配合一些用例和示例。git

简介

auto关键字的使用因属性而异。 对于本文,我将在每一个属性的上下文中解释值。github

width: auto

块级元素(如<div><p>)的初始宽度是auto,这使得它们占据了包含它们的块的整个水平空间。面试

根据CSS规范:浏览器

‘margin-left’ + ‘border-left-width’ + ‘padding-left’ + ‘width’ + ‘padding-right’ + ‘border-right-width’ + ‘margin-right’ = 块的宽度bash

当一个元素的宽度值为auto时,它包含marginpaddingborder,不会变得比它的父元素大。其中 content 的宽度将是content自己减去marginpaddingborder微信

咱们以上面的模型为例。app

html

<div class="wrapper">
  <div class="item">
    <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Eos maxime cum non cupiditate, perferendis saepe vitae fugiat id exercitationem officiis voluptate sint ducimus commodi reiciendis error itaque dolores ipsam? Ea!</p>
  </div>
</div>
复制代码

css

* {
    box-sizing: border-box;
}

.wrapper {
      max-width: 600px;
      margin: 2rem auto 0;
      padding: 1rem;
}

.item {
      padding: 1rem;
      margin: 0 50px;
      border: 15px solid #1f2e17;
}
复制代码

一切都好,元素 item被限制在其父项中。

是,若是咱们将元素item的宽度更改成100%而不是auto会发生什么? 该元素将占用其父项的100%,加上左侧和右侧的边距。

// css
.item {
      width: 100%;
      padding: 1rem;
      margin: 0 50px;
      border: 15px solid #1f2e17;
}
复制代码

你们都说简历没项目写,我就帮你们找了一个项目,还附赠【搭建教程】

该元素的宽度为568px,是如下各项的总和:

‘border-left-width’ + ‘padding-left’ + ‘width’ + ‘padding-right’ + ‘border-right-width’ = 15 + 16 + 506 + 16 + 15 = 568px

若是方向是ltr,则彻底忽略margin-right。在咱们的例子中,这种状况发生了。可是,若是布局是rtl,那么margin-left将被忽略。

事例源码:codepen.io/shadeed/pen…

width 用例: auto

仅仅解释基础知识不足以使咱们掌握这一律念,所以须要一些事例来讲明。

手机和 PC 之间的宽度不一样

咱们有一组按钮。在移动设备上,咱们但愿它们彼此相邻(每一个按钮包装器占据其父元素的50%),而在桌面设备上,每一个按钮都应该占据其父元素的所有宽度。该怎么作?

HTML

<div class="group">
    <div class="group__item">
        <button class="c-button">Sign In</button>
    </div>
    <div class="group__item">
        <button class="c-button c-button--ghost">Register</button>
    </div>
</div>
复制代码

这里使用 flex 布局将按钮排列在一块儿。

CSS

.group {
    display: flex;
}

.group__item {
    width: 50%;
}
复制代码

对于 PC,咱们每一个项须要都取全宽。在这种状况下,你可能倾向于使用width: 100%,对吗?下面是一个更好的解决方案。

CSS

@media (min-width: 800px) {
    /* Revert the wrapper to a block element instead of flex */
    .group {
        display: block;
    }

    .group__item {
        width: auto;
    }
}
复制代码

因为.group是一个块元素,所以使用width: auto能够很好地填充其父元素的可用空间。

事例源码:codepen.io/shadeed/pen…

你们都说简历没项目写,我就帮你们找了一个项目,还附赠【搭建教程】

height: auto

说到height,状况就不同了。元素的高度等于默认值为auto的内容。

考虑下面的例子

<div class="wrapper">
  <div class="item">What's my height?</div> </div> 复制代码

要使.item得到其容器的所有高度,咱们可使用如下方法之一:

  1. .wrapper一个固定的高度,而后为.item元素添加height: 100%
  2. .wrapper使用 flex 布局,默认状况下它将拉伸子项.item

CSS

.wrapper {
    height: 200px;
}

.item {
    height: 100%;
}
复制代码

margin 和 auto 关键字

对于margin,最多见的用例是将已知宽度的元素水平居中。

请考虑如下示例:

要让上面的蓝色矩形居中,可使用下面的方法:

.element {
    margin-left: auto;
    margin-right: auto;
}
复制代码

根据CSS规范:

若是margin-leftmargin-right值均为auto,则它们的使用值相等。 这使元素相对于包含块的边缘水平居中。

具备绝对定位元素的 margin:auto

另外一个不太常见的将绝对定位元素居中的用例是margin: auto。当咱们有一个元素应该在它的父元素内部水平和垂直居中时,咱们可能会倾向于使用translateXtranslateY

咱们可使用下面方法让具备绝对定位元素居中:

  1. 设置的宽度和高度。
  2. 元素应具备position: absolute

HTML

<div class="wrapper">
  <div class="item">I am centered.</div>
</div>
复制代码

CSS

.wrapper {
    position: relative;
}

.item {
    width: 200px;
    height: 100px;
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    margin: auto;
}
复制代码

事例源码:codepen.io/shadeed/pen…

你们都说简历没项目写,我就帮你们找了一个项目,还附赠【搭建教程】

Flexbox

在某些状况下,在flexbox中使用自动页边距很是有用。当一个子项目有一个marginauto 时,它将被推到远的另外一边。例如,若是一个flex项目的左边是margin-left: auto,那么它将被推到最右边。

考虑下面的模型,父级元素是一个 flex 布局:

咱们想把第二项推到最右边,自动边距就派上用场了。

CSS

.wrapper {
    display: flex;
}

.item-2 {
    margin-left: auto;
}
复制代码

不只如此,它还能够在水平或垂直方向工做。参见下面的示例

CSS

.item-2 {
    margin-top: auto;
}
复制代码

另外,若是只有一个子元素,则可使用margin:auto将其水平和垂直居中。

CSS

.item-1 {
    margin: auto;
}
复制代码

flex 属性和 auto 关键字

flexbox中,咱们可使用flex: auto做为子项目。这是什么意思?当一个子项目有flex: auto时,它等价于flex: 11 auto,与下面等价:

CSS

.item {
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: auto;
}
复制代码

MDN 描述

该项目根据其宽度和高度属性调整大小,但会增加以吸取flex容器中的任何额外自由空间,并会收缩到其最小尺寸以适合该容器,这等效于设置“ flex:1 1 auto”。

具备flex:auto的项目将根据其宽度和高度来调整大小,但它能够根据可用的额外空间来增大或缩小。 在研究本文以前,我不知道这一点!

HTML

<div class="wrapper">
  <div class="item item-1">Item</div>
  <div class="item">Item</div>
  <div class="item">Item</div>
</div>
复制代码

CSS

.wrapper {
    display: flex;
    flex-wrap: wrap;
}

.item {
    width: 120px;
    height: 500px;
}

.item-1 {
    flex: auto;
}
复制代码

事例源码:codepen.io/shadeed/pen…

CSS grid 和自动设置一个 auto

在CSS Grid中,咱们能够设置一个列为auto,这意味着它的宽度将基于它的内容长度。看看下面,你就知道个人意思了:

wrapper {
    display: grid;
    grid-template-columns: auto 1fr 1fr;
}
复制代码

grid 和 auto 边距

使用CSS网格时,可使用自动页边距实现相似于 flexbox 的结果。 当咱们有一个网格,而且其中的网格项目具备margin-left: auto时:该项目将被推到右边,其宽度将基于其内容长度

考虑下面的例子:

当咱们但愿item1的宽度基于其内容,而不是网格区域。 经过使用margin-left: auto,能够经过下面代码实实现:

.item-1 {
    margin-left: auto;
}
复制代码

从右向左布局

值得一提的是,使用margin-left: automargin-right: auto对于从左到右的布局(例如英语)可能效果很好。 可是,在多语言网站上工做时要小心颠覆这些价值观。 更好的是,使用flexboxgrid属性,以防使用它们完成工做。 若是没有,那么请使用自动页边距做为最后的选择,而应使用CSS逻辑属性

overflow 属性

当咱们有一个元素时,咱们应该考虑它应该包含的最小和最大内容。若是内容超过了最大值,那么咱们须要显示一个滚动条。

你可能想使用如下内容:

element {
  overflow-y: scroll;
}
复制代码

然而,这可能会显示一个滚动条,即便内容高度很短。参见下面的示例

在 Chrome 窗口中,滚动条老是显示出来,这是不正确和使人困惑的行为。

经过使用auto关键字,咱们能够确保滚动条不会显示,除非内容高度大于它的容器。

根据MDN

取决于用户代理。 若是内容适合填充框内部,则它看起来与可见内容相同,但仍会创建新的块格式化上下文。 若是内容溢出,桌面浏览器会提供滚动条。

.element {
  overflow-y: auto;
}
复制代码

position 属性

对于CSS定位属性toprightbottomleft,咱们可使用auto关键字做为它们的值。 接下来我要解释的是对我来讲是新的,我在研究本文时学到了它。

考虑下面的模型:

咱们有一个有内边距的 wrapper 元素,还有一个子项。子项目是绝对定位的,但没有任何定位属性。

.wrapper {
    position: relative;
    padding: 16px;
}

.item {
    position: absolute;
    width: 100px;
    height: 100px;
}
复制代码

在CSS中,每一个属性都有一个初始值/默认值。 若是我检查了子项并转到computed styles,你猜下left属性的值会是什么?

left的默认值为16px,即便没有设置。为何会发生这种状况? 好吧,缘由是绝对定位的元素相对于其最接近的父元素具备position:relative。 该父项具备padding: 16px,所以子项位于顶部和左侧的16px处。 有趣,不是吗?

如今,你可能会问,这样作有什么好处?好吧,让我继续。

假设子项必须在较小的视口中位于距左侧100像素的位置,对于桌面,它应恢复为默认位置

.wrapper {
    position: relative;
}

.item {
    position: absolute;
    left: 100px;
    width: 100px;
    height: 100px;
}
复制代码

如何在较大的视口中重设left? 咱们不能使用left:0,由于这会将子元素粘到边缘,这不是咱们想要的。 请参阅下面的模型,以了解个人意思。

要以正确的方式重置子项,咱们应该使用left: auto。 根据 MDN:

若是元素是静态元素,则将定位在它应该水平定位的位置

这意味着,它会尊重padding,而不会将子条目粘贴到其父条目的边缘。

.item {
    position: absolute;
    left: 100px;
    width: 100px;
    height: 100px;
}

@media (min-width: 800px) {
    .item {
        /* This is equivalent to left: 16px */
        left: auto;
    }
}
复制代码

top属性也是如此。 对于rightbottom属性,其默认计算值分别等于元素的宽度和高度。

事例源码:codepen.io/shadeed/pen…

你们都说简历没项目写,我就帮你们找了一个项目,还附赠【搭建教程】

用例和示例

值得一提的是,下面的用例可能还不够,可是我尝试添加一些用例,但愿它们对大家有用。

提示箭头

对于提示框,咱们须要一个指向箭头,以使其对用户更加清晰。 若是咱们正在设计系统上,则应该考虑多个状态。 例如,提示的箭头指向左侧,另外一个箭头指向右侧。

.tooltip:before {
    /* 箭头代码 */
    position: absolute;
    left: -15px;
}

/* 这是一个箭头指向右侧的版本*/
.tooltip.to-right:before {
    /* 箭头代码 */
    position: absolute;
    left: auto;
    right: -15px;

复制代码

请注意,在初始实现中,我使用left: auto来覆盖left: -15px。 供您参考,这是很是经常使用的,我建议改用如下内容:

.tooltip:before {
    position: absolute;
    right: 100%;
}

.tooltip.to-right:before {
    /* Arrow code */
    position: absolute;
    right: auto;
    left: 100%;
}
复制代码

经过使用100%,咱们避免了使用硬编码的值(箭头宽度),若是咱们改变箭头的大小,这个值可能会失败。这是一个更经得起时间考验的解决方案。

卡片组件

你可能有一个card组件,其左上角有一个操做,它可能仅用于装饰,也多是一个有用的操做。不论是什么,你都应该考虑到它是双向的。

经过使用left:auto,咱们能够很容易地重置它的基本实现。

.card .icon {
    position: absolute;
    left: 15px;
    top: 15px;
}

.card.is-right .icon {
    left: auto;
    right: 15px;
}    
复制代码

你们都说简历没项目写,我就帮你们找了一个项目,还附赠【搭建教程】

Flexbox 和 自动边距

当谈到flexbox时,它有无限的可能性。 经过将其与自动边距相结合,咱们能够构建功能强大的布局。

考虑下面的例子

咱们在右侧包含一行标题,描述和一个操做按钮的行。 咱们但愿操做按钮贴在右侧。

HTML

<div class="item">
    <div class="item-group">
        <!-- Title and description -->
    </div>
    <button class="item__action">Confirm</button>
</div>
复制代码

CSS

.item {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}

.item__action {
  margin-left: auto;
}
复制代码

就是这样! 经过使用margin-left: auto,将动做推到最右角。 更好的是,若是您要构建多语言网站,咱们可使用CSS逻辑属性。 CSS将以下所示:

.item__action {
    margin-inline-start: auto;
}
复制代码

CSS grid 和自动边距

在向网格项目添加边距时,它能够是固定值,百分比或自动值。 我对auto更感兴趣。 考虑如下:

HTML

<p class="input-group">
    <label for="">Full Name</label>
    <input type="email" name="" id="">
</p>
复制代码

CSS

.input-group {
  display: grid;
  grid-template-columns: 1fr;
  grid-gap: 1rem;

  @media (min-width: 700px) {
    grid-template-columns: 0.7fr 2fr;
  }
}
复制代码

我想将label 与input的左边缘对齐。 为此,我须要应用如下内容:

.input-group label {
    margin-left: auto;
}
复制代码

模态设计

在进行模态设计时,重要的是要考虑内容高度很大时会发生的状况。 对于这种状况,咱们可使用如下代码:

.modal-body {
    overflow-y: auto;
}
复制代码

这样,只有当内容高度足够大时,它才会显示滚动条。


代码部署后可能存在的BUG无法实时知道,过后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给你们推荐一个好用的BUG监控工具 Fundebug

原文:css-tricks.com/almanac/pro…


交流

文章每周持续更新,能够微信搜索「 大迁世界 」第一时间阅读和催更(比博客早一到两篇哟),本文 GitHub github.com/qq449245884… 已经收录,整理了不少个人文档,欢迎Star和完善,你们面试能够参照考点复习,另外关注公众号,后台回复福利,便可看到福利,你懂的。

相关文章
相关标签/搜索