代码之家  ›  专栏  ›  技术社区  ›  Andreas Gohr

表单元素和链接具有相同高度的最小CSS

  •  5
  • Andreas Gohr  · 技术社区  · 6 年前

    在我的项目中一次又一次出现的问题是,将表单元素和链接设置为具有相同的高度。

    下面是一个简单的例子( fiddle ):

    HTML格式:

    <select><option>one</option></select>
    <input type="text">
    <button>foo</button>
    <a href="foo">test</a>
    

    select,
    input,
    button,
    a {
      padding: 0.5rem;
      margin: 0.25rem;
      border: 1px solid red;
    }
    

    所有元素都采用完全相同的样式,包括填充、边距和边框。但他们的身高都略有不同,我真的不明白为什么。

    有人可以吗

    1. 解释差异从何而来?Chrome inspector告诉我,每一个的实际内部元素都有不同的大小-不应该是相同的吗?
    2. 告诉我我需要对CSS做些什么最小的修改来实现我想要的,而不需要对每个元素进行稍微不同的样式设置?我的目标是自由选择填充、边距和边框大小(使用变量),并且保持高度一致。

    Updated fiddle with solution

    3 回复  |  直到 6 年前
        1
  •  2
  •   Stickers    6 年前

    这个 最小 版本:

    您需要添加以下附加规则:

    select,
    input,
    button,
    a {
      padding: 0.5rem;
      margin: 0.25rem;
      border: 1px solid red;
      display: inline-block; /*new*/
      font: inherit;         /*new*/
    }
    

    但这仍不能保证它们在某些浏览器中接收到的某些输入类型的高度相同。你也可以重新设置外观,但我不建议这样做全球,除非它的设计要求。

    -webkit-appearance: none;
    appearance: none;
    

    非最小值 版本:

    *,
    *:before,
    *:after {
      box-sizing: border-box;
    }
    
    ::-moz-focus-inner {
      border-style: none;
      padding: 0;
    }
    
    ::-webkit-file-upload-button {
      font: inherit;
      -webkit-appearance: button;
    }
    
    ::-webkit-inner-spin-button,
    ::-webkit-outer-spin-button {
      height: auto;
    }
    
    ::-webkit-search-cancel-button,
    ::-webkit-search-decoration {
      -webkit-appearance: none;
    }
    
    button,
    input,
    optgroup,
    select,
    textarea {
      font-family: inherit;
      font-size: 1rem;
      line-height: 1.15;
      margin: 0;
    }
    
    button,
    input {
      overflow: visible;
    }
    
    button,
    select {
      text-transform: none;
    }
    
    [type="checkbox"],
    [type="radio"] {
      padding: 0;
    }
    
    [type="search"] {
      outline-offset: -2px;
      -webkit-appearance: textfield;
    }
    
    [type="color"],
    [type="date"],
    [type="datetime"],
    [type="datetime-local"],
    [type="email"],
    [type="month"],
    [type="number"],
    [type="password"],
    [type="search"],
    [type="tel"],
    [type="text"],
    [type="time"],
    [type="url"],
    [type="week"],
    select,
    textarea,
    button,
    [type="button"],
    [type="reset"],
    [type="submit"] {
      display: inline-block;
      vertical-align: middle;
      height: calc(2.25rem + 2px);
      color: #333;
      border: 1px solid #ccc;
      border-radius: 3px;
    }
    
    [type="color"],
    [type="date"],
    [type="datetime"],
    [type="datetime-local"],
    [type="email"],
    [type="month"],
    [type="number"],
    [type="password"],
    [type="search"],
    [type="tel"],
    [type="text"],
    [type="time"],
    [type="url"],
    [type="week"],
    select,
    textarea {
      max-width: 100%;
      padding: 0.5rem;
      background-clip: padding-box;
      background-color: #fff;
      box-shadow: inset 1px 1px 2px rgba(0, 0, 0, 0.1);
    }
    
    [type="color"]:focus,
    [type="date"]:focus,
    [type="datetime"]:focus,
    [type="datetime-local"]:focus,
    [type="email"]:focus,
    [type="month"]:focus,
    [type="number"]:focus,
    [type="password"]:focus,
    [type="search"]:focus,
    [type="tel"]:focus,
    [type="text"]:focus,
    [type="time"]:focus,
    [type="url"]:focus,
    [type="week"]:focus,
    select:focus,
    textarea:focus {
      border-color: rgb(30, 144, 255);
      box-shadow: 0 0 2px rgba(30, 144, 255, 0.8);
      outline: 0;
    }
    
    button,
    [type="button"],
    [type="reset"],
    [type="submit"] {
      padding: 0.5rem 0.75rem;
      background-color: #f7f7f7;
      box-shadow: 0 1px 0 #ccc;
      cursor: pointer;
      -webkit-appearance: button;
    }
    
    button:hover,
    [type="button"]:hover,
    [type="reset"]:hover,
    [type="submit"]:hover {
      background-color: #fafafa;
      border-color: #999;
    }
    
    button:focus,
    [type="button"]:focus,
    [type="reset"]:focus,
    [type="submit"]:focus {
      border-color: rgb(30, 144, 255);
      box-shadow: 0 0 2px rgba(30, 144, 255, 0.8);
      outline: 0;
    }
    
    button:active,
    [type="button"]:active,
    [type="reset"]:active,
    [type="submit"]:active {
      background-color: #eee;
      border-color: #999;
      box-shadow: inset 0 2px 5px -3px rgba(0, 0, 0, 0.5);
    }
    
    button:disabled,
    [type="button"]:disabled,
    [type="reset"]:disabled,
    [type="submit"]:disabled {
      background-color: #f7f7f7;
      color: #a0a5aa;
      border-color: #ddd;
      box-shadow: none;
      text-shadow: 0 1px 0 #fff;
      cursor: default;
    }
    
    select {
      -moz-appearance: textfield;
      -webkit-appearance: textfield;
    }
    
    select::-ms-expand {
      display: none;
    }
    
    select[multiple],
    select[size]:not([size="1"]) {
      height: auto;
      padding: 0;
    }
    
    select[multiple] option,
    select[size]:not([size="1"]) option {
      padding: 0.5rem;
    }
    
    select:not([multiple]):not([size]),
    select:not([multiple])[size="1"] {
      padding-right: 2rem;
      background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z'/%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3C/svg%3E") right 0.25rem center no-repeat;
    }
    
    textarea {
      height: auto;
      overflow: auto;
    }
    <select>
      <option>one</option>
    </select>
    <input type="text" placeholder="text">
    <button>foo</button>

    上面的大部分代码都不会直接回答问题,甚至不相关,也不包括 <a>

        2
  •  1
  •   Quentin    6 年前

    (仅用铬测试)

    解释差异从何而来?

    它来自 用户代理样式表 为每个应用不同的样式作为默认样式 标签 .
    这些样式会根据浏览器的不同而变化。


    输入 , 选择 标记有一个默认字体大小,它不是从body字体大小声明继承的。将其字体大小值设置为 inherit .

    input, select, button { 
      font-size: inherit; 
    }
    

    默认情况下,标记是内联的。将其值设置为 inline-block .
    另外,将其“框大小”值设置为 border-box .

    a { 
      display: inline-block; 
      box-sizing: border-box;
    }
    

    选择 有一个最大的高度内容,因为它的下拉图标。
    您可以通过删除它的默认外观来修复它,但我不建议这样做。

    select {
      -webkit-appearance: none;
    }
    

    演示

    body {
      font-size: 16px
    }
    
    select,
    input,
    button,
    a {
      padding: 0.5rem;
      margin: 0.25rem;
      border: 1px solid red;
      vertical-align: top;
    }
    
    input,
    select,
    button {
      font-size: inherit;
    }
    
    a {
      display: inline-block;
      box-sizing: border-box;
    }
    
    /* Bad practice */
    select {
      -webkit-appearance: none;
    }
    <select>
      <option>Select</option> 
    </select>
    <input type="text" value="Input">
    <button>Button</button>
    <a href="#">Link</a>

    另一个解决办法是 height line-height

    body {
      font-size: 16px
    }
    
    select,
    input,
    button,
    a {
      height: 40px;
      line-height: 40px;
      display: inline-block;
      vertical-align: top;
      margin: 0.25rem;
      padding: 0 0.5rem;
      border: 1px solid red;
      font-size: inherit;
      box-sizing: border-box;
    }
    <选择>
    <选项>选择</选项>
    </选择>
    <按钮>按钮</按钮>
    <a href=“#”>链接</a>
        3
  •  0
  •   wtitus    6 年前

    1 据我所知,表单元素的CSS规范非常松散,因此很难同时将样式应用于许多不同类型的表单元素。因此,这些不同的元素都以不同的方式应用样式规则。

    2

    body {
    font-size: 16px;
    }
    
    select,
    input,
    button,
    a {
    padding: 0.5rem;
    margin: 0.25rem;
    border: 1px solid red;
    font: 1rem "Helvetica", sans-serif;
    }
    

    你可以把这个字体改成你喜欢的任何字体,它应该还能用。这种风格主要完成的是“规范化”一切,尤其是“a”元素。“a”元素似乎希望保留其初始字体系列和某种形式的初始字体大小。因此,使用字体样式,可以确保每个元素都继承了带有1rem的正文字体大小,并且每个元素都有一个一致的字体。