Truncate/increase font size within a div so it fits - javascript

Suppose I have a div of size 100px x 20px and text within it set randomly with different lengths i.e. some text sections are long and some are short.
So, when the amount of text is less, then there is blank space within the div. And if there is large amount of text, it overflows.
My objectives
If text is less than the div capacity, then the font-size of that text will maximize to fit within that div as much as possible without clipping/ cutting.
But if text size is larger than the div capacity then I want to truncate text and append ... (3 dots only).

For the first part, I'd suggest to wrap the text in a <span> so you can get its offsetWidth, then you can set its font-size style property to 200 / span.offsetWidth.
Keep in mind, though, that this is a rough calculations with some approximations being made, and maybe you want to do better using 190 or 195 instead of 200.
For the second part, just set overflow: hidden; text-overflow: ellipsis; white-space: nowrap;.
Keep in mind that the ellipsis dots don't appear in older Firefox clients.

I think you will need another (inner) <div> in order to be able to check the height of the text.
<div id="mainDiv">
<div class="inner">
<p>Some text</p>
</div>
</div>
//css
#mainDiv
{
width: 200px;
height: 50px;
overflow: hidden;
}
Then you will need some simple functions (something like this):
//pseudocode
function doCheck()
{
if (".inner".height > "#mainDiv".height) truncate()
else increaseSize()
}
function truncate()
{
for (i = 1; i <= ".inner".wordCount)
while (".inner".height <= "#mainDiv".height)
{
addOneMoreWord() + " …";
if (".inner".height > "#mainDiv".height) removeLastWord()
}
}
//similar thing for increaseSize();

Related

How to check if 2 elements displayed on the same row?

Assuming I have 2 elements on a responsive design like this:
<div id="container">
<div class="first"></div>
<div class="second"></div>
</div>
both of them with style contains:
width: auto;
display: inline-block;
float: left;
And because I'm expecting different screen sizes to view page, so, according to screen size, sometimes they will be rendered/displayed on the same row, and sometimes they will not!, the second DIV will be moved to a separate row.
So, I'm wondering, how can I check if they are on the same line with JavaScript?
Thank you
"on the same line" would require inline elements or floating block elements of the exact same height. DIVs are block elements by default. So either use <span> tags instead of <div>, or add display: inline-block;to the CSS rule of those DIVs
ADDITION after EDIT OF QUESTION:
width: auto for a <div> means 100% of the parent element (in this case full width). As I wrote: If you have blocks, use display: inline-block; in their CSS. If you want them to have the same height, put them into a common container DIV (which you already have) and apply the following CSS:
#container {
display: table;
}
.first, .second {
display: table-cell;
width: 50%;
}
Aha (edited question), Javascript: Well, read out the DIV widths, add them and compare the result to the (read-out) container width.
You can use the element bounding boxes and check for overlap:
var rect1 = $('.first')[0].getBoundingClientRect();
var rect2 = $('.second')[0].getBoundingClientRect();
var overlaps = rect1.top <= rect2.bottom && rect2.top <= rect1.bottom;
This checks for any overlap which will probably be sufficient for your use. I used jQuery to get the elements but you can use pure js in the same way, it would just be a bit more verbose.
There is no concept of line on a page. You can check the x and y position of any element in the window and then decide if that meets whatever criteria you have for "on the same line".
By default, a div is the full width of a window so the two divs inside your container in this HTML:
<div id="container">
<div class="first"></div>
<div class="second"></div>
</div>
will be one above the other unless there is some other CSS you have not disclosed that controls the layout to allow them to be in the same row. If they are indeed width: auto and don't have any other layout rules affecting this, then they will each be full width and thus first will be above second in the layout stream. They would never be "on the same line" by any typical definition of that phrase.
Feel free to try it out here: https://jsfiddle.net/jfriend00/y0k7hLr8/ by resizing the right pane to any width you want. In all cases, the first will stay on top of the second.
If, on the other hand, you allow the div elements to have a different type of layout such as let them be display: inline-block and define a width for them, then the layout engine will fit as many on a given row as possible like here: https://jsfiddle.net/jfriend00/229rs97p/
Something tells me display: flex might help you in this. Read https://css-tricks.com/snippets/css/a-guide-to-flexbox/ for more info.

Place dynamic DIVs in columns without vertical gaps between them?

Got a series of quotes of varying length to fit in DIVs of fixed width but content determined height. I could individually position each DIV so it looked tidy and there were no vertical gaps. For example - http://www.zergnet.com/. I wondered if there was a CSS solution to problem, as I noted Zergnet uses inline styling and absolute positioning of every news teaser (which makes me think javascript is involved somewhere).
.testimonialBubble {
position: relative;
width:48%;
margin: 8px 0;
padding:0 2% 0 0;
float: left;
}
The idea being no matter what volume of content is thrown (within reason) into the divs in the 2 col layout they'll fit together and fill spaces. At the moment if the 2nd element is longer than the 1st, when 3rd element kicks round under the 1st element there's a gap between the two caused by the 2nd elements height. Is there a CSS only solution or is it only achievable via javascript?
Many thanks for reading.

Javascript height to impact content not just div

I am working on a form on a webpage. I want to have a button on a panel which when pressed expands a div (underneath the button) to make it visible and then invisible again when the button is pressed again - a kind of further details popout box. So far i have got this:
function blockappear() {
var ourblock = document.getElementById("theblock");
ourblock.style.transition = "all 2s";
if (ourblock.style.height == "0px") {
ourblock.style.height = "220px";
} else {
ourblock.style.height = "0px";
}
}
and this:
#theblock {
background-color: #a83455;
height: 220px;
width: 100%;
padding: 0;
margin: 0;
display: block;
}
and this:
<p><button type="button" onclick="blockappear()">Try it</button></p>
<div id="theblock">
Some text
</div>
And it seems to work which is quite pleasing (even though it has taken hours to get this far). The problem is this. I want the div to change from 200px to 0px including the contents not just to the extent it can according to the contents. At the moment the div shrinks, but the content "some text" stays put on the page. I have tried changing the display attribute of the div to 'block' and 'table' and still no joy. I thought that the point of a div was that it enclosed the content with the group tags and that the content could not exist without the div. If the div has 0px height how can the text still show?
Incidentally, if i just use display:none; on the div it works (without the transition of course). I need the content of the div to respond to the height of the div somehow - i suspect using the css properly.
I think this has been covered before by using jquery, but i want to use javascript now that i have started as it will probably take me another few hours if i start again with a whole new language :-)
Thanks for any help...
Add overflow: hidden; to your div. This will hide the content which doesn't fit into the container.
You want to use this CSS property on your div:
overflow: hidden;
This will make any content of #theblock bigger than #theblock itself invisible. So - if #theblock has height of 0px - all of its contents will be hidden.
Default value is overflow: visible;, so even content bigger than containing element itself will still be there for all to see. That's all there is to it.
Read more: overflow CSS property (MDN)

HTML / CSS inline textarea set width to same as input

I'm not sure if this is possible by CSS alone, but I'm attempting to create an inline textarea element where the text is selectable but still looks like part of a sentence. It looks fine when the number of characters are known (cols="11") by:
<p>To run nload for your device run <textarea readonly cols="11">nload p3p1</textarea> in your terminal.</p>
and the CSS:
textarea {
display: inline;
border:none;
resize: none;
}
Is there a way of doing this dynamically, without specifying the columns for each textarea in CSS? So each textarea is inline and looks unobtrusively part of a normal paragraph but selectable? Failing a CSS solution, is there a (pure) JavaScript one?
You will need to render the input text and calculate the width of the input submitted text based on that render.
A possible sollution is to copy the text into a hidden span and check it's width as illustrated:
jQuery('input').on('input', function()
{
var $this = jQuery(this);
// Create a widthSpan if we haven't already.
document.$widthSpan = document.$widthSpan || jQuery('<span style="display: none" />').appendTo(document.body);
document.$widthSpan.text($this.val());
$this.css('width', document.$widthSpan.width() + 5);
}).trigger('input');
A working fiddle: http://jsfiddle.net/687uew37/.
Do note this is an example which updates as soon as the input's content is changed. Depending on the implementation and usage if this you might need to implement changes accordingly.
You can use JavaScript to dynamically set the width of your textarea depending on the number of characters inside your textarea.
HTML:
<p>To run load for your device run <textarea class="tx" readonly>nload p3p1</textarea> in your terminal.</p>
<p>Here is another example which follows the same pattern <textarea class="tx" readonly>your textarea query you can add lots of text. </textarea>You can add a lot of other stuff after it and it will still look like part of your text.</p>
CSS:
p{
line-height:1.5em;
font-size:14px;
}
textarea {
margin-bottom:-0.3em;
border:none;
overflow:hidden;
height:14px;
display:inline;
white-space: nowrap;
}
Jquery:
$(document).ready(function(){
$('textarea').each(function(){
//Width of a character:
var chars = 8;
//Find out how many characters are in the text area:
var txLength = $(this).val().length;
//Calculate the width:
var txWidth = chars * txLength;
//Set the width:
$(this).css({'width':txWidth,'resize':'none'});
});
});
You start by taking each textarea one at the time. The idea is that you already have a font-family predefined and you know the average width of the characters in your font-family. You can find your font-family average character width online or you can estimate if you don't know it (I took a guess here).
In this case the variable chars holds the average width value of the character. You then compute the desired textarea width by multiplying the number of characters with the average character width and insert that in your CSS using jQuery's .css() function.
Working fiddle here: http://jsfiddle.net/ys2Lfrt8/5/
Drawbacks: Not responsive but can be fixed using #media-queries

CSS - how to force text input fill remaining space of container

I have div and inside that div are floated child divs and one text input. I need force that text input to fill remaning horizontal space and stay on same line unless some min-width condition places that input to next line. Is it possible? I don't wanna use javascript for that.
here is example (write tag and hit enter)
EDIT EXAMPLE: I have div with 300px width. It contains 3 left floated divs with various width (for instance 30, 60, 100) and one text input. I want to have that text input on same vertical position like that floated divs, so it must automatically shrink to fit remaining space (300-(30+60+100) = 110px). That text input has some min-width, so it prevents it from getting to small and in that case it jumps to next line).
http://plnkr.co/edit/sulxnvR58LnQqyI7ddFK?p=preview
You could try adding something like this:
style="width: 100%; min-width=2000px;"
http://plnkr.co/edit/uuL91pnUBkBRHMziaGBs?p=preview
Can't you just use percentage width for the input and overflow hidden?
Add this CSS
div.tag-wrapper input[type=text] {
width: 100%;
}
div.tag-wrapper {
padding: 5%;
overflow: hidden;
}

Categories