Expand a text box to grow to fit its content with CSS? - html

I'm trying to get a content editable text box (div element) to grow as needed to fit the text typed into it, up to 80% of the width of the parent div.
Is there any way to do this with just CSS? If not, I'm open to Javascript solutions, but I am using React, which complicates things in that regard
This is NOT a duplicate of any other question I'm aware of, as it requires a solution which is:
Independent of viewport size
Supports a parent div with a max-width
Works on contentEditable
Works when the text content changes

May be you could have a div inside parent div which is 80% of the parent div. And then set width : auto for the text box.
Might sound a bit tricky.

I'm trying to get a text box to grow as needed to fit the text typed
into it, up to 80% of the width of the parent div.
I'm fairly certain this won't be possible via CSS alone, because there is no way for CSS to determine the length of the text-content of the textarea.
With javascript, on every keypress, you can check the length of the text-content and if:
the text-content is above a certain number of keypresses; and
the width of the textarea is still narrower than the maximum allowed width
then the textarea can incrementally expand.
Working Example:
var myTextArea = document.getElementsByTagName('textarea')[0];
var myTextLength = myTextArea.value.length
var myTextWidth = parseInt(window.getComputedStyle(myTextArea).width);
var myTextMinLength = 20;
var myTextMaxWidth = ((parseInt(window.getComputedStyle(document.body).width) / 100) * 80);
function checkTextLength() {
myTextLength = myTextArea.value.length;
if ((myTextLength > myTextMinLength) && (myTextWidth < (myTextMaxWidth))) {
myTextWidth += 8;
}
myTextArea.style.width = myTextWidth + 'px';
}
myTextArea.addEventListener('keypress', checkTextLength, false);
textarea {
width: 180px;
height: 40px;
}
<form>
<textarea placeholder="Start typing..."></textarea>
</form>

hm... try this:
display: inline-block;
I am not sure tho. Let me know if it works.

Related

Angular Material struggling adjust width of dialog elements

I'm working on a text dialog that I'll be reusing frequently in my app. My text dialog is fairly simple, it has a header, a message to display above the text input, the text input area, and an "Ok" and "Cancel" button.
From what I can see, the simplest way to adjust the width of a dialog is to pass it in with the MatDialogConfig object when calling open on the dialog, as so:
openDialog() {
var params = {
data: {
// my data getting pased into the dialog
},
width: "600px"
}
const dialogRef = this.dialog.open(TextDialog, params);
dialogRef.afterClosed().subscribe(() => { //do something after close });
}
This causes the window to increase to the preferred size, however all my elements inside the dialog's template do not increase in size. If I do not adjust the width when calling the window and I inspect the window's elements, the width is 228.27. The text input's width is 180.
When I increase the width of the element to 600, the input stays the same width. I've tried inspecting the dialog. Everything sits in the mat-dialog-container, including the div.mat-dialog-container element, both of those are the correct width. However, everything from the mat-form-field and below all still hold the original 180 pixel width. I can manually adjust the width with:
mat-form-field {
width: 600px;
}
But if I try using inherit or auto it doesn't work. Any help would be appreciated!
When using dynamic styling in Angular, use NgStyle.
This will allow you to pass expression-driven styling, thus letting Angular answer all the questions related to how and when to update the styles in the DOM.
I don't know why I didn't think of this sooner, but setting the width to 100% fixed the issue for me without any wizardry.
In my css file,
mat-form-field {
width: 100%;
}
This was all that was needed.

Calculate width from auto to pixel then add by pixel in LESS CSS

I want to use auto width and add x pixels to it.
How can this be acheived Less file?
span
{
width:calc(auto + 100px);
}
I want to use auto, since I don't know the length of the text. But I know a fixed size text gets append to it at some point. I don't want the span to grow larger when this happen. Therefore, adding 100px to auto would handle it perfectly.
You should do this with JQuery.
window.onload = function(){
$('span').width($('span').width()+100px);
};
And the CSS code remains
span{
width: auto;
}
EDIT: If the span content changes after the onload function is being executed, then you should execute that line whenever the content changes.
Here you can find how to do this. Credits to #Emile
1- The jQuery change event is used only on user input fields because if anything else is manipulated (e.g., a div), that manipulation is coming from code. So, find where the manipulation occurs, and then add whatever you need to there.
2- But if that's not possible for any reason (you're using a complicated plugin or can't find any "callback" possibilities) then the jQuery approach I'd suggest is:
a. For simple DOM manipulation, use jQuery chaining and traversing, $("#content").html('something').end().find(whatever)....
b. If you'd like to do something else, employ jQuery's bind with custom event and triggerHandler
$("#content").html('something').triggerHandler('customAction');
$('#content').unbind().bind('customAction', function(event, data) {
//Custom-action
});
Here's a link to jQuery trigger handler: http://api.jquery.com/triggerHandler/
As stated by #Paulie_D, this wasn't possible.
Proposed solution to handle this with Javascript would probably work, but I prefer to avoid this solution as I don't like handling the layout with Javascript instead of HTML/CSS.
The solution I used :
Use a DIV instead of a SPAN. This allowed to add another div inside it with a fixed width of 100px. This way, the parent div size to content including this 100px child div. Thus making the +100 needed.
When extra content is added, child div is used to display the extra content instead.
<div class="ParentDiv">
TextWithVariableLength
<div class = "ChildDiv"></div>
</div>
LESS
.ParentDiv
{
width: auto;
}
.ChildDiv
{
height:100%;
width: 100px;
}

Make readonly textarea's height determined by it's content

I would to make a readonly input appear like a pre or div tag with CSS.
I would have thought that it would have been easy to do with a textarea but it seems to be quite the task. I'm able to hide the border and the resizing but, for whatever reason, I can't make the textarea's height be determined by it's content.
I've seen a lot of stuff on using javascript to auto-resize textareas but is there anything I can do if it's static text that doesn't require javascript?
UPDATE
I just wanted to clarify the purpose of this: I'm looking to write, re-write with javascript, and submit a single readonly element with forms and, at the same time, not have it constrained to a single inline area which forces, at best, scrolling and, at worse, loss of data.
UPDATE 2
Per the request, I've created a fiddle to show an example of what I'm trying to do: http://jsfiddle.net/BUwdE/1/ .
textarea[readonly] {
width: 100%;
border: 0;
resize: none;
overflow: hidden;
}
You'll see that the content is cutoff at the bottom because the textarea's height isn't determined by its content.
I actually tried to do what you have been doing. But since it is going to be a read-only input, I actually ended up applying a CSS to a div element. This will be a hack which releases our headache.
HTML
<div class="faketextarea"> some long long text </div>
CSS
.faketextarea {
// css of a text area
}
You can specify the height of a textarea in HTML using the rows attribute, but that doesn't automatically resize. You might have to appeal to the W3C CSS Working Group to get what you want.
<textarea name="whatWillBeSentToServer" rows="4" readonly="readonly">
Modified from here:
function auto_grow(){
var ts = document.getElementsByTagName('textarea')
for (i in Object.keys(ts)){
ts[i].style.height = "5px";
ts[i].style.height = (ts[i].scrollHeight+49)+"px";
}
}
textarea {
resize: none;
overflow: hidden;
min-height: 50px;
max-height: 100px;
...
(properties for your needs)
}
<body onload='auto_grow()'>
<textarea>anytexts</textarea>
<textarea>texts 2</textarea>
</body>
The differences being I have assigned the auto_grow() function on the html <body> tag instead of the <textarea> tag
fiddle: https://jsfiddle.net/btq7m3a6/
More: https://jsfiddle.net/8o67huq2/

Make HTML button same size as its background

Usually, you make a button with a given size:
<button style="width: 120px; height: 40px;">
Mememe
<button>
Then you add a background which is the same size as the button:
button
{
background-size: 100% 100%;
}
Obviously, if you want it to be 1:1, the image should be 120x40 px too.
But is there a way to make the button same size as the image is? (With neither IMG elements nor scripts).
Regards,
No, not by using only HTML and CSS. It is, however, possible by using either PHP (or some other server-side scripting language) or JavaScript
One way might be to get the size of the loaded image, using JavaScript, and then apply the appropriate style on your button:
var width = document.images[0].width;
var height = document.images[0].height;
var button = document.getElementById('button-id');
button.style.width = width;
button.style.height = height;

how can i have multiple lines of text centered if they are not wide enough, and justified if they fill the entire width?

I have a large paragraph that I want to keep in one p tag. I have seen some solution, but it requires every line to be in a different tag.
the idea is to have lines justified and centered at the same time. I know in CSS it does not make sense as the property text-align defines both for some strange reason.
before posting a solution, please create one <p> or <div> or whatever you want, fill it with three lines of text, and make sure that the first two are justified, and the last one is centered. That is exactly what I am asking for.
I understood your original question and the clarification to be asking for two different things.
If you're trying to make a page that displays short text centered and a long paragraph justified then you could use javascript to check the length of the text and apply the appropriate style.
It would be pretty straightforward to do something like this with jquery:
<p id='fixed_text'>
Text above a certain length can be displayed as justified and shorter text can be centered
</p>
...
var maxLength = 100;
function sizeParagraph(){
if($('#fixed_text').text().length > maxLength){
$('#fixed_text').css('text-align','justified');
} else {
$('#fixed_text').css('text-align','center');
}
}
Rationale: if the height() is equal to the line-height, the paragraph (or any block element) gains the class "oneliner" (which is centered with a css rule).
css:
/*
all Ps should be {
text-align: justified;
height: auto;
} by default
*/
.oneliner {text-align: center}
js:
$(document).ready(function(){
$('p').each(function(){ // change the "p" selector at will
var $this = $(this);
if(Math.round(parseFloat($this.css('lineHeight'), 10)) == $this.height())
$this.addClass('oneliner');
});
});
Note that this will not work if you have nested images or block elements taller than the paragraph's line-height, or if the height is not auto.