getting the width of a specific element that it actually uses - javascript

I have an application, that takes html as input, renders an image and saves it. It also requires the user to specify the width and height that the image should be. I want to automate the height and width part so the user wouldn't need to set it up manually
The Problem:
if the html is as simple as <p>text</p> the height is pretty easy to find by using clientHeight but the width will be the whole width of the viewport and most of it would be absolutely unneeded to show text, so the picture would be very narrow (height = 16px; width = 1080px) and that is not great.
The Question:
is there any way to find the width of an element that it actually uses? (for instance width required by <p>text</p> would be closer to 16px but not 1080px)

You are having this error because elements such as <p> and <div> will extend the entire width of the parent by default. You should use width: fit-content to stop that.
div {
background-color: blue;
}
p {
background-color: red;
}
.width {
width: fit-content;
}
<div>This is a DIV with width: auto</div>
<p>This is a P with width: auto</p>
<div class="width">This is a DIV with width: fit-content</div>
<p class="width">This is a P with width: fit-content</p>
clientHeight will return the height for the entire window. You should focus on just the parent of the elements you want to render to get a better reading. Use offsetWidth and offsetHeight to get the full width of the parent.
var div = document.getElementById('div');
div.innerHTML = 'Width: ' + div.offsetWidth + '<br>Height: ' + div.offsetHeight;
.square {
width: 100px;
height: 100px;
background-color: blue;
}
<div id="div" class="square"></div>

Related

How do I make a parent container the same size as its child without knowing that size ahead of time?

I have a display ad container <div class="sponsor">...ad here...</div>
If the injected ad is 200x300 i want to make .sponsor 200x300. Is that possible with css or do I need some javascript.
In addition to my comment, you should check fit-content, max-content and min-content for the width value.
By default, width and height value are auto
For width, it will take all the space available,
For height, it will define the height needed to display the content without overflow.
In your case, i suggest leaving the height value as auto unless you need another behaviour.
To quickly explain *-content:
min-content : It will take the minimum space available for its element to be displayed. For example, with text, it will be set to the width of the wider word, and display the minimum word possible per line, in order to get the smallest width possible
max-content : It will take the minimum space available without having to wrap the content, for example, it will be set to the full line of text without new line. It will breakline if the height is higher than the parent.
fit-content : Mix of both, it will be max-content unless the space available is too small, then will switch to min-content
Depending on the child element, you can use different value, but i would suggest leaving height:auto;and set width:min-content; to begin with.
Like the others wrote, you can try this with CSS. If that doesn't help you, here is a JavaScript solution:
const ad = document.querySelector('#ad'); /* get the ad */
const container = ad.parentElement; /* get the div.sponsor */
/* get widht and height of the ad */
const ad_widht = ad.offsetWidth;
const ad_height = ad.offsetHeight;
/* set widht and height of the div.sponsor */
container.style.width = ad_widht + 'px';
container.style.height = ad_height + 'px';
Working example: (with a button and an event listener to show the effect)
document.querySelector('#shrink').addEventListener('click', function() {
const ad = document.querySelector('#ad');
const container = ad.parentElement;
const ad_widht = ad.offsetWidth;
const ad_height = ad.offsetHeight;
container.style.width = ad_widht + 'px';
container.style.height = ad_height + 'px';
});
.sponsor {
width: 400px;
height: 300px;
background-color: red;
}
#ad {
width: 300px;
height: 200px;
background-color: yellow;
}
<div class="sponsor">
<div id="ad">
<p>this is the ad</p>
<button id="shrink">shrink</button>
</div>
</div>
I know that display: table is not the best solution in these days, but using display: table on .sponsor class should do the trick.
.outer {
background: green;
}
.sponsor {
background: blue;
display: table;
}
.sponsor img {
display: block;
}
<div class="outer">
<div class="sponsor">
<img src="https://via.placeholder.com/200x300" />
</div>
</div>
You could inspect element and see that the .sponsor class has the same width and height as the image (200 x 300). Also try to change the image and check if the .sponsor class does indeed have the same size as the image.
EDIT: Another option is to use display: flex on the parent of that div, but this will be really situational, this really depends on how you want the sibling of the .sponsor class behaves:
.outer {
background: green;
display: flex;
}
.sponsor {
background: blue;
}
.sponsor img {
display: block;
}
<div class="outer">
<div class="sponsor">
<img src="https://via.placeholder.com/200x300" />
</div>
</div>

Change width of contenteditable div by chuncks based on text

I'm trying to change the width of a div based on the content of the div:
Lets say initially the div has a width of 100px, I want it to remain at that width until the user has filled up 90px with text.
When this arrive the width of the div should be incremented by a fixed value. if the user writes even more (190px) the div will again have its width incremented.
I tried using the clientWidth of the div like this:
get style(): string {
if (!this.el) {
return `
width: 100px;
line-height: ${DEFAULT_HEIGHT}px;
max-height: inherit;
`;
}
let divWidth = 100;
const maxWidth = window.innerWidth - SCROLLBAR_WIDTH;
while (this.el.clientWidth > divWidth * 0.9 && divWidth < maxWidth) {
const width = width + 100
if (width > maxWidth) {
break;
}
divWidth = width;
}
return `
width: ${divWidth}px;
line-height: ${DEFAULT_HEIGHT}px;
max-height: inherit;
`;
}
but it does compare the width of the div with itself and not the content of the div.
Thanks in advance,
You can relate to this answer to get the content width: https://stackoverflow.com/a/47224153/12933115
My recommendation is that you use two nested DIVs like this:
<div id="container">
<div id="content"></div>
</div>
<input id="txtBox" />
The div#container would have a fixed size, whereas the div#content wouldn't.
#container {
width: 100px;
}
#content {
max-width: fit-content;
max-width: -moz-fit-content; /* For Mozilla Firefox */
}
Now, you detect the typing instead of the width. Then, you check the width of the inner DIV within the event listener.
const input = document.getElementById("txtBox");
input.addEventListener("input", () => {
// Check the width of the inner DIV (#content) here...
// If the width of the inner width exceeds your limit, then you change the width
// of the container DIV (#container).
});
The above was a general explanation. You'll figure out how to apply this according to your needs.

How to increase height of textarea based font size

I have a textarea,where user will input some text,and also have a input range,where user can increase the font size of text,I want that the width of textarea still same,but height increase depend font size to show all text,and also I want textarea don't have a scroll and resize
I did that using div,and I want the same result using textarea
I did that using div https://jsfiddle.net/Meline222/fgpedL0z/1/
I want the same result but using textarea https://jsfiddle.net/Meline222/fgpedL0z/3/ bt when i use textarea all text can't see
I tried did but all text don't show textarea
this work for div
#inputText {
width: 150px;
height: auto;
border: 1px solid;
word-wrap: break-word;
overflow:hidden;
resize: none;
}
If you want only the height to be adjusted along font size, use em unit measure.
width: 150px;
height: 2em;
Documentation about the em unit says
em: 1em is the same as the font-size of the current element.
JSFiddle Demo: https://jsfiddle.net/craigiswayne/qkn8rdxp/20/
function adjustSize(i){
var o = document.getElementById('inputText');
o.setAttribute("style","height: auto;");
var val = i.value;
o.style.fontSize = val + 'px';
var fontSize = o.style.fontSize;
o.setAttribute("style","font-size: " + fontSize + "; height: " + o.scrollHeight + "px;");
}
#inputText {
width: 150px;
height: auto;
border: 1px solid;
word-wrap: break-word;
}
<textarea name="" id="inputText">kyb u uuhhhkjh kj</textarea>
<input id="input" type="range" min="12" max="72" oninput="adjustSize(this);">
So the solution I chose to set the height of the textarea to it's scrollHeight
scrollHeight is defined by MDN docs as
The scrollHeight value is equal to the minimum height the element would require in order to fit all the content in the viewport without using a vertical scrollbar
https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight
see also this post for an explanation of scrollHeight, clientHeight and offsetHeight
What is offsetHeight, clientHeight, scrollHeight?

How to resize a div to clients viewport height?

Ok, so i want to have a series of divs which are the exact width and height of the user's browser window, regardless of the screen size. I can easily make the divs stretch horizontally with "width: 100%;" but i cant work out how to make the height stretch itself. I am guessing that i need to use some bit of javascript to judge the height, and then another piece to resize the seperate divs. Unfortunately I am a complete javascript n00b and after two hours of seemingly fruitless searching and coming up with about 100 "solutions" this was as far as id gotten (Im sure that at some point I have probably been closer to the answer):
var viewportHeight = "height:" + document.documentElement.clientHeight;
getElementById('section-1').setAttribute('style', viewportHeight);
<div class="section" id="section-1"></div>
<div class="section" id="section-2"></div>
<div class="section" id="section-3"></div>
edit:
ah i should be more clear, im attempting to have all three divs take up the entire screen, so you have to scroll down to see each one - almost like seperate slides. The idea is that each one takes up the entire screen so you cant see the next section until you scroll down, rather than having three divs which take up a third of the screen.
If you haven't already tried it, you'll want to look at parent:child inheritance of elements within the DOM by way of using CSS.
What I want to STRESS is that everyone giving you JS hacks to accomplish this is not only providing you with overkill (YOU did ask for a JavaScript solution, so they gave it to you!), but it's also a deviation from standards. HTML is for structure, CSS is for presentation, and JavaScript is for behavioral aspects... setting a div to the width of the viewport on load is a PRESENTATION aspect and should be done in CSS... not JavaScript. If you were trying to change the width based on events or user interaction, then yes JavaScript is your friend... but stick with just HTML and CSS for now.
The trick is that most elements have an undefined height - and height is later defined by the content that the element holds.
If you want to 'trick' an element into having a height other than what it wants to default to, you'll have to explicitly define it. Since you want to inherit your height from the viewport, you'll have to define the height at the top and bring it down...
You might be in luck and can avoid JavaScript altogether (unnecessary). Just use CSS.
Try something like:
html, body {
height: 100%;
width: 100%;
}
Now, when you try to set your div's later on, specify width: 100% and the height gets inherited from the html --> body --> div.
Try that and see if that solves your problem - if not, point us to a website, a pastebin, or a SOMETHING with code in it that we can just show you how to do it (whereas what you posted for code was an attempt in JavaScript which is only 1 part of the code - post the full thing either to a server or temp site like pastebin).
Here is some sample code I wrote (tested in Chromium):
The HTML:
<html>
<head>
<title>Test Divs at 100%</title>
<link rel="stylesheet" type="text/css" href="divtest.css"
</head>
<body>
<div class="test1">aef</div>
<div class="test2">aef</div>
<div class="test3">aef</div>
</body>
</html>
The CSS:
html, body {
width: 100%;
height: 100%;
background-color: #793434;
padding: 0;
margin: 0;
}
div {
height: 100%;
width: 100%;
}
.test1 {
background-color: #E3C42E;
}
.test2 {
background-color: #B42626;
}
.test3 {
background-color: #19D443
}
try this
div#welcome {
height: 100vh;
background: black;
color: white;
}
div#projects {
height: 100vh;
background: yellow;
}
<div id="welcome">
your content on screen 1
</div>
<div id="projects">
your content on screen 2
</div>
it should work for you, but little support in IE
A bit of jQuery should do it:
$(document).ready(function() {
var window_height = $(window).height();
$('#section-1").height(window_height);
});
And if you want to keep 100% height on window resize:
$(document).ready(function() {
function viewport_height() {
var window_height = $(window).height();
$('#section-1").height(window_height);
}
viewport_height();
$(window).resize(function() {
viewport_height();
});
});
try this
window.onload = init;
function init()
{
var viewportHeight = "height:" + document.documentElement.clientHeight+"px;";
document.getElementById('section-1').setAttribute('style', viewportHeight);
}
Here is a script free solution, just CSS. This assumes that the divs are directly in the body element or a parent with position absolute and the parent has no padding.
#section-1 {
position: absolute;
height: 100%;
width: 100%;
background: #ff0000;
}
#section-2 {
position: absolute;
width: 100%;
top: 100%;
height: 100%;
background: #00ff00;
}
#section-3 {
position: absolute;
width: 100%;
top: 200%;
height: 100%;
background: #0000ff;
}
See fiddle: http://jsfiddle.net/QtvU5/1/

Centering a label

I have a div with some text inside and absolute position. I can set the left or the right, but is there a way to set the center, so Div's text would expand in both directions.
So far I could only think about creating exstremly long div and centering text inside.
If your div is positioned absolutely, you can simply set it's left property so that it's centered.
Example:
HTML:
<div class="outer">
<div class="inner">Some text...</div>
</div>
CSS:
.outer {
position: relative;
width: 900px;
}
.inner {
position: absolute;
width: 500px;
top: 0;
left: 200px;
}
If you don't know the width of the inner element, you'll have to rely on javascript.
Here's an example using jQuery:
var $el = $('.inner');
$el.css('left',
( $el.parent().width() - $el.width() ) / 2
);
and here's the fiddle: http://jsfiddle.net/aa93G/ . Play around with the text inside .inner, and you'll see that the text stays centered.
to centralize inner text and inline elements use text-align: center in the parent element.
If you're dealing with block elements, you should use margin: auto in the element itself. but you must first set a width for the element, otherwise it will just occupy the whole width of the parent.

Categories