Print when textarea has overflow - html

I have a form with some text areas that allow a scroll bar when the text exceeds the text box. The user would like to be able to print the screen, and this text is not visible. How do I make all of the text visible for just printing? Am I better of making a print to pdf link or something?

You cannot solve this problem with CSS alone.
Why Pure-CSS Solutions are Insufficient (with demo)
Let me convince you the answers involving print stylesheets and overflow: visible are insufficient. Open this page and look at the source. Just what they suggested, right? Now print preview it (in, say, Chrome 13 on OS X, like me). Note that you can only see a line or two of the note when you attempt to print!
Here’s the URL for my test case again: https://alanhogan.github.io/web-experiments/print_textarea.html
Solutions:
A JavaScript link that opens a new window and writes the contents of the textarea to it for printing. Or:
When the textarea is updated, copy its contents to another element that that his hidden for screen but displayed when printed.
(If your textarea is read-only, then a server-side solution is also workable.)
Note that textareas treat whitespace differently than HTML does by default, so you should consider applying the CSS white-space: pre-wrap; in the new window you open or to your helper div, respectively. IE7 and older do not understand pre-wrap however, so if that is an issue, either accept it or use a workaround for them. or make the popup window actually plain text, literally served with a media type text/plain (which probably requires a server-side component).
The “Print Helper” Solution (with code + demo)
I have created a demo of one JavaScript technique.
The core concept is copying the textarea contents to another print helper. Code follows.
HTML:
<textarea name="textarea" wrap="wrap" id="the_textarea">
</textarea>
<div id="print_helper"></div>
CSS (all / non-print):
/* Styles for all media */
#print_helper {
display: none;
}
CSS (print):
/* Styles for print (include this after the above) */
#print_helper {
display: block;
overflow: visible;
font-family: Menlo, "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", Monaco, monospace;
white-space: pre;
white-space: pre-wrap;
}
#the_textarea {
display: none;
}
Javascript (with jQuery):
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript">
jQuery(function($){
function copy_to_print_helper(){
$('#print_helper').text($('#the_textarea').val());
}
$('#the_textarea').bind('keydown keyup keypress cut copy past blur change', function(){
copy_to_print_helper(); // consider debouncing this to avoid slowdowns!
});
copy_to_print_helper(); // on initial page load
});
</script>
Again, the successful JavaScript-based demo is at https://alanhogan.github.io/web-experiments/print_textarea_js.html.

Loop through each of your text areas and move the content to a holder
window.onbeforeprint = function () {
$('.print-content').remove();
$('textarea').each(function () {
var text = $(this).val();
$(this).after('<p class="well print-content">' + text + '</p>');
});
}
And use the following CSS
.print-content {
display: none !important;
}
#media print {
.print-content {
display: block !important;
}
textarea {display: none !important;}
}

I recently ran into the same issue. My solution was to duplicate the content into form controls for editing and into divs for printing.
In my Head I put a print stylesheet.
<link rel="stylesheet" href="printform.css" type="text/css" media="print" />
In printform.css I put the following
.screenOnly { display: none; }
.printOnly { display: inline-block; }
For textareas (and other field types that were causing problems) I used the following code
<textarea class="screenOnly" name="myTextArea"><?php echo (htmlspecialchars ($_POST ['myTextArea'])); ?></textarea>
<div class="printOnly"><?php echo (htmlspecialchars ($_POST ['myTextArea'])); ?></div>
When displayed on screen the textareas are shown and the divs duplicating their content are hidden. When printing the opposite applies.
I know you already picked an answer to this question but while using the print stylesheet is a good idea it didn't describe a specific solution. Setting overflow:visible on the textarea (my first idea) didn't work so I ended up going with the solution above. If you're still having difficulties I hope this helps you out

Just encourter the problem recently too. Thanks for Alan H's posts. It works perfect with Chrome and Safari. However, with IE and Firefox, the issue is that the last several pages(page elements after textarea) will be missing from printing(FF), missing pages and overlapped layout(IE9).
Another finding that will be helpful to solve the issue is, you can set textarea's rows properties correctly as the control's height says to make it work with CSS overflow:visable stuff. All browsers seems to respect the rows property while printing.

This seems to work for applying to all elements that have overflowing content:
$("textarea").each(function () {
var Contents = $(this).val();
if ($(this)[0].scrollHeight > $(this).height()) {
$(this).after("<div class='print-helper'>" + Contents + "</div>");
$(this).addClass("no-print");
}
});

This is an easy fix with CSS, given that most users aren't really bothered about printing a bit of extra blank space. Just target a minimum height for textareas when printing:
#media print {
textarea {
min-height: 500px;
}
}
Tag that onto the end of your CSS with a min-height that is comfortably enough when you look at it in Print Preview.

With the usage of pure CSS it is not possible to prepare the textarea for printing.
It is necessary to add some javacript magic to the text area or add a hidden field.
There are a couple of solutions, that have been mentioned here:
Hidden paragraph or div
Using Javascript to extent the size of the textarea
1. Hidden paragraph or div
HTML & CSS:
<textarea>Sample Text</textarea>
<div class="hidden-div">Sample Text</div>
<style>
.hidden-div{display: none;}
#media print{
.hidden-div{display:block;}
}
</style>
2. Javascript
You could use a js library e.g https://github.com/thomasjo/jquery-autoresize
$(function() {
$("textarea").autoResize()
})

Adding onto Alan's answer above, if you have multiple instances of this problem on the same page, then you can use data-* attributes to handle all at once. Sample:
var $printOnlyArr = $('.print-only');
for (var i = 0; i < $printOnlyArr.length; i++) {
var $printOnly = $($printOnlyArr[i]);
var textSource = $printOnly.data('textsource');
if (textSource) {
$printOnly.text($("#" + textSource).val());
}
}
.print-only {
display: none;
}
#media print {
.print-only {
display: block;
}
.no-print {
display: none;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea class="form-control no-print" maxlength="2000" id="txtAdditionalComments"></textarea>
<div class="print-only" data-textsource="txtAdditionalComments"></div>

I had this same problem. My project is React, I was a semnaticUi TextArea component. The Text that could only be seen by scrolling down in the Textarea aka the "overflow" could not be seen in the print view when I press the print screen button.
Solution :)
I just used a normal paragraph tag instead and set css white-space: pre-wrap on a div that enclosed the p tag.
Worked for me!

try this using jQuery. Redefine height of all textareas based on quantity of lines.
Attention: this code change the textarea on screen too
window.onbeforeprint = function () {
$('textarea').each(function () {
var lines = Math.round($(this).val().split('\n').length * 1.6) ; //multiply to 1.6 to consider spacing between lines
$(this).height(lines+'em');
});
}

Define a separate CSS for print media like this <link rel="stylesheet" href="print.css" type="text/css" media="print" /> and for the text area, define the overflow attribute as
overflow: visible;

I use this in my styling:
PRE.print {
display:none;
}
#media print {
TEXTAREA {
display:none;
}
PRE.print {
display:block;
width:90%; /* fixes margin issues in some funky browsers */
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
font-family:monospace,sans;
}
}
Then, after every TEXTAREA, I use a PRE with class "print" like so:
<textarea id="message" name="message" rows="10" cols="80" onblur="updatePrint('#message')"><?= $MESSAGE ?></textarea>
<pre id="message-print" class="print">
<?= $MESSAGE ?>
</pre>
...note the PHP I used -- you can switch with your programming language. And then this code above needs the following function, assuming you have jQuery library loaded:
<script type="text/javascript">
function updatePrint(sID) {
$(sID + '-print').text($(sID)[0].value);
}
</script>
The way this all works
The way this works is that I'm basically loading content twice into the page, but using the stylesheet to hide content not suitable for the printer like the TEXTAREA.
You can change the PRE styling as you wish. However, I use monospace in case someone was wanting to print HTML code that they typed into the field and wanted it to format nicely.
The onblur event helps capture a need to update the related PRE.
Note you can also do the stylesheet stuff via the media attribute on a link rel in the HEAD section of your HTML, using things like media="all not print" and media="print".

Related

Remove Certain CSS Style from Html Page

I have a Html page which has anchor tag, I Need to remove certain style applied already in html page for anchor tag while the html page is opened throw Iframe.
HTML Content as below:
<html>
<body>
<div>some content<a href="http://www.website.com" name="test1"/> some content </div>
</body>
</html>
I tried as below:
a[name^="test1"]:before{
content:"[prefix text]";
display:inline;
color:red;
}
a[name^="test1"]:after{
content:"suffix text";
display:inline;
color:green;
}
iframe a[name^="test1"]:before{
display:none;
}
iframe a[name^="test1"]:after{
display:none;
}
But inside "iframe" also these styles has been applying.
You have to first detect if your page is rendered inside an iframe and in that case apply an alternative CSS. It' can't be done with vanilla CSS then it has to be done with some JavaScript:
<script type="text/javascript">
function getTopWindow() {
try {
return window.top;
} catch {
// If we can't access window.top then browser is restricting
// us because of same origin policy.
return true;
}
}
function isRendererdInFrame() {
// If top window is null we may safely assume we're in iframe
return window.self !== getTopWindow();
}
function loadCss(location) {
if(document.createStyleSheet) {
document.createStyleSheet('http://server/stylesheet.css');
} else {
var styles = "#import url('" + location + "');";
var newSS=document.createElement('link');
newSS.rel='stylesheet';
newSS.href='data:text/css,'+escape(styles);
document.getElementsByTagName("head")[0].appendChild(newSS);
}
}
</script>
Code to load CSS from JavaScript is from How to load up CSS files using Javascript?.
With all that code you may simply write (even just after that inside <script> block):
var cssToLoad = isRendererdInFrame() ? "iframe.css" : "not-iframe.css";
loadCss("http://server/" + cssToLoad);
Of course same technique can be applied to patch CSS with iframe specific styles:
if (isRenderedInFrame())
loadCss("http://server/iframe-patch.css");
i dont know how to detect if page is opened in iframe or not, but there is one possible(not very nice) workaround, you can set iframe to width which is not commonly used by devices (example 463px) and then set media query for this resolution which apply when content is shown in this iframe. This is really nasty way since its not 100% and i would not recommending that.

HTML/CSS: Show full size image on click

I have a text + image side by side, and I want a function where the user can click on the image to make it bigger. I'm new to HTML/CSS so I was wondering how I can approach this. Thanks! (demo -> https://jsfiddle.net/DTcHh/6634/)
Is there any way to do this with pure HTML/CSS and no javascript?
The ones I found have been telling me to use javascript such as:
<script type="text/javascript">
function showImage(imgName) {
document.getElementById('largeImg').src = imgName;
showLargeImagePanel();
unselectAll();
}
function showLargeImagePanel() {
document.getElementById('largeImgPanel').style.visibility = 'visible';
}
function unselectAll() {
if(document.selection) document.selection.empty();
if(window.getSelection) window.getSelection().removeAllRanges();
}
function hideMe(obj) {
obj.style.visibility = 'hidden';
}
</script>
Is there a simpler way to do this in HTML/CSS?
You could use a CSS pseudo-class to change the styling when, for example, the mouse is over the image:
img:hover {
width: 300px;
height: 300px;
}
Generally, though, to add interactivity to your web pages, you will have to become acquainted with JavaScript. I don't know of any way to toggle a state (e.g. "zoomed-in") without the use of JavaScript.
You can think of the HTML as defining the content, the CSS as defining how it looks, and the JavaScript as defining how it behaves.

div to appear in full screen

I am new to html. Can I make a particular div in my web-page appear in fullscreen when I press alt and space keys? This is my code.
<!DOCTYPE html>
<html>
<body>
<p>This is some text.</p>
<div style="color:#0000FF">
<img src="./1.jpg" height="42" width="42">
</div>
</body>
</html>
Use the full-screen pseudo class (for webkit and mozila) :
:-webkit-full-screen {
/* css rules for full screen */
}
:-moz-full-screen {
/* css rules for full screen */
}
See this Mozilla article and this David Walsh article for usage
HTML and CSS provide no means to trigger full screen mode for an element. JavaScript is your only option.
HTML 5 introduces a full screen API for JavaScript. It is still experimental, so you need to use prefixed property names in some browsers and it won't work at all in others.
function makeFullScreen(element) {
if (element.requestFullScreen) {
element.requestFullScreen();
} else if (element.webkitRequestFullScreen) {
element.webkitRequestFullScreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.msRequestFullScreen) {
element.msRequestFullScreen();
}
}
You then just need to bind an event handler to call it.
document.addEventListener('keypress', function (evt) {
if (evt.altKey && evt.keyCode === 32) {
makeFullScreen(document.querySelector('div'));
}
});
Beware of depending on modifier keys though. On my system, alt + space is captured at the OS level (to open Spotlight) so it will never reach the browser.

How to style readonly attribute with CSS?

I'm currently using readonly="readonly" to disable fields. I'm now trying to style the attribute using CSS. I've tried using
input[readonly] {
/* styling info here */
}
but it is not working for some reason. I've also tried
input[readonly='readonly'] {
/* styling info here */
}
that doesn't work either.
How can I style the readonly attribute with CSS?
input[readonly]
{
background-color:blue;
}
https://curtistimson.co.uk/post/css/style-readonly-attribute-css/
Note that textarea[readonly="readonly"] works if you set readonly="readonly" in HTML but it does NOT work if you set the readOnly-attribute to true or "readonly" via JavaScript.
For the CSS selector to work if you set readOnly with JavaScript you have to use the selector textarea[readonly].
Same behavior in Firefox 14 and Chrome 20.
To be on the safe side, i use both selectors.
textarea[readonly="readonly"], textarea[readonly] {
...
}
Loads of answers here, but haven't seen the one I use:
input[type="text"]:read-only { color: blue; }
Note the dash in the pseudo selector. If the input is readonly="false" it'll catch that too since this selector catches the presence of readonly regardless of the value. Technically false is invalid according to specs, but the internet is not a perfect world. If you need to cover that case, you can do this:
input[type="text"]:read-only:not([read-only="false"]) { color: blue; }
textarea works the same way:
textarea:read-only:not([read-only="false"]) { color: blue; }
Keep in mind that html now supports not only type="text", but a slew of other textual types such a number, tel, email, date, time, url, etc. Each would need to be added to the selector.
To be safe you may want to use both...
input[readonly], input[readonly="readonly"] {
/*styling info here*/
}
The readonly attribute is a "boolean attribute", which can be either blank or "readonly" (the only valid values). http://www.whatwg.org/specs/web-apps/current-work/#boolean-attribute
If you are using something like jQuery's .prop('readonly', true) function, you'll end up needing [readonly], whereas if you are using .attr("readonly", "readonly") then you'll need [readonly="readonly"].
Correction:
You only need to use input[readonly]. Including input[readonly="readonly"] is redundant. See https://stackoverflow.com/a/19645203/1766230
There are a few ways to do this.
The first is the most widely used. It works on all major browsers.
input[readonly] {
background-color: #dddddd;
}
While the one above will select all inputs with readonly attached, this one below will select only what you desire. Make sure to replace demo with whatever input type you want.
input[type="demo"]:read-only {
background-color: #dddddd;
}
This is an alternate to the first, but it's not used a whole lot:
input:read-only {
background-color: #dddddd;
}
The :read-only selector is supported in Chrome, Opera, and Safari. Firefox uses :-moz-read-only. IE doesn't support the :read-only selector.
You can also use input[readonly="readonly"], but this is pretty much the same as input[readonly], from my experience.
input[readonly], input:read-only {
/* styling info here */
}
Shoud cover all the cases for a readonly input field...
capitalize the first letter of Only
input[readOnly] {
background: red !important;
}
<input type="text" name="country" value="China" readonly="readonly" />
If you select the input by the id and then add the input[readonly="readonly"] tag in the css, something like:
#inputID input[readonly="readonly"] {
background-color: #000000;
}
That will not work. You have to select a parent class or id an then the input. Something like:
.parentClass, #parentID input[readonly="readonly"] {
background-color: #000000;
}
My 2 cents while waiting for new tickets at work :D
Use the following to work in all browsers:
var readOnlyAttr = $('.textBoxClass').attr('readonly');
if (typeof readOnlyAttr !== 'undefined' && readOnlyAttr !== false) {
$('.textBoxClass').addClass('locked');
}

Webkit (Chrome/Safari) does not update display when custom attribute selected is changed

Working example: http://jsfiddle.net/JVVcA/
HTML:
<fieldset id="data-page">
<legend>data-page</legend>
<button rel="page1">Highlight page one</button>
<button rel="page2">Highlight page two</button>
<div data-page="page1">
<h1 id="page1">Page one</h1>
<h1 id="page2">Page two</h1>
</div>
</fieldset>
<fieldset id="class">
<legend>class</legend>
<button rel="page3">Highlight page three</button>
<button rel="page4">Highlight page four</button>
<div class="page3">
<h1 id="page3">Page three</h1>
<h1 id="page4">Page four</h1>
</div>
</fieldset>
CSS:
fieldset { border: 1px solid #aaa; padding: 5px; }
h1 { background-color: white; }
div[data-page="page1"] h1#page1 { background-color: pink; }
div[data-page="page2"] h1#page2 { background-color: pink; }
div.page3 h1#page3 { background-color: cyan; }
div.page4 h1#page4 { background-color: cyan; }
JS:
$('#data-page button').click(function(){
var rel = $(this).attr('rel');
$(this).siblings("div").attr('data-page', rel);
});
$('#class button').click(function(){
var rel = $(this).attr('rel');
$(this).siblings("div").attr('class', rel);
});
Initial load:
After clicking "Highlight page two" and "Highlight page four" in Webkit (specifically, Google Chrome stable Windows 7):
After doing the same in Firefox:
As you can see, the data-page selector works fine on the initial rendering of the of the page, but when the DOM is manipulated on the fly, styles defined by the [data-page="???"] CSS selector are not affected accordingly. Compare this to the situation with the class selectors. When classes are changed on the fly, the styles change as expected.
A possibly related note is that I've encountered cases while using this attribute selector in conjunction with CSS transitions where a similar lack of responsiveness happens, but on those cases, clicking elsewhere on the page, waving your mouse around, or just waiting for a bit eventually results in the expected change going through.
So is there a way around this other than to just throw up your hands and not use data-page-style attributes?
It's the same issue that's applied for the ~ or multiple + selectors and pseudo-classes in webkit: this kind of selectors are rendered only once and the last time I checked the relevant bug reports in webkit's tracker, they stated that it works like intended.
But, some people had found the fix, but it's really is overhead: to add always-reflowing property to body, so it's must be added only to those elements, where something changes, the divs inside field sets for your example.
So, there is a fixed fiddle: http://jsfiddle.net/JVVcA/2/
And these are the styles for fixing such problems:
/* The `fixing` animation */
#-webkit-keyframes bugfix { from { padding: 0; } to { padding: 0; } }
.anElementToFix { -webkit-animation: bugfix infinite 1s; }
Note that you must add the fix to the element whose attribute is can be changed, not the targeted by selector elements.
My version of workaround.
$('#data-page button').click(function(){
var rel = $(this).attr('rel');
var my_div = $(this).siblings("div");
my_div.attr('data-page', rel);
var my_html = my_div.html();
my_div.html(my_html);
});
$('#class button').click(function(){
var rel = $(this).attr('rel');
$(this).siblings("div").attr('class', rel);
});
Running an animation seems overly expensive.
Thanks to Zoltan Olah, I found a much more elegant, concise, and efficient workaround.
Simple toggle a nonsense class on the body. This will cause contained selectors to be re-evaluated.
You don't even have to define this class in CSS. Just applying it forces Safari to hunt through the page re-evaluating things.
Every time you change the attribute in question, toggle this class on or off to force the re-evaluation.
// change some attribute
$(".blah").attr("state", "otherState"); // example of changing an attribute (your app will be different)
$('body').toggleClass('zoltan'); // THIS IS THE LINE YOU MUST ADD EVERY TIME YOU CHANGE THE ATTRIBUTE