美化表单——自定义单选按钮和复选按钮

发布于 大漠

大家都知道,在Web的Form中美化是最头痛的,尤其是表单中的“input[type=checkbox]”、“input[type="radio"]”、“input[type=file]”和select这些元素我们单单只使用CSS是无法匹配设计图的,像背景颜色或者背景图片,甚至说margin和padding等等在各浏览器下都没法实现一致的效果,具体大家可以看看这里所展示的页面效果。为了解决这样的问题,我们只有另选其他的途径。使用CSS和js配合,使用他们实现各浏览器的统一样式。

前面我在本站也介绍了这方面的知识点,比如说《自定义表单——美化你的文件载入框》中介绍了如何通过js和css来美化表单中的文件载入框(input[type=file]),在《自定义表单——jQuery制作个性化Checkbox》中介绍了如何通过jQuery和CSS3来美化复选按钮的效果。那么今天我想和大家一起在学习另外一个有关于表单元素的美化知识——自定义单选按钮和复选按钮。就如下面DEMO展示的效果一样:

一、准备工作

上面DEMO展示的单选和复选按钮是不是很靓呀,为了达到上面的那种DEMO效果,我们需要准备两张背景图片:

这两张图就是我们所需要制作的“单选按钮”和“复选按钮”的效果图,我们后期将会使用“sprites”技术,将其当作背景应用到我们表单中,从而实现表单的美化效果。

二、HTML Markup

我们先按照下面的几个条件创建一个基本的表单:

  1. 给每个ipnut定义一个唯一的ID名称;
  2. 给每个input匹配一个label标签;
  3. 匹配好每个label中的“for”属性,其中“for”值对应其匹配的“input”的“ID”名;
  4. 对于单选按钮,如果其是一组的,我们还需要给他们定义一个相同的“name”名。

根据上面的要求,写了一个简单的HTML Markup

			<form class="form" method="post">
				<fieldset>
					<legend>Which genres do you like?</legend>
					<input type="checkbox" value="action" id="check-1" name="genre"><label for="check-1" class="">Action / Adventure</label>
					<input type="checkbox" value="comedy" id="check-2" name="genre"><label for="check-2" class="">Comedy</label>
					<input type="checkbox" value="epic" id="check-3" name="genre"><label for="check-3" class="">Epic / Historical</label>
					<input type="checkbox" value="science" id="check-4" name="genre"><label for="check-4" class="">Science Fiction</label>
					<input type="checkbox" value="romance" id="check-5" name="genre"><label for="check-5" class="">Romance</label>
					<input type="checkbox" value="western" id="check-6" name="genre"><label for="check-6" class="">Western</label>
				</fieldset>	
				<fieldset>
					<legend>Caddyshack is the greatest movie of all time, right?</legend>
					<input type="radio" value="1" id="radio-1" name="opinions"><label for="radio-1" class="">Totally</label>
					<input type="radio" value="1" id="radio-2" name="opinions"><label for="radio-2" class="">You must be kidding</label>
					<input type="radio" value="1" id="radio-3" name="opinions"><label for="radio-3" class="">What's Caddyshack?</label>
				</fieldset>
			</form>
		

这里有一点是非常得要的,正确的配对input和label标签是必不可以的。这样做的好处是,我们点击了一个标签能选中相对应的选择按钮。

当我们后面把所需的脚本加截进来后,我们会发现,我们每一对标签外增加了一个“div”标签,这一点后面我们可以通过firefox的插件firebug速度查看得知:

三、CSS Code

有了基本结构,我们就需要通过CSS样式来美化这个表单,说得简单一点就是美化我们今天所说的“单选按钮”和“复选按钮”,我们主要分以下几步来细化这些样式:

我们前面得知,通过后面的脚本加入后,我们每一组选项会在外部增加一个“div”容器,那么我们需要使用绝对定位,将“input”元素标签和“label”背景图片定位到一起:

			/* wrapper divs */
			.custom-checkbox, 
			.custom-radio { 
				position: relative; 
			}
			/* input, label positioning */
			.custom-checkbox input,
			.custom-radio input {
				position: absolute;
				left: 2px;
				top: 3px;
				margin: 0;
				z-index: 0;
			}
			.custom-checkbox label,
			.custom-radio label {
				display: block;
				position: relative;
				z-index: 1;
				font-size: 1.3em;
				padding-right: 1em;
				line-height: 1;
				padding: .5em 0 .5em 30px;
				margin: 0 0 .3em;
				cursor: pointer;
			}
		

接下来这一步是相当的关键,我们使用“sprites”技术,在label上设置不同状态下的背景图片,比如说默认状态、鼠标悬停状态,得到焦点和失去焦点的状态。

			/* ==默认状态效果== */
			.custom-checkbox label { 
				background: url(images/checkbox.gif) no-repeat; 
			}
			.custom-radio label { 
				background: url(images/radiobutton.gif) no-repeat; 
			}
			.custom-checkbox label, 
			.custom-radio label {
				background-position: -10px -14px;
			}
			
			/*==鼠标悬停和得到焦点状态==*/
			.custom-checkbox label.hover,
			.custom-checkbox label.focus,
			.custom-radio label.hover,
			.custom-radio label.focus {
				background-position: -10px -114px;
			}
			
			/*==选中状态==*/
			.custom-checkbox label.checked,
			.custom-radio label.checked {
				background-position: -10px -214px;
			}
			.custom-checkbox label.checkedHover,
			.custom-checkbox label.checkedFocus {
				background-position: -10px -314px;
			}
			.custom-checkbox label.focus,
			.custom-radio label.focus {
				outline: 1px dotted #ccc;
			}
		

实现上面DEMO所有CSS CODE

			/* page styles */
			body {
				font-size: 62.5%;
			}
			fieldset {
				padding: 0 15px 3em;
				border: 0;
			}
			legend {
				font-size: 1.4em;
				font-weight: bold;
				padding: .2em 5px;
			}
			/* wrapper divs */
			.custom-checkbox, 
			.custom-radio { 
				position: relative; 
			}
			/* input, label positioning */
			.custom-checkbox input,
			.custom-radio input {
				position: absolute;
				left: 2px;
				top: 3px;
				margin: 0;
				z-index: 0;
			}
			.custom-checkbox label,
			.custom-radio label {
				display: block;
				position: relative;
				z-index: 1;
				font-size: 1.3em;
				padding-right: 1em;
				line-height: 1;
				padding: .5em 0 .5em 30px;
				margin: 0 0 .3em;
				cursor: pointer;
			}
			/* states */
			.custom-checkbox label { 
				background: url(images/checkbox.gif) no-repeat; 
			}
			.custom-radio label { 
				background: url(images/radiobutton.gif) no-repeat; 
			}
			.custom-checkbox label, 
			.custom-radio label {
				background-position: -10px -14px;
			}
			.custom-checkbox label.hover,
			.custom-checkbox label.focus,
			.custom-radio label.hover,
			.custom-radio label.focus {
				background-position: -10px -114px;
			}
			.custom-checkbox label.checked,
			.custom-radio label.checked {
				background-position: -10px -214px;
			}
			.custom-checkbox label.checkedHover,
			.custom-checkbox label.checkedFocus {
				background-position: -10px -314px;
			}
			.custom-checkbox label.focus,
			.custom-radio label.focus {
				outline: 1px dotted #ccc;
			}
		

四、jQuery Code

平时我们有结构有样式就能看到效果,但这个不一样,因为我们需要下面的脚本,如果没有这个脚本,我们上面做的一切都是徒劳无功的。这个脚本是由Maggie在《Accessible, Custom Designed Checkbox and Radio Button Inputs Styled with CSS (and a dash of jQuery)》中写了一个customInput.jquery.js插件,大家可以直接从前面的地址中下载这个插件,也可以直接copy下面的代码,保存到你的文件中:

			jQuery.fn.customInput = function(){
				$(this).each(function(i){
					if($(this).is('[type=checkbox],[type=radio]')){
						var input = $(this);
						//get the associated label using the input's id
						var label = $('label[for='+input.attr('id')+']');
						//get type,for classname suffix
						var inputType = (input.is('[type=checkbox]')) ? 'checkbox' : 'radio';
						//wrap the input + label in a div
						$('<div class="custom-'+ inputType +'"></div>').insertBefore(input).append(input,label);
						//find all inputs in this set using the shared name attribute
						var allInputs = $('input[name='+input.attr('name')+']');
						//necessary for browsers that don't support the :hover pseudo class on labels
						label.hover(function(){
							$(this).addClass('hover');
							if(inputType == 'checkbox' && input.is(':checked')) {
								$(this).addClass('checkedHover');
							}
						},function(){
							$(this).removeClass('hover checkedHover');
						});
						
						//bind custom event, trigger it, bind click,focus,blur events
						input.bind('updateState',function(){
							if(input.is(':checked')){
								if(input.is(':radio')){
									allInputs.each(function(){
										$('label[for='+$(this).attr('id')+']').removeClass('checked');
									});
								};
								label.addClass('checked');
							} else {
								label.removeClass('checked checkedHover checkedFocus');
							}
						})
						.trigger('updateState')
						.click(function(){
							$(this).trigger('updateState');
						})
						.focus(function(){
							label.addClass('focus');
							if(inputType == 'checkbox' && input.is(':checked')) {
								$(this).addClass('checkedFocus');
							}
						})
						.blur(function(){
							label.removeClass('focus checkedFocus');
						});					
					}
				});
			}
		

现在有了这个插件,我们就可以按下面的方法载入这个插件了,当然在使用这个插件之前,我们还需要jQuery版本库配合,具体可以按下面的来操作:

			<script type="text/javascript" src="js/jquery.min.js"></script>
			<script type="text/javascript" src="js/customInput.jquery.js"></script>
		

现在版本库和插件都导入到Web页面中了,那么我们最后一步就是需要调用这个对象:

			$('input').customInput();
		

到此我们就最终完成效果所需的代码,如果你上面的每一步都没有出错的话,你将看到下面的效果:

不知道你实现了效果没有,不过我本地测试是OK了,那么我们今天有关于表单美化的另个知识点就和大家探讨到此。希望大家喜欢这样的教程,更希望此教程对大家在平时的工作中有所帮助。谢谢大家。

如需转载烦请注明出处:W3CPLUS

Zoom Kobe 1 Protro