21

Certain HTML form elements have extra UI attached to them, like the up/down arrows on number. When printing the page however, those buttons are no longer needed, as the user can not interact with them in print form.

Text boxes are easy to deal with:

@media print {
    input {
        border: none;
        border-bottom: 2px solid #000000;
    }
}

Makes them print quite nicely, as a line with text on it. Just like a form one would fill out by hand. However doing the same for inputs like number leaves you with those nasty up/down arrows:

HTML <input type="number">

And then there are even less useful printouts, like range, which means nothing when on a page:

HTML <input type="range"

Is there any way to get around this? Any way to style that portion of the element to be invisible, but still see the value/text?

I realize one could swap out the type="" attribute with JS, or have another element holding the value to be displayed on print, but if there is a solution that can be done with CSS only, that would be superior.

zeel
  • 1,101
  • 1
  • 13
  • 31
  • every html element can be hidden by CSS either, you just have to come up with proper selector (http://www.w3.org/TR/CSS2/selector.html) It would help if you could paste the HTML of the controls that you speak of – Paweł Staniec May 05 '13 at 06:52
  • 1
    That is not the problem, I don't want to hide the element, I want to hide the extraneous UI attached to certain kinds of `input` elements, that are meaningless when printed. Hiding the element its self would also hide its value/text, which *is* important. – zeel May 05 '13 at 07:11
  • extraneous UI must be HTML too, right ? :) – Paweł Staniec May 05 '13 at 07:48
  • 1
    No, it is the browser-given bits that make different types of `input` useful beyond what a simple `text` box can do. As I mentioned, the `number` type uses a pair of up/down buttons to increment/decrement the value. Those buttons however are not HTML buttons, they are provided by the browser for that specific kind of `input`. Thus hiding them is not strait forward. Hence the question. – zeel May 05 '13 at 07:53
  • I get it, you are referring to HTML5 input type related behavior, that is currently supported by only few browsers out there. The easy answer is - if you don't want to use HTML5 features don't use HTML5 type attributes - that would mean js dom manipulation (removing/replacing type attributes) is the easiest way to go – Paweł Staniec May 05 '13 at 08:05
  • 2
    you can try the webkit tricks, but be aware that if other browsers implement the HTML5 controls you will have to update your code http://stackoverflow.com/questions/3790935/can-i-hide-the-html5-number-inputs-spin-box – Paweł Staniec May 05 '13 at 08:08
  • 2
    @torm Maybe the OP does actually want to use HTML5 input features _in the browser_. The problem comes when one prints the page and those form controls become useless. You're misunderstanding the question here – Bojangles May 05 '13 at 08:08
  • @Bojangles true, at first I was assuming some css/js ui framework/extension, then I figured out it's HTML5 related. However this is kind of browser specific problem as IE or FF don't support HTML5 input controls, so ... it's still mostly for Chrome (or Opera) users - if I'm not wrong – Paweł Staniec May 05 '13 at 08:13
  • 1
    @torm Well, it will be a problem in other browsers soon (and probably more of a problem). – ralph.m May 05 '13 at 09:39
  • That's essentially the idea. – zeel May 05 '13 at 13:31
  • what about overlapping a "raw display" element? It is not that dirty, especially for the cursor. It would be really easy to map the original element to it so it always have the same value. And at the end, you only play with css when it is time to show/hide – Sebas May 05 '13 at 20:33
  • How much browser-compatibilty do you want for your answer? I've got an idea but it's not gonna work with old browsers. – Farid Rn May 05 '13 at 20:35
  • @faridv It should work with any browser that supports ``, which is an HTML5 input type. And @Sebas I had thought of something like that. I tried using `::before` with `content: attr(value);` which only works on some inputs, and will not update when you edit the value. Using a separate element is possible, but It would probably be easier to just swap the `type` to text if I am going to use JS. – zeel May 05 '13 at 20:53
  • 2
    What is the use case here? If it's a printable report of the form submission, I wouldn't bother trying to deal with making the form elements print friendly, but rather give the user a results page that was print optimized. – steveax May 06 '13 at 06:17
  • This is a form, that must be used in print, but can optionally be filled out on the computer. The print version should look like your average form, with lines to write on. While the online version should act like a web form. – zeel May 06 '13 at 22:58
  • Hand on a second, @torm actually already gave me the answer, for webkit at least. I'll give another day for you to post what was in that link (how did I not notice the hyperlink?), then I will just post it. – zeel May 08 '13 at 18:36
  • @zeel Please, do post that link as your answer and upvote the original author. I deserved no credit here :) – Paweł Staniec May 11 '13 at 11:19
  • I wouldn't say the range input or number input mean nothing on a printed HTML page. – Jessica Nov 13 '18 at 08:37
  • @JessicaWard It's not that they don't mean *anything* it's that they don't provide a function for the user. There may be scenarios in which printing them out visually would be useful. However, for the purpose of a form that needs to be filled in, they just get in the way in print. On a computer, they make input a bit easier (and make it easier to set bounds and increments), but if you print the form out (so that it can be filled in by hand, or so that a hard copy can be retained) those controls are useless, they are just pictures that get in the way of what the user needs to do. – zeel Dec 11 '18 at 16:18

6 Answers6

3

You can try to hide specific elements with CSS selectors

@media print {
    input[type=range] {
        display: none;
    }
}

However, to hide the arrows in a number element, perhaps you could try to put 2 elements instead, 1 text and 1 number, and then display the number when in screen mode, while the text is hidden, and vice-versa in print mode

@media print {
    input[type=text] {
        display: inline-block;
        border:none;
        border-bottom:2px solid #000;
        etc..
    }
    input[type=number] {
        display: none;
    }
}
@media screen {
    input[type=number] {
        display: inline-block;
    }
    input[type=text] {
        display: none;
    }
}

Something similar can be done for other form elements. It will depend on your implementation if you can use this method.

Opifexer
  • 176
  • 8
  • Like the other answer, that requires that the `text` box be updated with the value of the `number` constantly. As far as I know, this will always require JS. – zeel May 06 '13 at 22:56
2

This effect can be achieved in webkit browsers. I still can not find a way to do it in others, but it will work for webkit.

@media print {
    input::-webkit-outer-spin-button,  
        input::-webkit-inner-spin-button {
        -webkit-appearance: none;
    }
}

Webkit actually treats those buttons as pseudo elements (with good reason) and provides a way to hide them. This is exactly the kind of behavior one would want, though being limited to just webkit is a bit annoying.

zeel
  • 1,101
  • 1
  • 13
  • 31
2

A better solution, as it doesn't use vendor prefix, will be to use the output element.

Principles

  1. hide output element on @media screen ;
  2. update the value of the output element on field input ;
  3. toggle visibility of the input and the output element on @media print.

codepen available here.

HTML

<form onsubmit="return false" oninput="print.value = parseInt(screen.value)">
  <input class='screen' name="screen" type="number" value='0'> →
  <output class='print' name="print">5 (default print value)</output>
</form>
<p>The <code>output</code> element replace the <code>input</code> on print media</p>

CSS

.print {
  display: none;
}

@media print {
  .screen {
    display: none;
  }
  .print {
    display: inline-block;
  }
}
Édouard Lopez
  • 40,270
  • 28
  • 126
  • 178
  • 1
    This is the same answer as others, you just used a different (more semantic, but ultimately no more useful) element. The goal is to change the apearance of the page without actualy changing the content. – zeel Jun 30 '15 at 18:05
  • I'm not using vendor prefix at all, but standard CSS and as you said it's more semantic. It is indeed not a pure CSS answer but being aware of `output` might help in other form scenario. – Édouard Lopez Jul 03 '15 at 07:50
1

try to use a hidden test on screen and then show it on print

@media print {
    .hideOnprint {
        display: none;
    }
    .hideOnScreen {
        display: block;
    }
}
@media screen {
    .hideOnprint {
        display: block;
    }
    .hideOnScreen {
        display: none;
    }
}

affect the text with the class hideOnScreen and the input with the class hideOnPrint

wannas
  • 388
  • 3
  • 11
  • This doesn't answer the question I asked. – zeel May 06 '13 at 10:39
  • I am looking for a solution that fixes the display behavior of the `input`s, using CSS. Hidden text would require JavaScript, which is not what I am looking for. – zeel May 06 '13 at 15:33
  • you dont need javascript to hide text, u can hide it with css by using `display:none;` i haven't any idea how to fix the display behaviour of the input with css. good luck – wannas May 07 '13 at 07:44
  • The hidden text will not show the value of the input unless I update it with JS. – zeel May 07 '13 at 19:26
0

Maybe you should use a simple javascript to get only the values of the concerned fields, on print action, change to a printable format, perform the print and change it right back to normal?

Really don't know if doable using only CSS.

You might want to consider using XML parsing mechanism. This is a really convenient method for such tasks.

http://webdesign.about.com/od/xslt/a/xslt-tutorial-1.htm

trox
  • 306
  • 4
  • 12
0

An alternative would be to provide a link to print, and have another copy of the page without all the extra stuff

ie:        www.something.com/page.htm
printpage  www.something.com/page-print.htm

this is the most common practice (also, you can reuse css with the print only parts in it)

hope that helps

Ess Kay
  • 598
  • 4
  • 20
  • Then I would need to submit the information to the server, and have it deal with it, and return the printer friendly page. This requires that a web-server is available. – zeel May 06 '13 at 23:00
  • not nessesarily . you can add a button from here http://www.printfriendly.com/button – Ess Kay May 07 '13 at 15:56
  • you can also use the same page but have two css pages --> read more here http://stackoverflow.com/questions/46718/best-way-to-make-a-printer-friendly-asp-net-page – Ess Kay May 07 '13 at 15:57