How to resize font size if element overflows vertically? - html

On our cover page we want to display a title on a big font but if the title is too long it overflows and isn't displayed properly.
I came up with this js solution to resize the font when it overflows:
/** Checks if an element overflows. **/
let isOverflown = e => e.offsetWidth < e.scrollWidth || e.offsetHeight < e.scrollHeight;
/** Resizes an element's font size until it no longer overflows. **/
let resizeFont = $e => {
let fontSize = parseInt($e.css('font-size'));
const parent = $e.parent()[0];
while (fontSize > 0 && isOverflown(parent)) $e.css('font-size', --fontSize + 'px');
}
resizeFont($('.title'));
And it does work for horizontal overflow, like in this case when you have a very long single word with no whitespaces. Just tweak the max width in the .container and you'll see the resize function at work.
However the same is not true for vertical overflow. Why isn't the overflow check function evaluating this case as no overflow when it obviously is overflowing?
edit: if I add $e.css({'height': '100%'}); after the resizing function is run it does work but for some obscure reason the text is no longer aligned to the bottom on mobile. I tried using flexbox with align-items: end on the parent but then that messes up the resize function. Plus, mobile seems to ignore the flex alignment rule.

Inspect element shows the font-size changing and the height and width are constant for .title. Please recheck.

I fixed it by adding height: 100%; width: 100%; to .title and then using flexbox after the font resizing is finished in order to align the text to the bottom:
$e.css({'display': 'flex', 'align-items': 'flex-end'});

Related

CSS - make font be as large as possible to fill container

I have a grid that filled screen and each it's cell contain some text as labels. What should I write in CSS to resize this text to fill container without overflow? Keep in mind it may be restricted by height or by width.
Now it is just
label {
display: flex;
justify-content: center;
align-items: center;
font-size: 150pt; /*must be adaptive*/
}
Jsfiddles: grid 3x3, grid 1x10
Or if there is no ideas...
At the moment I have two formulas as alternate variant that can calculate desired font-size relative to height (first) and width (second). I would use min() of them if it was supported. So if there is no elegant solution on CSS, the other question: will it be effectively to define CSS variable and set to it min of formulas with js in window.onresize?
I'm pretty sure there's no "pure css" way to accomplish this.
I wrote a js script that checks the container for overflow/scroll-height. Either you start at something small, say 1px font size, and continually increase it until the container has overflow, then shrink it back down 1 notch.
Alternatively, have a really large font size, say 200px (or whatever your MAX is). And do the reverse until there's no longer overflow/scrolling on the container.
You could optimize this by jumping "half way" each time, instead of 1px at a time. So...
200px ? scrollHeight > height || scrollWidth > width : true
100px ? scrollHeight > height || scrollWidth > width : false
150px ? scrollHeight > height || scrollWidth > width : true
125px ? scrollHeight > height || scrollWidth > width : true
... etc etc.
A couple other points:
Check scrollHeight AND scrollWidth (a long word that doesn't wrap)
hide the container while it's calculating to prevent flicker
test, test test, lots of potential issues with this, but I've found it works quite well
There's probably a library, just use that if you're lazy ;)
Try this. It would scale the fonts to each container
label {
display: flex;
justify-content: center;
align-items: center;
font-size: 150pt;
font-size: 9vw;
}

Issue with container div not resizing as the page size changes

I am working on an issue in which my container element is not resizing as the page changes size, which would lead to issues displaying the page on smaller screens (e.g. content is hidden, and the user cannot scroll down far enough to see it). I gave the offending container (section.padder-content.scrollable) a smaller than usual height, so it is easier to see. Here is an image demonstrating the issue:
The issue
On the left is the screen before resizing, and on the right is after resizing-- here, the user can no longer see the "Create" button, and cannot scroll down any further to see it. I wanted to try and post images of the source code of the three elements I think are contributing to the issue, but I don't have enough reputation at the moment. But basically the offending container has:
position: absolute;
height: 600px;
overflow-y: auto;
Its parent has:
display: table-cell;
vertical-align: top;
float: none;
position: relative;
border-spacing: 0;
And the parent's parent:
height: 100%;
overflow-y: auto;
min-height: 90%;
max-height: 90%;
margin-bottom: 10px;
display: table;
table-layout: fixed;
border-spacing: 0;
width: 100%;
I tried experimenting with the positioning of the table-cells, changing the display to literally everything else, and nothing can quite get it to work. I am thinking it might have something to do with the mix of pixel heights and percentages, but when I experiment with those, I seem to make it worse. This isn't my code, and there are three separate css files being used: site.css, bootstrap.css, and app.css (Scale from ThemeForest). There's a lot of interaction potentially going on here that I don't quite understand, so any help would be appreciated. As a side-note: I am using IE11 at the moment, because although I found a hacky fix for Chrome/FF, it completely ruins the display in IE.
Please let me know if there are any more details I should provide.
So I fixed the issue. There were a couple of competing issues. The critical issue was that the template I used (Scale from ThemeForest) had javascript code (app.js) that didn't quite work properly in IE11. The offending code:
// fix vbox
var fixVbox = function(){
$('.ie11 .vbox').each(function(){
$(this).height($(this).parent().height());
});
return true;
}
fixVbox();
The 'vbox' would resize correctly if you increased the window size, but not if you decreased the window size, which is often what I was doing when trying to see how the site would work on mobile. There were elements that got their heights calculated based on their parents, and those parent elements calculated their heights from their child elements... so when the window size was decreased, and the fixVbox() function did not correctly calculate the new height, it caused issues with all of the elements.
In all, a very specific and difficult bug to track down-- a problem with the template itself that I was using.
My solution (for anyone else using this same template):
In app.js:
// unmobile
$window.width() < 768 && mobile();
// resize
var $resize;
$window.resize(function() {
clearTimeout($resize);
$resize = setTimeout(function(){
setHeight();
$window.width() < 767 && mobile();
$window.width() >= 768 && mobile('reset') && fixVbox();
}, 500);
});
to:
$window.width() >= 768 && mobile('reset'); // && fixVbox();
and:
// fix vbox
var fixVbox = function(){
$('.ie11 .vbox').each(function(){
$(this).height($(this).parent().height());
});
return true;
}
fixVbox();
to:
//fixVbox();
Once the parent/child elements started resizing correctly, it was just a matter of fixing my css to account for the changes (e.g. I had to push my container window down 103px because that was the height of my navbar at the top, etc.)

Make div width max of two values?

Consider the basic HTML below:
<body>
Random HTML content
<div class="container">
<!--Some content loaded via ajax or the like -->
</div>
Other random HTML content
</body>
I want the width of the "container" div to be the MAXIMUM of three potential values:
100% of the window
1024px (for best visual appearance)
the width of the content
I have been able to accomplish #1 and #2 by using the CSS properties width:100% and min-width:1024px. I can also accomplish #2 and #3 by setting display:inline-block and min-width:1024px. However, I haven't been able to get all three: if I add in the width:100% to the display and min-width properties, it overrides the child content sizing effect of the inline-block display and gives me only 100% width, even when that means the content overflows.
I know I can hide overflow or give the div itself scrollbars, but what I want is for the div to expand as needed, or to the full width of the window, whichever is greater - but never narrower than 1024px.
Edit: Note that the content loaded in the div may be less than 1024px. The div itself, however, should never be less than that, as it would no longer blend nicely with the look and feel of the rest of the page.
You can achieve this by adding another div on top of first one:
<div class="container2">
<div class="container">
</div>
</div>
css:
.container2{min-width:100%; display:inline-block;}
.container{min-width:1024px; width:100%;}
http://jsfiddle.net/om10t3gn/4/
You can augment your second proposal with a virtual pseudo-element to achieve the dimensions you want without using javascript
.container {
min-width: 1024px;
display: inline-block;
}
.container::before {
width: 100vw;
display: block;
content: ' ';
}
Basically, it's adding a zero-height element to the top of your container that has the same width as your viewport, which is 100% of the width of <body>. So it adds #1 to your existing solution that already achieves #2 and #3.
And it doesn't use any javascript, and will stay correct with resizes.
I am not very skilled with CSS, but I think I have a solution for this problem.
To have a max-width in pixels and a max-with in percent at the same time, you could first calculate the width with the clamp-method (this includes the first of your two max-widths) and then add a normal max-width. The clamp-method is relatively new and not supported by old browsers unfortunately.
<div class='container'></div>
CSS:
.container{
width:clamp(400px,250px + 25vw,100%);
max-width:700px;
}
This should set a max-width both at 100% and 700px.
I have tested it on a notebook with Firefox and Chrome.
Use javascript to pick the largest value, use jQuery to assign that value to the width of the container div.
var window_width = $(window).width();
var container_width = $('.container').width();
var default_width = 1024px;
var max_width = Math.max(window_width, container_width, default_widht);
$('.container').css('width', max_width);

align fixed width child-elements centrally in unknown-width parent-container

Hi HTML/CSS Developers !
Stuck in a strange scenario
will try to explain my query through images.
Need it to work in IE 8 or 9 atleast.
Points:
its an approach for a responsive layout,
.container {width:100%;margin-left:auto;margin-right:auto;display:block;}
.parent-container {width:auto;overflow:hidden;margin:0 auto;display:block}
.child-element {width: 285px;float:left
}
Hierarchy
.container > .parent-container > .child-element
Labels:
I have a 100% container
inside it, I have a parent-container {no width-declared (red background color)}
inside that i have child-elements with a fixed width.
What I want that, no matter, what my screen size is, if there is space for 3 child or 4-child elements, my parent element should always be in center.
width of child elements should contribute to parent-elements width
This is what i have
This is what i am getting
This is what i want it to be (see the parent-width is reduced depending upon child-element)
FIDDLE
http://jsfiddle.net/happy2deepak/9wm7ppwL/2/
You need some javascript to update the parent container's width according to the window width, you can do it by dividing window width by child width (padding and margin included) and take the maximum possible children which is the floor of the division result
function setContainerWidth(){
var childWidth = 305,
winWidth = $(window).width(),
parentContainer = $('body').find('.parent-container'),
minChildren,
containerCalculatedWidth;
minChildren = Math.floor(winWidth / childWidth);
parentContainer.css("width", minChildren * childWidth);
}
setContainerWidth();
$(window).resize(setContainerWidth);
a fiddle to see how it works.

Data gets hidden while changing the browser height

I have a strange problem, my data gets hidden when I change the height of my browser.
It also disappears in mobile browsers sizes... here is a screenshot:
I am following this tutorial
Here is the page with the issue.
From what I can tell your slide DIVs have height: 100%; as well as your html and body tags. html will inherit it's height from the view-port size. Your content is larger than the view-port as you change the vertical height. Content gets hidden under the elements that come after it. If you remove the background color from all your slides you will begin to see your content overlapping.
What you need to do is remove height: 100%; from your slides. This will cause your slider DIVs to contain/show your content as they will expand to fit the height they actually take up and will prevent element stacking.
What you need is to either have the slide be the view-port size or the content size, which ever is larger. Since you are using jQuery already you could try something like this:
http://jsfiddle.net/z6xrf/
function slideHeights() {
var viewportHeight = $(window).height();
$('.slide').each(function(){
var elem = $(this);
// reset so we can get the correct height of element each time
elem.css('height','auto');
var slideHeight = elem.height(); // height of content in slide
if ( viewportHeight > slideHeight ) {
height = viewportHeight;
} else {
height = slideHeight;
}
elem.css('height', height);
});
}
$(document).ready(function(){
slideHeights(); // for page load
$(window).resize(slideHeights); // for window resize
});
What we did above is create a function that monitors the current size of the view-port and compares it to the height of the slide (total height of slide's content). If the view-port height is larger than content height we use that, otherwise we use the content height for the slide. In the process we reset the min-height value so it is not reading a value we previously set.
We initially fire the function on page load simply by calling it. Then we pass it to the resize function so it gets called when appropriate. See http://api.jquery.com/resize/ for how browser apply the resize event.
It is a problem of height of-course.
Do one thing, set a minimum height of each slide, approx 800 or 900 px. And then test, it will surely work.
.slide {
background-attachment: fixed;
height: 100%;
min-height: 800px; /*set any height here*/
position: relative;
width: 100%;
}