245

Is it possible to disable form fields using CSS? I of course know about the attribute disabled, but is it possible to specify this in a CSS rule? Something like -

<input type="text" name="username" value="admin" >
<style type="text/css">
  input[name=username] {
    disabled: true; /* Does not work */
  }
</style>

The reason I'm asking is that, I have an application where the form fields are autogenerated, and fields are hidden/shown based on some rules (which run in Javascript). Now I want to extend it to support disabling/enabling fields, but the way the rules are written to directly manipulate the style properties of the form fields. So now I have to extend the rule engine to change attributes as well as style of form fields and somehow it seems less than ideal.

It's very curious that you have visible and display properties in CSS but not enable/disable. Is there anything like it in the still-under-works HTML5 standard, or even something non-standard (browser specific)?

Anupam Jain
  • 7,851
  • 2
  • 39
  • 74
  • 7
    It's mentioned several times below but it's lost in the noise. Try pointer-events: none; – Corey Alix Apr 08 '16 at 02:31
  • pointer-events: none *isn't* equivalent to disabling the field by setting the disabled attribute! You can still manipulate the field via the keyboard (tab into it, type into text fields, toggle checkboxes and radio boxes, activate buttons, etc), and the value is still submitted when the input's form is submitted. The only thing it does is prevent clicking/tapping on the field, that's it. As the original poster is asking for some way to use CSS instead of setting the disabled attribute, any answer that suggests pointer-events: none is simply wrong. – blm Dec 05 '22 at 22:45

13 Answers13

214

You can fake the disabled effect using CSS.

pointer-events:none;

You might also want to change colors etc.

ANaimi
  • 6,266
  • 7
  • 32
  • 32
150

This can be helpful:

<input type="text" name="username" value="admin" >

<style type="text/css">
input[name=username] {
    pointer-events: none;
 }
</style>

Update:

and if want to disable from tab index you can use it this way:

 <input type="text" name="username" value="admin" tabindex="-1" >

 <style type="text/css">
  input[name=username] {
    pointer-events: none;
   }
 </style>
John Culviner
  • 22,235
  • 6
  • 55
  • 51
fbarikzehy
  • 4,885
  • 2
  • 33
  • 39
  • 4
    That looked like just what I was after to disable all my input fields but, although it blocks them from mouse events, they can still be accessed and changed using keyboard tab – Ken Oct 20 '15 at 15:18
  • 13
    tab-index css property does not exist. It needs to be a html attribute (tabindex=-1) – N4ppeL Dec 02 '15 at 14:05
  • 1
    tab-index not find and not work in chrome, hitting TAB key passed away disable feature so this is not complete solution. – QMaster Aug 17 '16 at 12:38
117

Since the rules are running in JavaScript, why not disable them using javascript (or in my examples case, jQuery)?

$('#fieldId').attr('disabled', 'disabled'); //Disable
$('#fieldId').removeAttr('disabled'); //Enable

UPDATE

The attr function is no longer the primary approach to this, as was pointed out in the comments below. This is now done with the prop function.

$( "input" ).prop( "disabled", true ); //Disable
$( "input" ).prop( "disabled", false ); //Enable
Dutchie432
  • 28,798
  • 20
  • 92
  • 109
  • 1
    Shouldn't that be $('#filedId').removeAttr('disabled'); // Enable – Anupam Jain May 11 '11 at 11:33
  • I think your example will also work, But you should choose between setting/unsetting the attribute, and not adding/removing it. A hybrid is less desirable. – Dutchie432 May 11 '11 at 11:44
  • 7
    It is probably worth noting that this solution won't work if the user has disabled JavaScript. – josh-fuggle Apr 18 '13 at 00:02
  • 1
    Firefox 20.0 (not sure about other versions, this is just what I'm using to develop) requires removing the attribute. While @Dutchie432 is right in theory, using .removeAttr('disabled'); is the correct practical solution (at least in my current browser). –  Apr 22 '13 at 06:16
  • 1
    Unless you can't use JQuery. – marines Apr 24 '14 at 11:30
  • @marines I said `using javascript (or in my examples case, jQuery)` - I think it provides enough of an idea for you to Google how to handle this in pure JS yourself. Try searching `Pure JS Remove Attribute` or `Pure JS Add Attribute` – Dutchie432 Apr 28 '14 at 12:41
  • 3
    FYI - the jQuery documentation suggests using `.prop()` instead of `.attr()` for this case. "As of jQuery 1.6, the .attr() method returns undefined for attributes that have not been set. To retrieve and change DOM properties such as the checked, selected, or disabled state of form elements, use the .prop() method." Source Documentation: [.attr()](http://api.jquery.com/attr/) and [.prop()](http://api.jquery.com/prop/) – Nicholas Ryan Bowers May 11 '15 at 19:58
  • Even if JS is enabled, this answer also fails in that the input will be editable until the JS is loaded. In JS intensive applications the JS may take some time to load. Within that time span, the input will be editable and sometimes that's a problem. – Akhorus Sep 03 '15 at 18:28
  • 1
    Important: Elements with `disabled` attribute are **not submitted** - their values are not posted to the server. Read on: http://stackoverflow.com/q/8925716/1066234 – Avatar Dec 10 '15 at 15:44
  • 1
    Didn't author specifically ask for CSS solution? – Klesun Jun 07 '19 at 16:17
62

It's very curious that you have visible and display properties in CSS but not enable/disable.

You're misunderstanding the purpose of CSS. CSS is not meant to change the behavior of form elements. It's meant to change their style only. Hiding a text field doesn't mean the text field is no longer there or that the browser won't send its data when you submit the form. All it does is hide it from the user's eyes.

To actually disable your fields, you must use the disabled attribute in HTML or the disabled DOM property in JavaScript.

Koray Tugay
  • 22,894
  • 45
  • 188
  • 319
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • 39
    Of course I know what CSS is "supposedly" for. But for modern webapps the distinction between "presentation" and "behaviour" is muddier than mud. Since disabled fields are not submitted to the server, it's a behaviour change. But then how is hiding all the form fields not one?! Perhaps in the good old days when all you could do on the web is read text and fill up forms, the distinction was clearer. In the modern webapp, if you want to separate presentation from behaviour, CSS versus HTML/JS is the wrong way to do it. – Anupam Jain May 11 '11 at 11:58
  • 19
    disabled is a state, not a behavior. What he's asking for is perfectly reasonable. For instance, you might want to add a busy class to multiple fields while data is being processed. Furthermore, the W3C seems to agree since it allows CSS selection of elements via the disabled pseudo class. – IAmNaN Aug 29 '13 at 20:58
  • 3
    @IAmNaN: 1) "disabled is a state, not a behavior." So is just about every other HTML/DOM attribute. 2) "For instance, you might want to add a busy class to multiple fields while data is being processed." You do that in a script. 3) "Furthermore, the W3C seems to agree since it allows CSS selection of elements via the disabled pseudo class." Being able to *select* an element based on whether it's enabled or disabled has nothing to do with being able to *change* that state using CSS. – BoltClock Aug 30 '13 at 07:30
  • 6
    There are many things in CSS that actually could be considered to be changes in *behavior* e.g. pointer-events:none; mentioned by @ANaimi. So disabled could be easily considered to be display property as well. Too bad it is not, would make few things easier. – Mikael Lepistö Sep 03 '14 at 07:43
  • 1
    @Mikael Lepistö: Yeah, I don't agree with `pointer-events` being a CSS property either. FYI, `pointer-events` [originates from SVG](http://www.w3.org/TR/SVG/interact.html#PointerEventsProperty). – BoltClock Sep 03 '14 at 08:58
  • @BoltClock True pointer-events is not CSS attribute until CSS4 http://wiki.csswg.org/spec/css4-ui is coming out. There are also other behavior changing attributes coming like touch-action and focusable. But you are right those are not here yet, so CSS3 still seems to be pure :) – Mikael Lepistö Sep 04 '14 at 07:02
  • 1
    The problem is with religiously deeming CSS to be purely and only relevant to visual styling for no reason other than that's how it was taught to you and that's how you understand it. Sure that is its intent, but technically speaking, CSS is a declarative rule engine, and arguing that you should use flawed imperative programming methods for things that declarative rule engines are perfect for *just* because they don't meet your arbitrary classification as being "visual" is silly. – devios1 Jun 15 '17 at 16:08
  • 1
    The truth is, disabling user interaction declaratively at a single point is a much safer way to do it. Having to manually set each input's disabled attribute separately results in fragile code that can easily develop state bugs that would be completely avoidable if done declaratively. – devios1 Jun 15 '17 at 16:08
  • @BoltClock. _Hiding a text field doesn't mean the text field is no longer there or that the browser won't send its data when you submit the form._ You can use css to hide/show complete forms, such as by using the state of radio buttons to control which of the following forms are displayed. That would totally isolate the form data sets, though the common data would be duplicated. – Patanjali Mar 06 '19 at 13:34
  • And then after you disable it at the "HTML or Javascript level" you have to understand that it can easily be changed with more console Javascript or open script injection. Now I guess we're "misunderstanding Javascript" and need to start validating at the server level, right? – ParanoidCoder May 30 '23 at 00:50
24

You can't use CSS to disable Textbox. solution would be HTML Attribute.

disabled="disabled"
Vishwanath Dalvi
  • 35,388
  • 41
  • 123
  • 155
  • While this does work in principle, if you read the full question it says the form field are being auto generated, and then need to be disabled afterwards. – thelem Sep 22 '14 at 15:07
  • 1
    @mr_eclair. it is possible using ---> pointer-events: none; Css property. – fbarikzehy Jun 10 '15 at 10:17
  • 3
    Note: Elements with `disabled` attribute are **not submitted** - their values are not posted to the server. Read on: http://stackoverflow.com/q/8925716/1066234 – Avatar Dec 10 '15 at 15:45
19

I am always using:

input.disabled {
  pointer-events:none;
  color:#AAA;
  background:#F5F5F5;
}

and then applying the css class to the input field:

<input class="disabled" type="text" value="90" name="myinput" id="myinput">
Avatar
  • 14,622
  • 9
  • 119
  • 198
18

The practical solution is to use CSS to actually hide the input.

To take this to its natural conclusion, you can write two html inputs for each actual input (one enabled, and one disabled) and then use javascript to control the CSS to show and hide them.

graphicdivine
  • 10,937
  • 7
  • 33
  • 59
12

first time answering something, and seemingly just a bit late...

I agree to do it by javascript, if you're already using it.

For a composite structure, like I usually use, I've made a css pseudo after element to block the elements from user interaction, and allow styling without having to manipulate the entire structure.

For Example:

<div id=test class=stdInput>
    <label class=stdInputLabel for=selecterthingy>A label for this input</label>
    <label class=selectWrapper>
         <select id=selecterthingy>
             <option selected disabled>Placeholder</option>
             <option value=1>Option 1</option>
             <option value=2>Option 2</option>
         </select>
    </label>
</div>

I can place a disabled class on the wrapping div

.disabled { 
    position : relative; 
    color    : grey;
}
.disabled:after {
    position :absolute;
    left     : 0;
    top      : 0;
    width    : 100%;
    height   : 100%;
    content  :' ';
}

This would grey text within the div and make it unusable to the user.

My example JSFiddle

Alexander van Oostenrijk
  • 4,644
  • 3
  • 23
  • 37
Larchy
  • 163
  • 3
  • 10
10

input[name=username] { disabled: true; /* Does not work */ }

I know this question is quite old but for other users who come across this problem, I suppose the easiest way to disable input is simply by ':disabled'

<input type="text" name="username" value="admin" disabled />
<style type="text/css">
  input[name=username]:disabled {
    opacity: 0.5 !important; /* Fade effect */
    cursor: not-allowed; /* Cursor change to disabled state*/
  }
</style>

In reality, if you have some script to disable the input dynamically/automatically with javascript or jquery that would automatically disable based on the condition you add.

In jQuery for Example:

if (condition) {
// Make this input prop disabled state
  $('input').prop('disabled', true);
}
else {
// Do something else
}

Hope the answer in CSS helps.

Shaze
  • 792
  • 1
  • 9
  • 14
3

You cannot do that I'm afraid, but you can do the following in jQuery, if you don't want to add the attributes to the fields. Just place this inside your <head></head> tag

$(document).ready(function(){ 
  $(".inputClass").focus(function(){
    $(this).blur();
  }); 
});

If you are generating the fields in the DOM (with JS), you should do this instead:

$(document).ready(function(){ 
  $(document).on("focus", ".inputClass", function(){
    $(this).blur();
  }); 
});
Cfrim
  • 920
  • 9
  • 19
1

This can be done for a non-critical purpose by putting an overlay on top of your input element. Here's my example in pure HTML and CSS.

https://jsfiddle.net/1tL40L99/

    <div id="container">
        <input name="name" type="text" value="Text input here" />
        <span id="overlay"></span>
    </div>

    <style>
        #container {
            width: 300px;
            height: 50px;
            position: relative;
        }
        #container input[type="text"] {
            position: relative;
            top: 15px;
            z-index: 1;
            width: 200px;
            display: block;
            margin: 0 auto;
        }
        #container #overlay {
            width: 300px;
            height: 50px;
            position: absolute;
            top: 0px;
            left: 0px;
            z-index: 2;
            background: rgba(255,0,0, .5);
        }
    </style>
DeFeNdog
  • 1,156
  • 1
  • 12
  • 25
1

There's no way to use CSS for this purpose. My advice is to include a javascript code where you assign or change the css class applied to the inputs. Something like that :

function change_input() {
 $('#id_input1')
  .toggleClass('class_disabled')
  .toggleClass('class_enabled');
  
 $('.class_disabled').attr('disabled', '');
 $('.class_enabled').removeAttr('disabled', '');
}
.class_disabled { background-color : #FF0000; }
.class_enabled { background-color : #00FF00; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<form>  
 Input: <input id="id_input1" class="class_enabled" />  
 <input type="button" value="Toggle" onclick="change_input()";/> 
</form>
Joel Barba
  • 83
  • 4
1

A variation to the pointer-events: none; solution, which resolves the issue of the input still being accessible via it's labeled control or tabindex, is to wrap the input in a div, which is styled as a disabled text input, and setting input { visibility: hidden; } when the input is "disabled".
Ref: https://developer.mozilla.org/en-US/docs/Web/CSS/visibility#Values

div.dependant {
  border: 0.1px solid rgb(170, 170, 170);
  background-color: rgb(235,235,228);
  box-sizing: border-box;
}
input[type="checkbox"]:not(:checked) ~ div.dependant:first-of-type {
  display: inline-block;
}
input[type="checkbox"]:checked ~ div.dependant:first-of-type {
  display: contents;
}
input[type="checkbox"]:not(:checked) ~ div.dependant:first-of-type > input {
  visibility: hidden;
}
<form>
  <label for="chk1">Enable textbox?</label>
  <input id="chk1" type="checkbox" />
  <br />
  <label for="text1">Input textbox label</label>
  <div class="dependant">
    <input id="text1" type="text" />
  </div>
</form>

The disabled styling applied in the snippet above is taken from the Chrome UI and may not be visually identical to disabled inputs on other browsers. Possibly it can be customised for individual browsers using engine-specific CSS extension -prefixes. Though at a glance, I don't think it could:
Microsoft CSS extensions, Mozilla CSS extensions, WebKit CSS extensions

It would seem far more sensible to introduce an additional value visibility: disabled or display: disabled or perhaps even appearance: disabled, given that visibility: hidden already affects the behavior of the applicable elements any associated control elements.

Matthew Millar
  • 122
  • 1
  • 4