自定义表单伪元素样式

当开发web应用程序时,表单样式是由客户端浏览器控制的,不同浏览器最终显示出来的样式各有差异,而且表单样式的美观度也达不到我们的预期。

现在,web 开发人可以通过伪元素给 web 渲染引擎添加钩子,控制表单的显示。然而,所有这些伪元素都是依赖于特定浏览器引擎的 (所以要带有浏览器引擎前缀),这样方便区分特定的浏览器引擎。

浏览器的内核

现在国内常见的浏览器有:IE、Firefox、QQ浏览器、Safari、Opera、Google Chrome、百度浏览器、搜狗浏览器、猎豹浏览器、360浏览器、UC浏览器、遨游浏览器、世界之窗浏览器等。但目前最为主流浏览器有五大款,分别是IE、Firefox、Google Chrome、Safari、Opera

浏览器最重要的部分是浏览器的内核。浏览器内核是浏览器的核心,用来解释网页语法并渲染到网页上。浏览器内核决定了浏览器该如何显示网页内容以及页面的格式信息。不同的浏览器内核对网页的语法解释也不同,因此网页开发者需要在不同内核的浏览器中测试网页的渲染效果。

浏览器内核又可以分成两部分:渲染引擎(layout engineer 或者 Rendering Engine)和 JS 引擎。最开始渲染引擎和 JS 引擎并没有区分的很明确,后来 JS 引擎越来越独立,内核就倾向于只指渲染引擎。

JS引擎

JS 引擎则是解析 Javascript 语言,执行 javascript 语言来实现网页的动态效果。主流的 JavaScript 引擎有:

  • V8

  • SpiderMonkey

  • JavaScriptCore

  • Chakra

渲染引擎

浏览器内核又叫渲染引擎,主要负责 HTML、CSS 的解析,页面布局、渲染与复合层合成。浏览器内核的不同带来的主要问题是对 CSS 的支持度与属性表现差异。

  • Trident内核:代表作品是IE,又称为 IE 内核或 MSHTML,此内核只能用于 Windows 平台,且不是开源的。

  • Gecko内核:代表作品是 Firefox,常被称为 firefox 内核。它是开源的,最大优势是跨平台,在Microsoft Windows、Linux、MacOs X等主 要操作系统中使用。

  • Webkit内核:代表作品是Safari、曾经的Chrome,是开源的项目。

  • Presto内核:(已弃用),代表作品是Opera。在13年之后,Opera宣布加入谷歌阵营,弃用了 Presto。

  • Blink内核:由 Google 和 Opera Software 开发的浏览器排版引擎,2013年4月发布。

浏览器内核与 JS 引擎

各浏览器前缀

  • -webkit- :WebKit 内核。如:谷歌、 Safari、 新版Opera浏览器 以及几乎所有 iOS 系统中的浏览器(包括iOS 系统中的火狐浏览器)

  • -moz- :Gecko 内核。如:火狐浏览器

  • -o- :Presto 内核。如:旧版Opera浏览器

  • -ms- :Trident 内核。IE浏览器 和 Edge浏览器

表单元素的伪元素

以下内容原文来源于伪元素控制表单样式,并参考了 伪元素表单控件默认样式重置与自定义大全,本人主要是对其中内容写了一些DEMO。另外,有一些个人的看法:

  • 各浏览器对伪元素的支持情况不一,目前为止(2020.08),使用需要谨慎。

  • 在chrome中,可以开启 shadow DOM,查看一些不在文档树的结构以及元素支持的伪元素。

    开启Shadow Dom:chrome开发者工具 -> 右上角三个竖排点 -> setting -> perferences -> elements -> show user agent shadow DOM。

  • 现有浏览器可能已经有更多支持的伪元素,具体可通过 shadow DOM元素查看。

  • 比较重要的一个属性 appearance,可以隐藏一些元素原生的一个样式。如:input、select。

一般而言,HTML5中表单的控件效果都是通过浏览器的 Shadow Dom 创建的,脱离文档主树,不受大环境 CSS 影响,要控制其 UI 只能使用浏览器开发的伪元素API接口。记住,只有部分的样式可以重置。

1. input[type=button]、input[type=reset]、input[type=submit]、button

Gecko: input 类型是 button,reset, 和 submit,还有 button 元素,有两个伪元素设置样式:

  • ::-moz-focus-outer

  • ::-moz-focus-inner

也许你用这些伪元素不能做很多事情,但是有一点重要的事情是,火狐可以应用他们添加border和padding。

<style>
    .box_11 button::-moz-focus-inner,
    .box_11 input::-moz-focus-inner {
        border: 1px dotted transparent;
        padding: 0 2px;
    }
</style>

<section class="box_11">
    <div>
        <button>button</button>
        <input type="reset" value="reset">
        <input type="submit">
        <input type="file">
        <input type="button" value="button">
    </div>
    <div class="element_item11">
        <button>button</button>
        <input type="reset" value="reset">
        <input type="submit">
        <input type="file">
        <input type="button" value="button">
    </div>
</section>

查看DEMO

2. input[type=checkbox] / input[type=radio]

**Trident:**IE浏览器引擎提供::-ms-check伪元素,来控制单选复选框的样式。

<style>
    .item_01 ::-ms-check {
        color: #0aa;
        background: #f2f2f2;
        padding: 10px;
        border: 1px solid #0aa;
    }
</style>
<section>
    <div class="item_01">
        <input type="checkbox">
        <input type="radio">
    </div>
</section>

查看DEMO

3. input[type=color]

**WebKit:**提供了两个伪元素, ::-webkit-color-swatch-wrapper::-webkit-color-swatch。目前 IE10 以及 FireFox21 还没有支持 input[type=color] ,自然也没有响应的伪元素支持,Chrome浏览器下可以。

<style>
    .box_02 input { width: 120px; }
    .item_02::-webkit-color-swatch-wrapper { 
        border: 1px solid #777;
        background-image: linear-gradient(to right, red, orange 15%, yellow 30%, green 50%, darkcyan 65%, blue 80%, purple);
    }
    .item_02::-webkit-color-swatch {
        height: 21px;
        position: relative;
        left: 135px;
        top: -5px; 
    }
</style>

<section class="box_02">
    <input type="color">
    <br /><br />
    <input class="item_02" type="color">
</section>

查看DEMO

4. input[type=date]

**WebKit:**下面8个伪元素是webkit专为定制输入日期

  • ::-webkit-datetime-edit:控制编辑区域

  • ::-webkit-datetime-edit-fields-wrapper:控制年月日这个区域

  • ::-webkit-datetime-edit-text:这是控制年月日之间的斜线或短横线

  • ::-webkit-datetime-edit-month-field:控制月份

  • ::-webkit-datetime-edit-day-field:控制具体日子

  • ::-webkit-datetime-edit-year-field:控制年份

  • ::-webkit-inner-spin-button:控制上下小箭头,即控制时期增减的两个小三角

  • ::-webkit-calendar-picker-indicator:控制下拉小箭头,即点击弹出日期选择框的小三角

下面有这些元素(Shadow Dom)的内部结构:

<style>
   .item_03::-webkit-datetime-edit { padding: 1em; background: #f2f2f2; }
   .item_03::-webkit-datetime-edit-fields-wrapper { background: silver; }
   .item_03::-webkit-datetime-edit-text { color: red; padding: 0 0.3em; }
   .item_03::-webkit-datetime-edit-month-field { color: blue; }
   .item_03::-webkit-datetime-edit-day-field { color: green; }
   .item_03::-webkit-datetime-edit-year-field { color: purple; }
   .item_03::-webkit-inner-spin-button { display: none; }
   .item_03::-webkit-calendar-picker-indicator { background: #f2f2f2; color: orange }   
</style>
<section>
   <input type="date">
   <br/><br/>
   <input class="item_03" type="date">
</section>

查看DEMO

5. input[type=file]

当我们写上<input type="file">,所有的渲染引擎会自动创建一个按钮。以前,这个按钮是完全不能设置样式的。然而,最近IE和webkit通过伪元素可以给他们添加样式了。

**Trident:**IE10可以使用 ::-ms-browse 伪元素给<input type="file">按钮添加样式,任何添加给普通按钮的样式,都可以应用给伪元素。

**WebKit:**Webkit使用 ::-webkit-file-upload-button 伪元素为 <input type="file"> 按钮添加样式,同样任何添加给普通按钮的样式,都可以应用给伪元素。

<style>
    .item_04::-ms-browse {
        background: #0aa;
        color: white;
        padding: 1em;
        border: 1px solid blue;
        line-height: 20px;
    }
    .item_04::-webkit-file-upload-button {
        background: #0aa;
        color: white;
        padding: 1em;
        border: 1px solid blue;
        line-height: 20px;
    }
</style>

<section>
    <input type="file">
    <input class="item_04" type="file">
</section>

查看DEMO

6. input[type=number]

**WebKit:**Webkit通过默认的数字选择器提供下拉列表一个控制。虽然不能对这样的元素做过多的控制,但是至少可以隐藏掉下来

以下三个伪元素可以控制:

  • ::-webkit-textfield-decoration-container: input内部、上下箭头以及填写数值的外部容器

  • ::-webkit-inner-spin-button:就是Chrome下上上下下的小小按钮。样式不一定生效,感觉最大功能主是隐藏按钮。

  • ::-webkit-outer-spin-button:??没测出来是做什么用

<style>
    .item_05::-webkit-textfield-decoration-container { border: 2px solid red; }
    .item_05::-webkit-inner-spin-button {
        /*color: red; // 无效
        background: blue; // 无效*/
        -webkit-appearance: none;
    }
    .item_05::-webkit-outer-spin-button {} 
</style>

<section>
    <input type="number">
    <br/><br/>
    <input class="item_05" type="number">
</section>

查看DEMO

7. input[type=password]

**Trident:**Trident引擎为密码输入框提供的一种控制,就是可以让他显示显示纯文本。而这个控制是通过 ::-ms-reveal 操作的。你可以在这个控制下修改包括字体颜色,背景色或是显示隐藏的效果。

<style>
    .item_06::-ms-reveal { color: white; background: #0aa; } 
</style>

<section>
    <input type="password">
    <br/> <br/>
    <input class="item_06" type="password">
</section>

查看DEMO

8. placeholder属性

**Gecko:**火狐引擎用伪元素 ::-moz-placeholder 控制占位符的文本样式。注意:火狐引擎从 :-moz-placeholder 在firefox的19版时改为 ::-moz-placeholder 。

**Trident:**Trident引擎为占位符文本提供的一个伪类而不是伪元素来设置样式。但是伪类 :-ms-input-placeholder,其他渲染引擎可以用其他的伪元素代替。

**WebKit:**Webkit引擎使用::-webkit-input-placeholder,他也可以修改占位符的字体颜色和字体属性

<style>
    .item_07::-moz-placeholder { color: red; } 
    .item_07:-ms-input-placeholder { color: red; } 
    .item_07::-webkit-input-placeholder { color: red; } 
</style>

<section>
    <input type="text" placeholder="placeholder">
    <input class="item_07" type="text" placeholder="placeholder">
</section>

查看DEMO

9. input[type=range]

**Gecko:**火狐在 Firefox22 版提供两个伪元素来设置范围元素的样式,可以给他应用尽可能多的样式

  • ::-moz-range-track:拖动轨道

  • ::-moz-range-thumb:拖动手柄

**Trident:**IE引擎为定制范围元素样式提供一系列很棒的伪元素:

  • ::-ms-fill-lower: 轨道手柄前面

  • ::-ms-fill-upper: 轨道手柄后面

  • ::-ms-ticks-before: 跟踪刻度线范围上

  • ::-ms-ticks-after: 跟踪刻度线范围下

  • ::-ms-thumb: 拖动手柄

  • ::-ms-track: 轨道

  • ::ms-tooltip: 在用户选择一个范围元素时显示工具。注意,这个元素不能设置样式,只能用display隐藏。

**WebKit:**Webkit为范围元素提供两个伪元素,然而不能给他们添加过多的样式,你可以添加一些颜色和留白

  • ::-webkit-slider-runnable-track:拖动轨道

  • ::-webkit-slider-thumb:拖动手柄

<style>
    .item_08::-moz-range-track {
        border: 2px solid red;
        height: 20px;
        background: orange;
    }
    .item_08::-moz-range-thumb { background: blue; height: 30px; }
    .item_08::-ms-fill-lower { background: orange; }
    .item_08::-ms-fill-upper { background: green; }
    .item_08::-ms-ticks-after { display: block; color: blue; }
    .item_08::-ms-ticks-before { display: block; color: red; }
    .item_08::-ms-thumb { background: red; }
    .item_08::-ms-track { padding: 20px 0; }
    .item_08::-ms-tooltip { display: none; /* display and visibility only */ }  
    .item_08::-webkit-slider-runnable-track {
        border: 2px solid #0aa;
        background: #f2f2f2;
        padding: 5px 0;
    }
    .item_08::-webkit-slider-thumb { outline: 2px solid #0aa; }
</style>

<section>
    <input type="range">
    <br /> <br />
    <input class="item_08" type="range">
</section>

查看DEMO

**WebKit:**默认为搜索框提供一个定制的 ui 带有取消和搜索按钮的伪元素,可以提供定制样式,但除了隐藏,不能做再多的操作。

  • ::-webkit-search-cancel-button

  • ::-webkit-search-results-button

<style>
    .item_09 { -webkit-appearance: none; }
    .item_09::-webkit-search-cancel-button { -webkit-appearance: none; }
    .item_09::-webkit-search-results-button { -webkit-appearance: none; }  
</style>

<section>
    <input type="search">
    <br /> <br />
    <input class="item_09" type="search">
</section>

查看DEMO

11. input[type=text]

**Trident:**IE10使用 ::-ms-value 为文本输入框提供样式(文本输入框,密码输入框等等)和下拉列表,::-ms-clear 控制清除按钮。

<style>
    .item_10 input { appearance: none; border: 1px solid #0aa; }
    .item_10 ::-ms-value { color: white; background: #0aa; padding: 10px; }
    .item_10 ::-ms-clear { color: #0aa; background: #f2f2f2; padding: 10px; }
</style>

<section>
    <div>
        <input type="text" value="value">
        <input type="password" value="value">
        <select>
            <option selected>option</option>
        </select>
    </div>
    <div class="item_10">
        <input type="text" value="value">
        <input type="password" value="value">
        <select>
            <option selected>option</option>
        </select>
    </div>
</section>

查看DEMO

12. meter元素

WebKit: Webkit提供以下伪元素用于meter元素的显示样式。

  • ::-webkit-meter-bar:条

  • ::-webkit-meter-even-less-good-value:得分不好时状态

  • ::-webkit-meter-optimum-value:得分好时状态

  • ::-webkit-meter-suboptimal-value:得分一般时状态

后面三个只有一个,会在给定时间依据 meter 的value 值处于激活状态。

<style>
    .item_12 ::-webkit-meter-bar {
        height: 30px;
        background: #f2f2f2;
        border: 1px solid #0aa;
    }
    .item_12 ::-webkit-meter-optimum-value { background: green; }
    .item_12 ::-webkit-meter-suboptimum-value { background: orange; }
    .item_12 ::-webkit-meter-even-less-good-value { background: blue; }    
</style>

<section>
    <div>
        <meter low="69" high="80" max="100" optimum="100" value="92">A</meter>
        <meter low="69" high="80" max="100" optimum="100" value="72">C</meter>
        <meter low="69" high="80" max="100" optimum="100" value="52">E</meter> 
    </div>
    <div class="item_12">
        <meter low="69" high="80" max="100" optimum="100" value="92">A</meter>
        <meter low="69" high="80" max="100" optimum="100" value="72">C</meter>
        <meter low="69" high="80" max="100" optimum="100" value="52">E</meter> 
    </div>
</section>

查看DEMO

13. progress元素

WebKit: Webkit提供三个伪元素,用于进度条样式(必须给进度条元素设置 -webkit-appearance: none)。

  • ::-webkit-progress-inner-element

  • ::-webkit-progress-bar

  • ::-webkit-progress-value

**Gecko:**Gecko为进度条提供 ::-moz-progress-bar 来设置样式。

Trident: 像火狐一样,IE给进度条提供单一的伪元素::-ms-fill。

<style>
    .item_13 progress { -webkit-appearance: none; }
    .item_13 ::-webkit-progress-inner-element { background: black; }
    .item_13 ::-webkit-progress-bar { border: 2px solid #0aa; }
    .item_13 ::-webkit-progress-value { background: orange; }
    .item_13 ::-moz-progress-bar { background: red; }
    .item_13 ::-ms-fill { background: red; }
</style>

<section>
    <div>
        <progress max="100" value="50"></progress> 
        <progress max="100" value="75"></progress> 
        <progress max="100" value="90"></progress> 
    </div>
    <div class="item_13">
        <progress max="100" value="50"></progress> 
        <progress max="100" value="75"></progress> 
        <progress max="100" value="90"></progress> 
    </div>
</section>

查看DEMO

14. select元素

Trident: IE10提供::-ms-expand用来修改下拉列表的箭头样式。

<style>
    .item_14 { border: 1px solid #0aa; }
    .item_14::-ms-expand {
        padding: 10px;
        color: red;
        background: #0aa;
        border: 1px solid #0aa;
    }
</style>

<section>
    <select>
        <option selected>One</option>
    </select>
    <br/><br/>
    <select class="item_14">
        <option selected>One</option>
    </select>  
</section>

查看DEMO

15. textarea元素

WebKit: Webkit提供的 ::-webkit-resizer 用于可以自动控制尺寸的元素,把它添加到文本域的右下角。

::-webkit-resizer 可以用个display:none或是-webkit-appearance: none:隐藏掉,但并不能阻止用户修改 textarea 的尺寸。如果你禁用尺寸调整,可以设置css属性resize:none。这个不仅可以隐藏控制,也可以在所有浏览器都禁用文本域尺寸调整。

使用 ::-webkit-resizer 也可以添加一些基本的样式。

<style>
    .item_15 { resize: none; }
    .item_15::-webkit-resizer {
        displaynone;
        -webkit-appearance: none;

        /*border: 1px solid #0aa;*/
        /*background: #0aa;*/
        /*outline: 1px solid yellow;*/
    } 
</style>

<section>
    <textarea></textarea>
    <textarea class="item_15"></textarea>
</section>

查看DEMO

16. 表单验证信息

WebKit: Webkit是唯一支持约束验证api创建验证冒泡的渲染引擎。提供的伪元素如下:

  • ::-webkit-validation-bubble:整个弹出框区域

  • ::-webkit-validation-bubble-arrow: 弹出框的尖角

  • ::-webkit-validation-bubble-arrow-clipper:弹出框尖角所在块状区域

  • ::-webkit-validation-bubble-heading: 文字标题占据区域

  • ::-webkit-validation-bubble-message:文字提示的整个方形的信息框

  • ::-webkit-validation-bubble-text-block:文字所在block块区域

<!--chrome测试,无法修复验证框的样式-->
<style type="text/css">
    .item_16 { border: 1px solid #0aa; }
    .item_16::-webkit-validation-bubble { padding: 1em;  background: red;  }
    .item_16::-webkit-validation-bubble-arrow { background: blue;  }
    .item_16::-webkit-validation-bubble-arrow-clipper { border: 2px solid black;  }
    .item_16::-webkit-validation-bubble-heading { background: green;  }
    .item_16::-webkit-validation-bubble-message { color: white;  background: purple;  }
    .item_16::-webkit-validation-bubble-text-block { border: 1px solid red;  padding: 1em; }
</style>

<section>
    <form class="item_16">
        <input type="email" required>
        <br /><br />
        <input type="submit">
    </form>
</section>

查看DEMO

参考链接

伪元素控制表单样式

伪元素表单控件默认样式重置与自定义大全

最后更新于