I have a project where sometimes checkboxes don't have labels. The only way of setting custom image for checkbox I've found was setting image for label:before for corresponding label which has for value with id of checkbox.
Are there any CSS way (at least hacky) to set custom image to checkbox without changing markup? input[type="checkbox"]:before works only in Chrome.
The only way I've found that works everywhere except IE is via setting CSS appearance:
input[type="checkbox"] {
width: 16px;
height: 16px;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background-color: red;
}
input[type="checkbox"]:checked {
background-color: green;
}
<input type="checkbox" />
I think it's impossible to do it without label for all browsers. In my opinion label is necessarily.
But you can use JS for this and one of library like icheck (and many other not only jQuery also pure JS)
Maybe if you add a container to your checkbox like this
<div>
<input type="checkbox">
</div>
and then
div{
position: relative;
/* Your custom style */
}
input{
position: absolute;
height: 100%;
width: 100%;
left: 0;
top: 0;
opacity: 0;
}
Related
I've created my own custom file upload button by creating a label and hiding the input element with css. This all works fine, but the problem is I can't use the button by tabbing and enter. I tried adding tabindex=0 to the label. I could then tab to the element ok but there was no action when clicking enter as it is only a label.
Here is the HTML code
<label class="custom-file-upload>
<input type="file">
Choose file
</label>
and css to hide the default file upload button
input[type="file"] {
display: none;
}
Any help is much appreciated.
This can all be achieved with CSS on modern browsers with the added benefit that:
there is no reliance on JavaScript
there is no need for a tabindex
it activates with space or enter, both of which are expected behaviours.
The key is to make the input visually hidden (using the .visually-hidden class) but still focusable and then use the + to link the label (without wrapping the input in the label).
The key part of the example below is [type="file"]:focus + label
This lets you change the label styling when the input is selected (it is important that the <label> appears immediately after the <input> in the DOM in order for this to work).
I also included the syntax for applying a ::before styling on hover and focus for completeness.
Example (not a production ready solution)
The example given below was a quick and dirty way of demonstrating how to achieve your goal, it has a couple of accessibility issues that need addressing before putting it into production:-
you shouldn't use the same styling for hover and focus -> hover you should change colour and show the icon, focus add a border and show the icon
instead of using a font for the icon you should use an SVG as fonts may break if someone overrides them (i.e. if they have a preferred font due to dyslexia).
make sure that you disable animation of the icon entering if people have indicated they prefer reduced movement by using the prefers-reduced-motion: reduce media query https://developer.mozilla.org/en-US/docs/Web/CSS/#media/prefers-reduced-motion
Also make sure you associate the label with the input using for="inputName" on the label and id="inputName" on the input.
.visually-hidden {
position: absolute !important;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px, 1px, 1px, 1px);
white-space: nowrap;
}
[type="file"] + label {
background: #f15d22;
border: none;
border-radius: 5px;
color: #fff;
cursor: pointer;
display: inline-block;
font-size: inherit;
font-weight: 600;
margin-bottom: 1rem;
outline: none;
padding: 1rem 50px;
position: relative;
transition: all 0.3s;
vertical-align: middle;
background-color: #99c793;
border-radius: 50px;
overflow: hidden;
}
[type="file"] + label::before {
color: #fff;
content: "\f382";
font-family: "Font Awesome 5 Pro";
font-size: 100%;
height: 100%;
right: 130%;
line-height: 3.3;
position: absolute;
top: 0px;
transition: all 0.3s;
}
[type="file"]:hover + label,
[type="file"]:focus + label{
background-color: #497f42;
}
[type="file"]:hover + label::before,
[type="file"]:focus + label::before {
right: 75%;
}
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.2.0/css/all.css" />
<input type="file" id="inputName" class="visually-hidden"/>
<label for="inputName">upload</label>
You can rewrite your code something in this manner
<input id="file-upload" type="file">
<label for="file-upload" class="custom-file-upload>Choose file</label>
CSS for input and change css for label accordingly using sibling selector
input[type="file"] {
opacity: 0;
}
With labels you need to trigger click on keyboard events for enter
<label for ="file-upload1" tabindex="0" class="custom-file-upload">
<input type="file" id="file-upload"/> Choose file
</label>
CSS
input[type="file"]{
display:none;
}
JQuery Code
$('.custom-file-upload').on('keyup',function(event){
if (event.keyCode === 13) {
$('#file-upload').trigger('click');
}
})
I may have a little hack that can help. You can use the focus-within attribute on your parent element that holds your file input and style it with this
parent:focus-within {
border: 1px solid blue;
background: yellow;
}
I bought a bootstrap template, the style sheet file, has this code:
input[type=checkbox],
input[type=radio] {
opacity: 0;
position: absolute;
left: -9999px;
z-index: 12;
width: 18px;
height: 18px;
cursor: pointer;
}
I have a html table that has a cell with a checkbox, that is not showing up, with chrome inspector, I modified turn off the styling properties,
My question Is there any way that I could tell my code not to apply that style in the checkbox that is inside the table cell??
thanks
Alberto
yes, specifically call that check box add a class to the checkbox something like this <input type="checkbox" class="unique-class"/> then in your css add the style to just that checkbox with something like this
input.unique-class[type=checkbox],
input.unique-class[type=radio] {
/*stuff here*/
}
input[type="radio"], input[type="checkbox"] {
/*stuff here*/
cursor:pointer;
}
I know this kind of question was asked at least 100 times but here is what I mean by CSS only:
I want to change style of checkbox/radio with CSS without beeing required to change markup of those elements ( putting them in container / adding label element etc ). I'm asking if it's possible to style <input type"checkbox"/> without adding any new html to it.
Such CSS could be added to any exisitng page and work. All solutions I've found requires some given type of markup and if you'd just add them to some page with forms it just will not work as they might not have labels or containers for inputs itself.
By modify I mean - changing style of box (main css like border-radius, colors, borders, shadows) and changing style of check (color, shape etc).
I know required markup can be added by JS - but it's not solution, it's workaround and I'm not looking for that.
it is not cross-browser solution
input[type="checkbox"]{
width: 30px;
height: 30px;
margin: 0;
padding: 0;
-moz-appearance: none;
-webkit-appearance: none;
-ms-appearance: none;
-o-appearance: none;
appearance: none;
outline: none;
}
input[type=checkbox]:after {
content: "";
width: 30px;
height: 30px;
border: 2px solid #ccc;
margin: 0;
vertical-align: top;
display: inline-block;
border-radius: 50%;
}
input[type=checkbox]:checked:after{
background: #ccc;
}
<input type="checkbox" />
how can I make a custom checkbox with css only (no JS no JQ) with content:"on" when checked and content:"off" when uncheked.
Thanks.
reedit
OK, after LOT of copy/paste/delete, it work now.
Thank.
input[type=checkbox] {
position: relative;
visibility: hidden;
cursor: pointer;
}
input[type=checkbox]:after {
display: block;
content: "OFF";
position: absolute;
top: 0;
right: -30px;
visibility: visible;
height: 30px;
line-height: 30px;
width: 50px;
text-align: center;
border-radius: 4px;
background: #d00;
color: #fff;
font-weight: 600;
cursor: pointer;
}
input[type=checkbox]:checked:after {
content: "ON";
background: #0a0;
}
<input type="checkbox" />
It is possible. Check out these blog posts by Ryan Seddon. He explain how you can play with checkbox and CSS
http://www.thecssninja.com/css/custom-inputs-using-css
http://www.thecssninja.com/css/futurebox3
http://www.thecssninja.com/css/css-tree-menu
Creating an actual element with CSS isn't possible. You can however style a checkbox using css.
An example:
input[type=checkbox] {
outline: 2px solid #f00;
}
Relying on pure CSS is also a give-or-take when dealing with different browsers and platforms. I hope this answers your question.
I believe this is impossible with just css. Css decorates a html element and does not change its properties. If you click the checkbox, the box will have to do a postback to show it on the page. In which case the css will be the same. You need javascript.
What makes you not want to use javascript?
Is there a way to hide the browse button and only leave the text box that works in all browsers?
I have tried setting the margins but they show up different in each browser
No, what you can do is a (ugly) workaround, but largely used
Create a normal input and a image
Create file input with opacity 0
When the user click on the image, you simulate a click on the file input
When file input change, you pass it's value to the normal input (so user can see the path)
Here you can see a full explanation, along with code:
http://www.quirksmode.org/dom/inputfile.html
You may just without making the element hidden, simply make it transparent by making its opacity to 0.
Making the input file hidden will make it STOP working. So DON'T DO THAT..
Here you can find an example for a transparent Browse operation;
.dropZoneOverlay, .FileUpload {
width: 283px;
height: 71px;
}
.dropZoneOverlay {
border: dotted 1px;
font-family: cursive;
color: #7066fb;
position: absolute;
top: 0px;
text-align: center;
}
.FileUpload {
opacity: 0;
position: relative;
z-index: 1;
}
<div class="dropZoneContainer">
<input type="file" id="drop_zone" class="FileUpload" accept=".jpg,.png,.gif" onchange="handleFileSelect(this) " />
<div class="dropZoneOverlay">Drag and drop your image <br />or<br />Click to add</div>
</div>
I find a good way of achieving this at Remove browse button from input=file.
The rationale behind this solution is that it creates a transparent input=file control and creates an layer visible to the user below the file control. The z-index of the input=file will be higher than the layer.
With this, it appears that the layer is the file control itself. But actually when you clicks on it, the input=file is the one clicked and the dialog for choosing file will appear.
Below code is very useful to hide default browse button and use custom instead:
(function($) {
$('input[type="file"]').bind('change', function() {
$("#img_text").html($('input[type="file"]').val());
});
})(jQuery)
.file-input-wrapper {
height: 30px;
margin: 2px;
overflow: hidden;
position: relative;
width: 118px;
background-color: #fff;
cursor: pointer;
}
.file-input-wrapper>input[type="file"] {
font-size: 40px;
position: absolute;
top: 0;
right: 0;
opacity: 0;
cursor: pointer;
}
.file-input-wrapper>.btn-file-input {
background-color: #494949;
border-radius: 4px;
color: #fff;
display: inline-block;
height: 34px;
margin: 0 0 0 -1px;
padding-left: 0;
width: 121px;
cursor: pointer;
}
.file-input-wrapper:hover>.btn-file-input {
//background-color: #494949;
}
#img_text {
float: right;
margin-right: -80px;
margin-top: -14px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div class="file-input-wrapper">
<button class="btn-file-input">SELECT FILES</button>
<input type="file" name="image" id="image" value="" />
</div>
<span id="img_text"></span>
</body>
Came across this question and didn't feel like any of the answers were clean. Here is my solution:
<label>
<span>Select file</span>
<input type="file" style="display: none">
</label>
When you click the label the select file dialog will open. No js needed to make it happen.
You can style the label to look like a button.
Here is an example using w3css and font awesome:
<label class="w3-button w3-blue w3-round">
<span><i class="fas fa-image"></i></span>
<input type="file" style="display: none" >
</label>
Of course you need to add an event listener to the input to detect a file was chosen.
HTML - InputFile component can be hide by writing some css.
Here I am adding an icon which overrides inputfile component.
<label class="custom-file-upload">
<InputFile OnChange="HandleFileSelected" />
<i class="fa fa-cloud-upload"></i> Upload
</label>
css-
<style>
input[type="file"] {
display: none;
}
.custom-file-upload {
border: 1px solid #ccc;
display: inline-block;
padding: 6px 12px;
cursor: pointer;
}
</style>
So I found this solution that is very easy to implement and gives a very clean GUI
put this in your HTML
<label class="att-each"><input type="file"></label>
and this in your CSS
label.att-each {
width: 68px;
height: 68px;
background: url("add-file.png") no-repeat;
text-indent: -9999px;
}
add-file.png can be any graphic you wish to show on the webpage. Clicking the graphic will launch the default file explorer.
Working Example: http://www.projectnaija.com/file-picker17.html
Just an additional hint for avoiding too much JavaScript here: if you add a label and style it like the "browse button" you want to have, you could place it over the real browse button provided by the browser or hide the button somehow differently. By clicking the label the browser behavior is to open the dialog to browse for the file (don't forget to add the "for" attribute on the label with value of the id of the file input field to make this happen). That way you can customize the button in almost any way you want.
In some cases, it might be necessary to add a second input field or text element to display the value of the file input and hide the input completely as described in other answers. Still the label would avoid to simulate the click on the text input button by JavaScript.
BTW a similar hack can be used for customizing checkboxes or radiobuttons. by adding a label for them, clicking the label causes to select the checkbox/radiobutton. The native checkbox/radiobutton then can be hidden somewere and be replaced by a custom element.
Just add negative text intent as so:
input[type=file] {
text-indent: -120px;
}
before:
after:
Oddly enough, this works for me (when I place inside a button tag).
.button {
position: relative;
input[type=file] {
color: transparent;
background-color: transparent;
position: absolute;
left: 0;
width: 100%;
height: 100%;
top: 0;
opacity: 0;
z-index: 100;
}
}
Only tested in Chrome (macOS Sierra).
the best way for it
<input type="file" id="file">
<label for="file" class="file-trigger">Click Me</label>
And you can style your "label" element
#file {
display: none;
}
.file-trigger {
/* your style */
}
As of 2022, modern browsers support file button pseudo selector. I was only struggling with Safari v16.1 which didn't work as expected and had to workaround button hiding (::-webkit-file-upload-button part).
input[type=file]::file-selector-button {
display: none;
}
input[type=file]::-webkit-file-upload-button {
display: block;
width: 0;
height: 0;
margin-left: -100%;
}
input[type=file]::-ms-browse {
display: none;
}
You may also use concise syntax:
::file-selector-button {
/* ... */
}
::-webkit-file-upload-button {
/* ... */
}
::-ms-browse {
/* ... */
}