安卓自定义输入框样式_样式和自定义文件输入的智能方式

安卓自定义输入框样式

安卓自定义输入框样式

CustomFileInputs

There are quite a few techniques for “customizing” the <input type="file" /> element. I tried most of them, but none was good enough to have on Readerrr (for importing feeds by uploading a file). Probably the worst technique was the one where the input element is put into a container (which imitates a button), and the input follows the cursor so that when you click anywhere on the container, you actually click the input. Sounds interesting and weird at the same time, right? Anyway, it had some unacceptable drawbacks (usability, touch).

有很多技术可以“自定义” <input type="file" />元素。 我尝试了其中的大多数,但没有一个能比Readerrr更好(用于通过上传文件导入供稿)。 可能最糟糕的技术是将输入元素放入容器(模仿按钮),并且输入跟随光标,因此当您在容器上的任何位置单击时,实际上都单击了输入。 听起来既有趣又怪异,对吗? 无论如何,它有一些无法接受的缺点(可用性, touch )。

As as result, I tried googling for an unseen solution. Once it seemed that there was nothing new, my I eyes were caught by a comment on StackOverflow. It had just a few up votes and was lost somewhere in the middle of the page, but most importantly it contained a magic word – <label>! As you may know, pressing a label basically triggers the focus event for the bound input. Interesting thing is that, if it is a file input, it works out as a click event, resulting in opening a file browser. This is great for crafting a semantic solution.

结果,我尝试使用Google搜索来寻找一个看不见的解决方案。 一旦似乎没有什么新东西,我对StackOverflow的评论就引起了我的注意。 它只有几票赞成票,在页面中间某处丢失,但最重要的是,它包含一个神奇的词– <label> ! 如您所知,按下标签基本上会触发绑定输入的焦点事件。 有趣的是,如果是文件输入,它将作为单击事件工作,从而导致打开文件浏览器。 这对于设计语义解决方案非常有用。

<input type="file" name="file" id="file" class="inputfile" />
<label for="file">Choose a file</label>

So, pressing any of these two elements gives us the same result. That means that the most difficult part is… solved! No JavaScript, no other complex solutions like cursor position tracking, just these two lines. See for yourself:

因此,按这两个元素中的任何一个都可以得到相同的结果。 这意味着最困难的部分已经解决了! 没有JavaScript,没有其​​他复杂的解决方案(如光标位置跟踪),只有这两行。 你自己看:

Now let’s just style it and make this look like a normal button.

现在,让我们对其进行样式设置,使其看起来像普通按钮。

隐藏<input> (Hiding the <input>)

First off, we need to hide the ugly duckling. CSS properties such as display: none or visibility: hidden will not work out. The reasons are: the input value will not be sent to the server on form submit; the input will be excluded out of tab order (you want your website to be accessible, right?). I set up a combination of CSS properties/values for hiding the input visually but keeping it visible for the browser:

首先,我们需要隐藏丑小鸭。 CSS属性,例如display: nonevisibility: hidden不起作用。 原因是:输入值不会在表单提交时发送到服务器; 输入将被排除在选项卡顺序之外(您希望访问网站,对吗?)。 我设置了CSS属性/值的组合,以可视方式隐藏输入,但在浏览器中保持可见

.inputfile {
	width: 0.1px;
	height: 0.1px;
	opacity: 0;
	overflow: hidden;
	position: absolute;
	z-index: -1;
}

I see you are wondering why width and height are set to 0.1px instead of just 0px. Setting the property values to zero ends up throwing the element out of tab party in some browsers. And position: absolute guarantees the element does not interfere with the sibling elements.

我看到您想知道为什么将widthheight设置为0.1px而不是0px 。 将属性值设置为零最终会在某些浏览器中将元素扔出制表符。 和position: absolute保证元素不会干扰同级元素。

设置<label>样式 (Styling the <label>)

Since the <label> element is visually the button, you can use all of your creative CSS juices on it. I’m sticking to something very simple for now:

由于<label>元素在外观上是按钮,因此可以在其上使用所有创意CSS汁。 我现在坚持一些非常简单的方法:

.inputfile + label {
    font-size: 1.25em;
    font-weight: 700;
    color: white;
    background-color: black;
    display: inline-block;
}

.inputfile:focus + label,
.inputfile + label:hover {
    background-color: red;
}

辅助功能 (Accessibility)

How do you know that an element on the website is pressable? Firstly, the element should communicate a feeling that you can tap or click on it. Secondly, the cursor icon should change to an appropriate one when hovering the element. The former we’ve solved previously, let’s solve the latter, because labels do not trigger a cursor change by default:

您如何知道网站上的某个元素是可按下的? 首先,该元素应传达您可以点击或单击它的感觉。 其次,将鼠标悬停在元素上时,光标图标应更改为适当的图标。 我们之前已经解决了前者,让我们解决了后者,因为标签默认情况下不会触发游标更改:

.inputfile + label {
	cursor: pointer; /* "hand" cursor */
}

键盘导航 (Keyboard Navigation)

If users are unable to navigate on your website using just a keyboard, you are doing something wrong. Hiding the input itself in a correct manner was one thing, the other is indicating when the element is focused, i.e. rendering .inputfile:focus on the label:

如果用户仅使用键盘无法浏览您的网站,则说明您做错了。 以正确的方式隐藏输入本身是一回事,另一件事是指示元素何时被聚焦,即在label上呈现.inputfile:focus

.inputfile:focus + label {
	outline: 1px dotted #000;
	outline: -webkit-focus-ring-color auto 5px;
}

-webkit-focus-ring-color auto 5px is a little trick for obtaining default outline looks on Chrome, Opera and Safari. The style in the line above is for browsers that do not understand the -webkit… expression.

-webkit-focus-ring-color auto 5px是在Chrome,Opera和Safari上获取默认轮廓外观的小技巧。 上一行中的样式适用于不了解-webkit…表达式的浏览器。

可能的触摸问题 (Possible Touch Issues)

In case you’ve been using FastClick (a library for eliminating the 300ms tap-pause on touch-capable devices) and have plans to add some extra markup to the content of a label, the button won’t work as it should, unless you use pointer-events: none, respectively:

如果您一直在使用FastClick (用于消除具有触摸功能的设备上300ms的点击暂停的库)并计划在标签内容上添加一些额外的标记,则该按钮将无法正常工作,除非您分别使用pointer-events: none

<label for="file"><strong>Choose a file</strong></label>
.inputfile + label * {
	pointer-events: none;
}

JavaScript增强 (JavaScript Enhancement)

Probably and hopefully the last thing missing is indicating if files were selected. The file input does usually indicate that, but in our case the input is visually hidden. Luckily, there is a way out: a tiny JavaScript enhancement. The text of a label becomes the name of the selected file. If there were multiple files selected, the text will tell us how many of them were selected.

可能并且希望最后缺少的内容是指示是否选择了文件。 文件输入通常确实表明了这一点,但在我们的情况下,该输入在视觉上是隐藏的。 幸运的是,有一条出路:很小JavaScript增强。 标签的文本将成为所选文件的名称。 如果选择了多个文件,文本将告诉我们选择了多少个文件。

<input type="file" name="file" id="file" class="inputfile" data-multiple-caption="{count} files selected" multiple />
var inputs = document.querySelectorAll( '.inputfile' );
Array.prototype.forEach.call( inputs, function( input )
{
	var label	 = input.nextElementSibling,
		labelVal = label.innerHTML;

	input.addEventListener( 'change', function( e )
	{
		var fileName = '';
		if( this.files && this.files.length > 1 )
			fileName = ( this.getAttribute( 'data-multiple-caption' ) || '' ).replace( '{count}', this.files.length );
		else
			fileName = e.target.value.split( '\' ).pop();

		if( fileName )
			label.querySelector( 'span' ).innerHTML = fileName;
		else
			label.innerHTML = labelVal;
	});
});

There is also a jQuery version of this code presented in the source of the demo files. Make sure to check them out.

演示文件的源代码中也提供了此代码的jQuery版本。 确保将其签出。

A little explanation:

一点解释:

  • Having the native [multiple] attribute allows users to select more than one file per upload. Whereas [data-multiple-caption] is a fictive attribute for expressing the message if multiple files were selected. Here you can set a custom message. The use of the {count} phrase is optional and the fragment is replaced with the number of files selected. The reason I use an additional HTML attribute instead of assigning this sentence as a value for a JavaScript variable is because it’s much easier to maintain the copy when it is in one place.

    具有本机[multiple]属性可让用户为每次上传选择多个文件。 而[data-multiple-caption]是一个虚拟属性,用于在选择了多个文件的情况下表示消息。 您可以在此处设置自定义消息。 {count}短语的使用是可选的,该片段将替换为所选文件的数量。 我使用附加HTML属性而不是将这句话分配为JavaScript变量的值的原因是因为将副本放在一个位置时维护起来容易得多。

  • HTML attribute [multiple] is not supported in IE 9 and below and neither is the files property of JavaScript. For the latter case, we simply rely on value. Since it usually has a value of C:fakepathfilename.jpg format, the split( '\' ).pop() extracts what’s actual – the name of the file.

    IE 9和更低版本不支持HTML属性[multiple] ,JavaScript的files属性也不支持。 对于后一种情况,我们仅依靠value 。 由于通常具有C:fakepathfilename.jpg格式的值,因此split( '\' ).pop()提取实际的内容-文件名。

  • An interesting thing is that you can unset a value of the input by pressing the ESC button while in the file browser. This is possible only in Chrome and Opera. Therefore, we use labelVal for storing the default value of the label and bringing it back when necessary.

    有趣的是,您可以在文件浏览器中通过按ESC按钮来取消输入的值。 这仅在Chrome和Opera中可行。 因此,我们使用labelVal来存储标签的默认值,并在必要时将其恢复。

This is how the final result looks like:

最终结果如下所示:

如果JavaScript不可用怎么办? (What if JavaScript is not available?)

Since there is no JavaScript-less way to indicate if any files were selected, it would be better to rely on the default looks of the file input for the sake of usability. All we need to do is to add a .no-js class name to the <html> element and then use JavaScript and replace it with .js – that’s how we will know if JavaScript is available.

由于没有一种无JavaScript的方式来指示是否选择了任何文件,因此出于可用性的考虑,最好依靠文件输入的默认外观。 我们需要做的就是在<html>元素中添加.no-js类名,然后使用JavaScript并将其替换为.js –这就是我们将了解JavaScript是否可用的方式。

<html class="no-js">
    <head>
        <!-- remove this if you use Modernizr -->
        <script>(function(e,t,n){var r=e.querySelectorAll("html")[0];r.className=r.className.replace(/(^|s)no-js(s|$)/,"$1js$2")})(document,window,0);</script>
    </head>
</html>

The CSS part accordingly:

CSS部分相应地:

.js .inputfile {
    width: 0.1px;
    height: 0.1px;
    opacity: 0;
    overflow: hidden;
    position: absolute;
    z-index: -1;
}

.no-js .inputfile + label {
    display: none;
}

Firefox错误 (Firefox Bug)

It is quite unexpected that Firefox completely ignores the input[type="file"]:focus expression, whereas :hover and :active work just fine! Surprisingly, Firefox allows to catch the focus event in JavaScript, so the workaround is adding a class to the file input element that let’s us control the focus style:

出乎意料的是,Firefox完全忽略了input[type="file"]:focus表达式,而:hover:active正常工作! 令人惊讶的是,Firefox允许在JavaScript中捕获focus事件,因此解决方法是在文件输入元素中添加一个类,让我们控制焦点样式:

input.addEventListener( 'focus', function(){ input.classList.add( 'has-focus' ); });
input.addEventListener( 'blur', function(){ input.classList.remove( 'has-focus' ); });
.inputfile:focus + label,
.inputfile.has-focus + label {
    outline: 1px dotted #000;
    outline: -webkit-focus-ring-color auto 5px;
}

Check out the example styles in the demo to see how to style the file input element according to your needs. Make sure to take a look at the source code of the demo and feel free to use this technique in your projects. Happy uploading!

在演示中查看示例样式,以了解如何根据需要设置文件输入元素的样式。 确保查看该演示的源代码,并随时在您的项目中使用此技术。 祝您上传愉快!

The icon in the demo is made by Daniel Bruce from www.flaticon.com and it is licensed under CC BY 3.0.

该演示中的图标由www.flaticon.comDaniel Bruce制作,并根据CC BY 3.0授权。

翻译自: https://tympanus.net/codrops/2015/09/15/styling-customizing-file-inputs-smart-way/

安卓自定义输入框样式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值