How to make text area to fit dynamic content completely without any overflow? - css

This is an angular app (but anyone with css knowledge can help), where there is a text area with dynamic content.
So as the content item.text changes the text area should grow or shrink according to the content to fit the content perfectly without any overflow.
<textarea [value]="item.text" [placeholder]="item.text ? '' : 'Your Text Here...'" class="font-xl font-bold"></textarea>
// dont worry about the placeholder. you can ignore that.
Currently in my case scrollbar appears & it is not shrinking or growing with the dynamic content.
How can I achieve that?
Or if there is a way to convert a regular html <div> to a textarea, you can suggest that too. But prefers a solution for the above one.
I've tried css rules like, max-content fit-content etc... nothing is working out!

Install npm install ngx-autosize
in html add autosize
<textarea autosize [value]="item.text" [placeholder]="item.text ? '' : 'Your Text Here...'" class="font-xl font-bold"></textarea>
then in appmodule
put in imports: [AutosizeModule ],
Demo

This can't be accomplished with just css, it needs JavaScript that has quite a few corner cases and can be tricky. Such as, pasted input, input populated programatically, auto filled input, handling screen size changes correctly, and on and on, and doing so in a way that is reusable and performs well.
Given all that, I recommend using a lib for this.
I've used angular material's plenty of times with no issues, just add material to your project (can be done via angular CLI with ng add #angular/material) and either import the MatInputModule from #angular/material/input or TextFieldModule from #angular/cdk/text-field (TextFieldModule is quite a bit smaller) to the module where you want to use it, then do:
<textarea cdkTextareaAutoSize cdkAutosizeMinRows="5" [value]="item.text" [placeholder]="item.text ? '' : 'Your Text Here...'" class="font-xl font-bold"></textarea>
you can exclude the cdkAutosizeMinRows option and then it will default to 1 row, but you can use that option to set however many minimum rows you'd like to display. You can also use the cdkAutosizeMaxRows option to make it stop growing at a certain number of rows if you wish, otherwise it will grow indefinitely with the content.
blitz: https://stackblitz.com/edit/angular-4zlkw1?file=src%2Fapp%2Ftext-field-autosize-textarea-example.html
docs: https://material.angular.io/components/input/overview#auto-resizing-textarea-elements
https://material.angular.io/cdk/text-field/overview

You can't change the height of the textarea without Javascript. But you can use an editable div instead. In plain HTML something like this would serve the same purpose as an textarea and will resize automatically based on the content.
<div class="font-xl font-bold" contentEditable>Hello World</div>

If you use a <div> which you can edit then it can grow or shrink accordingly.
<div contenteditable="true">This is a div. It is editable. Try to change this text.</p>

The below will loop over the item and compare height to scrollHeight incrementing the height by lineHeight. Then resets the rows once the height is greater than the scroll height
(function () {
const el = document.querySelector('textarea');
dynamicallyResize(el);
el.addEventListener('change', function () { dynamicallyResize(el); });
})();
function dynamicallyResize(el) {
el == undefined && (el = this.target);
const lineHeight = 16;
let i = el.getAttribute('rows'),
height = Math.ceil(el.getBoundingClientRect().height);
el.style.overflow = 'visible'; //triger redraw
while(height < el.scrollHeight) {
height += lineHeight;
i++;
el.setAttribute('rows', i);
}
el.style.overflow = 'auto';
}
<textarea [value]="item.text" [placeholder]="item.text ? '' : 'Your Text Here...'" class="font-xl font-bold" rows="2">Starting text that exceeds the 2 row limit initially placed on this particular text area.</textarea>

Related

React-big-calendar with bootstrap 4.0 alpha layout ugly

I am using bootstrap 4.0 alpha with no other styles. The layout is very ugly that, the calendar shows only a single column instead of a table. Any idea of why and how?
I notice the following from the website, but I don't understand what should I do:
note: The default styles use height: 100% which means your container must set an explicit height (feel free to adjust the styles to suit your specific needs).
This is my rendering code:
render() {
return (
<div className="container">
<TaskSearchBar
search={this.onSearch}
/>
<BigCalendar
selectable
events={[]}
defaultView='week'
scrollToTime={new Date(1970, 1, 1, 6)}
defaultDate={new Date(2015, 3, 12)}
onSelectEvent={event => alert(event.title)}
onSelectSlot={(slotInfo) => alert(
`selected slot: \n\nstart ${slotInfo.start.toLocaleString()} ` +
`\nend: ${slotInfo.end.toLocaleString()}`
)}
/>
<TaskList
queryUrl={this.state.queryUrl}
/>
</div>
);
}
This is the layout result
I found I missed this line:
require('react-big-calendar/lib/css/react-big-calendar.css');
Thanks to enter link description here
In case you still run into any issues, that snippet you copied says that the element containing BigCalendar needs to have a specific height set on it, like 420px or 60%. That'll keep the flexbox algorithm from greedily eating space. If you don't do that, you'll find that the day view renders every single hour at once, rather than providing a scrollable window.

Disable width and height fields from image properties windows

Disable width and height fields from image properties I am using ckeditor 4
CKEDITOR.replace('<%=txtCkEditor.ClientID %>', {allowedContent:'img[!src,alt];'});
By using above method it shows only image properties with width and height hidden and rest of the controls also get visible false. Kindly suggest me a solution for disabling the width and height fields from image properties windows.
Thanks in advance.
I'm not sure I entirely understand your question. It seems you want to hide the fields that allow input of height and width. Your initial solution doesn't seem to affect the dialog box, but what content gets saved. These are very different kinds of solutions. My answer assumes you're seeking to alter the image properties dialog box fields.
Based on this earlier question, I recommend adding the following configuration:
CKEDITOR.on('dialogDefinition', function(ev) {
var editor = ev.editor;
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
if (dialogName == 'image') {
var infoTab = dialogDefinition.getContents( 'info' );
infoTab.remove( 'txtWidth' ); // Remove width element from Info tab
infoTab.remove( 'txtHeight' ); // Remove height element from Info tab
}
});

Wrap text from bottom to top

Anybody know how I could wrap the text in reverse order, from bottom to top?
I attached an example image.
[][http://i.stack.imgur.com/RVsIG.jpg]
Instead of breaking the line after it is full and having an incomplete line at the end, I need to brake somehow from bottom to top, so bottom lines are full and top line is incomplete.
I would not recommend using exotic CSS attributes which aren't even in Chrome & Firefox yet. The best cross-browser solution is to handle this in Javascript when the document loads. Here's a sketch of how to do that:
$(function() {
$(".title").each(function(i,title) {
var width = 0;
var originalHeight = $(title).height();
var spacer = $('<div style="float:right;height:1px;"/>').prependTo(title);
while (originalHeight == $(title).height()) {
spacer.width( ++width );
}
spacer.width( --width );
});
});
Working JSFiddle is here: http://jsfiddle.net/zephod/hfuu3m49/1/
6 years later, but fret not! I have found a pure CSS solution!
Turns out you can achieve this result with flexbox, but it's not obvious or very straight forward. This is what I started out with:
I want the header to be "bottom-heavy", the same effect as you describe in the question.
I began by splitting up my string by whitespace and giving them each a <span> parent. By using flex-wrap: wrap-reverse, and align-content: flex-start. You will achieve this:
Oh no! Now the order is messed up! Here comes the trick. By reversing both the order in which you add spans to the HTML and the direction order of flex with 'flex-direction: row-reverse', you actually achieve the "pyramid-shaped" upwards overflow effect you desire.
Here is my (simplified) code, using react and react-bootstrap:
<Row className='d-flex flex-wrap-reverse flex-row-reverse align-content-start'>
{props.deck.name
.split(' ')
.reverse()
.map(word => (
<span className='mr-1'>{word}</span>
))}
</Row>
There is no general css solution for it. You must have to utilize help of any language.
This is one of the solution using PHP:
<?php
$str= "This is what I want to achieve with your help";
$str = strrev($str);
$exp = str_split($str,18);
$str = implode(">rb<", $exp);
echo strrev($str);
?>
Well, if that is depending on the text, then you can try something like a word replacer. For example
var words = "This is what I want to achieve";
var newWords.replace("what", "what <br />"); // note the line break
document.write(newWords);
Here is a fiddle for you: http://jsfiddle.net/afzaal_ahmad_zeeshan/Ume85/
Otherwise, I don't think you can break a line depending on number of characters in a line.
Wrap and Nowrap will be rendered by the client-browser, so you can not force the browser to wrap from bottom to top. but you can do that with javascript or asp.
This is not a formal solution for this problem. But see if this helps.
The HTML CODE
<div id="mydiv">
I can imagine the logic behind the code having to detect what is the last line, detect the div size, and the font size... then measure how many characters it can fit and finally go to the above line and insert the break where necessary. Some font families might make this harder, but trial and error should solve the issue once the basic code is set..
</div>
CSS:
#mydiv
{
width:1000px;
line-height:18px;
font-size:20px;
text-align:justify;
word-break:break-all;
}
Here setting the div width around 50 times that of the font-size will give you the precise result. Other width values or font values might slightly disorient the last line, giving some blank space after the last character.(Could not solve that part, yet).
JQuery:
$(document).ready(function(){
//GET the total height of the element
var height = $('#mydiv').outerHeight();
//Get the height of each line, which is set in CSS
var lineheight = $('#mydiv').css('line-height');
//Divide The total height by line height to get the no of lines.
var globalHeight = parseInt(height)/parseInt(lineheight);
var myContent = $('#mydiv').html();
var quotient = 0;
//As long as no of lines does not increase, keep looping.
while(quotient<=globalHeight)
{
//Add tiny single blank space to the div's beginning
$('#mydiv').html(' '+myContent);
//Get the new height of line and height of div and get the new no of lines and loop again.
height = $('#mydiv').outerHeight();
lineheight = $('#mydiv').css('line-height');
quotient = parseInt(height)/parseInt(lineheight);
myContent = $('#mydiv').html();
}
//get the final div content after exiting the loop.
var myString = $('#mydiv').html();
//This is to remove the extra space, which will put the last chars to a new line.
var newString = myString.substr(1);
$('#mydiv').html(newString);
});
If you already know where you want your breaks to take place just use simple HTML breaks to break your content and have it display the way you want.
<p>This is what<br/>
want to acheive with your help</p>
If you set the breaks manually (and you know where you want them to break) then create them yourself.
You could also try setting separate css width adjustments based on the dimensions of the screen you are seeing the breaking you are not liking and set an #media reference to make the div width smaller to break the text so it doesn't run unevenly across the top of certain size devices.
Use display: inline-block; on the text div.

Adjust size based on height (vertical length)

I am doing a div that needs to display the whole content of a text field and adjust the text size dynamically so that it will not overflow.
To get an idea of the problem, look here http://sandbox.littlegraffyx.com/bible/
You can try entering verses at lower left text box using the format GEN 1:1 for "Genesis 1:1"
My problem is when I try to display long verses, they get truncated. I need to change the size based on how long the current text is. Is there some css that can be applied based on text field size?
As mentioned in the comments, it isn't possible to scale text based on the height of its containing element using pure CSS. But here's a small jQuery script I have used in the past when I needed to achieve what you want. It also adjusts the text size when the user resizes the browser window.
HTML:
<p class="quote">
Really long text goes here...
</p>​
CSS:
.quote {
// The largest size to display text at.
font-size: 36px;
}​
JS:
$(window).bind('resize',function(e){
scaleQuote();
});
function scaleQuote(){
var quote = $('.quote');
var winH = $(window).height();
// Reset font size.
quote.css('font-size', '');
// If quote is larger than viewport, reduce font-size until it fits.
while (winH < (quote.height())){
var fontSize = parseInt(quote.css('font-size'), 10);
quote.css('font-size', fontSize-1+'px');
}
}
scaleQuote();​
Demo: http://jsfiddle.net/eCBmc/2/
You can try something like this. It will set input field to 10 character, and if it's bigger it increase it's size.
http://jsfiddle.net/4qjjf/1/
<html>
<body>
<textarea cols="10" rows="1" id="shit"
onkeyup="this.cols=this.value.length>10?this.value.length:10;"></textarea>
</body>
</html>​

Autosize Text Area (Multiline asp:TextBox)

I have a MultiLine asp:Textbox (a standard html textarea for those non-asp people) that I want to be auto-sized to fit all it's content only through css. The reason for this is that I want it to be of a specified height in the web browser, with scrolling enabled.
I have implemented a print style sheet however and want all text located in the textarea to be displayed when printed with no overflow hidden.
I can manually specify the height of the textarea in the print.css file problem with this being that the fields are optional and a 350px blank box is not optimal and there is always the possibility of a larger amount of text than this...
I have tried using :
height: auto;
height: 100%;
In IE and Firefox respectively yet these seem to be overridden by the presence of a specified number of rows in the html mark-up for the form which must be generated by .NET when you do not specify a height on the asp:Textbox tag, this seems to only accept numercial measurements such as px em etc...
Any ideas?
What you are asking for (a css solution) is not possible.
The content of the textarea is not html elements, so it can not be used by css to calculate the size of the textarea.
The only thing that could work would be Javascript, e.g. reading the scrollHeight property and use that to set the height of the element. Still the scrollHeight property is non-standard, so it might not work in all browsers.
jQuery or a javascript function to find and make textboxes bigger might be the best solution - at least thats what i found
we use this set of functions and call clean form after the page is loaded (i know this isnt the best solution right here and am working to transfer to a jQuery solution that is more elegant) - one note make sure your textareas have rows and cols specified or it doesnt work right.
function countLines(strtocount, cols)
{
var hard_lines = 1;
var last = 0;
while (true)
{
last = strtocount.indexOf("\n", last + 1);
hard_lines++;
if (last == -1) break;
}
var soft_lines = Math.round(strtocount.length / (cols - 1));
var hard = eval("hard_lines " + unescape("%3e") + "soft_lines;");
if (hard) soft_lines = hard_lines; return soft_lines;
}
function cleanForm()
{
var the_form = document.forms[0];
for (var i = 0, il = the_form.length; i < il; i++)
{
if (!the_form[i]) continue;
if (typeof the_form[i].rows != "number") continue;
the_form[i].rows = countLines(the_form[i].value, the_form[i].cols) + 1;
}
setTimeout("cleanForm();", 3000);
}
If you set rows to be a ridiculously high number the CSS height rule should override it on the screen.
Then in the print stylesheet just set height to auto. This might result in some big blank space where all the available rows haven't been filled up, but at least all text will be visible.
give jQuery's autogrow() a go #
http://plugins.jquery.com/project/autogrow

Resources