68

I know that input elements are made read-only by applying the readonly boolean attribute, and being an attribute it is not affected by CSS.

On the other hand, my scenario seems to be a very good fit for CSS, so I was hoping there is some kind of a CSS trick to let me do it. I have a printable version hyperlink on my form. Clicking it displays a ... printable version of the document. It is mostly CSS stuff, my print.css looks like this:

html.print {
    width: 8.57in;
}

.print body {
    font: 9pt/1.5 Arial, sans-serif;
    margin: 0 1in;
    overflow: auto;
}

.print #header, .print #footer {
    display: none;
}

.print .content {
    background-color: white;
    overflow: auto;
}

.print .fieldset > div.legend:first-child {
    background: white;
}

.print ::-webkit-input-placeholder {
    /* WebKit browsers */
    color: transparent;
}

.print :-moz-placeholder {
    /* Mozilla Firefox 4 to 18 */
    color: transparent;
}

.print ::-moz-placeholder {
    /* Mozilla Firefox 19+ */
    color: transparent;
}

.print :-ms-input-placeholder {
    /* Internet Explorer 10+ */
    color: transparent;
}

.print .check-mark {
    display: inline;
}

.print input[type=checkbox] {
    display: none;
}

.print .boolean-false {
    display: none;
}

There are also a few javascript pieces, such as:

  • Adding the print class to the html element
  • Displaying tables without scroll bars
  • A few other minor things, like hiding any popup overlays.

My current problem is input fields. They should be read-only, however, I have no idea how to do it with minimum changes to the code. CSS could be a perfect solution.

Any ideas?

James Donnelly
  • 126,410
  • 34
  • 208
  • 218
mark
  • 59,016
  • 79
  • 296
  • 580
  • on the printable version, could you not just add the attribute to the html tag? – Pete May 29 '13 at 10:11
  • Don't think it's possible with CSS. CSS is for styling. – sroes May 29 '13 at 10:11
  • 1
    This doesn't answer the question, but why not use a media query like `@media print` for making a printer-friendly version? – PLPeeters May 29 '13 at 10:16
  • I want to show the printable version before the user actually selects print from the browser menu. `@media print` is only activated in the browser's print preview dialog or when actually printing. I want to give a printable version, but on the screen media. – mark May 29 '13 at 11:13

10 Answers10

42

With CSS only? This is sort of possible on text inputs by using user-select:none:

.print {
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;          
}

JSFiddle example.

It's well worth noting that this will not work in browsers which do not support CSS3 or support the user-select property. The readonly property should be ideally given to the input markup you wish to be made readonly, but this does work as a hacky CSS alternative.

With JavaScript:

document.getElementById("myReadonlyInput").setAttribute("readonly", "true");

Edit: The CSS method no longer works in Chrome (29). The -webkit-user-select property now appears to be ignored on input elements.

James Donnelly
  • 126,410
  • 34
  • 208
  • 218
  • 1
    I was looking for similar thing. And thanks for the answer. But there is an issue i found out in the fiddle.. When we focus it and press the delete button the text area is getting deleted. Is there any solution for that? I am using mozilla firefox – Rohith May 29 '13 at 11:08
  • @Rohith this doesn't appear to be an issue in Chrome. As I mentioned though, ideally the `readonly` property should be given to the element (either through direct markup modification or with JavaScript). – James Donnelly May 29 '13 at 11:10
  • Interesting, in Chrome it behaves as expected - navigates away from the page. – mark May 29 '13 at 11:10
  • 4
    With firefox 27, the "user-select:none" only prevents me to select text in the field with the mouse but not with keyboard shortcut (Shift + arrows), which is ridiculous, or changing its content (erasing, writing). Under Opera 12, the field is totally normal. – lolesque Apr 02 '14 at 13:42
  • The Fiddle under Firefox is quite bizarre - and might be a bug. I can click in the field but pressing 'delete' moves the keyboard caret to the right one character and THEN deletes the character following it. The result is that every other character in the text field is deleted. – CubicleSoft Jun 07 '17 at 15:03
  • @CubicleSoft I edited this answer in September 2013 to say that the CSS approach no longer works in Chrome. I'd be surprised if it still works in Firefox almost 4 years on! – James Donnelly Jun 07 '17 at 15:04
  • JavaScript works great. Used it to protect a GravityForms field in X Theme. – John Cruz May 10 '20 at 14:35
  • fiddle example proves the CSS does't work. This answer is incorrect. – Florin Marcus Jan 22 '21 at 15:59
  • @FlorinMarcus this answer is from a long time ago and was edited in 2016 to say it no longer works on Chrome. Chances are it no longer works on other browsers now, either. – James Donnelly Jan 23 '21 at 11:27
22

The read-only attribute in HTML is used to create a text input non-editable. But in case of CSS, the pointer-events property is used to stop the pointer events.

Syntax:

pointer-events: none;

Example: This example shows two input text, in which one is non-editable.

<!DOCTYPE html> 
<html> 
    <head> 
        <title> 
            Disable Text Input field 
        </title> 

        <style> 
        .inputClass { 
            pointer-events: none; 
        } 
        </style> 
    </head> 

    <body style = "text-align:center;">
        Non-editable:<input class="inputClass" name="input" value="NonEditable"> 

        <br><br> 

        Editable:<input name="input" value="Editable"> 
    </body> 
</html>                  

Edit static

Jee Mok
  • 6,157
  • 8
  • 47
  • 80
  • 5
    It can still be editable by tabbing through the element. – Sidra Aug 04 '20 at 09:42
  • 1
    @Sidra thanks for finding that out! there is no way for CSS to control events but you can assign a CSS class to do that, see this answer: https://stackoverflow.com/a/18462465/9206753 – Jee Mok Aug 05 '20 at 00:25
17

It is not (with current browsers) possible to make an input field read-only through CSS alone.

Though, as you have already mentioned, you can apply the attribute readonly='readonly'.

If your main criteria is to not alter the markup in the source, there are ways to get this in, unobtrusively, with javascript.

With jQuery, this is easy:

 $('input').attr('readonly', true);

Or even with plain Javascript:

document.getElementById('someId').setAttribute('readonly', 'readonly');
Faust
  • 15,130
  • 9
  • 54
  • 111
16

Not really what you need, but it can help and answser the question here depending of what you want to achieve.

You can prevent all pointer events to be sent to the input by using the CSS property : pointer-events:none It will kind of add a layer on top of the element that will prevent you to click in it ... You can also add a cursor:text to the parent element to give back the text cursor style to the input ...

Usefull, for example, when you can't modify the JS/HTML of a module.. and you can just customize it by css.

JSFIDDLE

Jscti
  • 14,096
  • 4
  • 62
  • 87
2

This is not possible with css, but I have used one css trick in one of my website, please check if this works for you.

The trick is: wrap the input box with a div and make it relative, place a transparent image inside the div and make it absolute over the input text box, so that no one can edit it.

css

.txtBox{
    width:250px;
    height:25px;
    position:relative;
}
.txtBox input{
    width:250px;
    height:25px;
}
.txtBox img{
    position:absolute;
    top:0;
    left:0
}

html

<div class="txtBox">
<input name="" type="text" value="Text Box" />
<img src="http://dev.w3.org/2007/mobileok-ref/test/data/ROOT/GraphicsForSpacingTest/1/largeTransparent.gif" width="250" height="25" alt="" />
</div>

jsFiddle File

Roy Sonasish
  • 4,571
  • 20
  • 31
0

No behaviors can be set by CSS. The only way to disable something in CSS is to make it invisible by either setting display:none or simply putting div with transparent img all over it and changing their z-orders to disable user focusing on it with mouse. Even though, user will still be able to focus with tab from another field.

David Jashi
  • 4,490
  • 1
  • 21
  • 26
0

You don't set the behavior of controls via CSS, only their styling.You can use jquery or simple javascript to change the property of the fields.

sAnS
  • 1,169
  • 1
  • 7
  • 10
0

Why not hide the input element and replace it with a label element with the same content?

I puzzled over how the React TODOMVC app accomplished this same thing and this is the strategy they came up with.

To see it in action, check out the app below, and watch the CSS properties of the TODO items when you double click them and then click away.

http://todomvc.com/examples/react-backbone/#/

When you render the page you can have either an editable input, or a non-editable label with display:none; depending on your media query.

Ian Danforth
  • 779
  • 1
  • 9
  • 18
-1

CSS based input text readonly change color of selection:

CSS:

/**default page CSS:**/
::selection { background: #d1d0c3; color: #393729; }
*::-moz-selection { background: #d1d0c3; color: #393729; }

/**for readonly input**/
input[readonly='readonly']:focus { border-color: #ced4da; box-shadow: none; }
input[readonly='readonly']::selection { background: none; color: #000; }
input[readonly='readonly']::-moz-selection { background: none; color: #000; }

HTML:

<input type="text" value="12345" id="readCaptch" readonly="readonly" class="form-control" />

live Example: https://codepen.io/alpesh88ww/pen/mdyZBmV

also you can see why i was done!! (php captcha): https://codepen.io/alpesh88ww/pen/PoYeZVQ

-16

Hope this will help.

    input[readonly="readonly"]
{
    background-color:blue;
}

reference:

http://jsfiddle.net/uzyH5/1/

RachithaS
  • 181
  • 2
  • 12
  • 6
    You assign the `readonly` property in the HTML and reference it using the CSS. OP is looking to assign `readonly` or similar behavior *using* CSS, if I interpret it correctly. – ASGM May 30 '13 at 10:01