Using CSS "padding-trick" for proportional resizing on Y-axis? - html

I'm building an web app which has a 100% height/width/fullscreen layout. I am looking for a CSS-trick to proportionally resize an elements dimensions according to its height.
Right now I am looking for an equivalent of what this trick does to the x-axis:
html, body{
height:100%;
margin:0;
}
#view {
min-height: 100%;
position: relative;
width: 100%;
background-color: #333333;
}
#test-hld {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
background-color: tomato;
width: 100%;
height: 75%;
}
.test{
position: relative;
width: 30%;
}
.test:before{
content: "";
display: block;
padding-top: 75%;
}
.content{
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: black;
}
<div id="view">
<div id="test-hld">
<div class="test">
<div class="content"></div>
</div>
</div>
</div>
But changing (for example) .test{height: 80%} and .test:before{padding-left: 75%} makes the browser render no dimensions of the box at all.
My question(s) is
Why is the opposite not working?
Has it something fundamental to do with setting heights of elements with CSS?
Can flex/flexbox solve this?
I know it's possible to fix this with some lines of JS but I just can't believe it's not doable with CSS until someone slaps my face telling me to get real.

First of all, just to know why the padding trick works.
Padding-top and padding-bottom are vertical dimensions that are related to the width (so, an horizontal dimension) of the container.
That allows the ratio of an element to be fixed, and related to the width of the container. But there isn't any horizontal dimension that is related to some vertical of the container, so the equivalent trick over the height is not posible right now.
I have tried to get this same result using another technique, but I have had a very partial success.
My failed attempt is try to use an image to set the ratio
body, html {
height: 99%;
}
.base {
height: 40%;
border: solid 1px green;
display: inline-block;
position: relative;
}
.ratio {
content: url("http://placehold.it/400x200");
opacity: 0.05;
height: 100%;
width: auto;
position: relative;
}
<div class="base">
<img class="ratio" />
</div>
This is working in IE and Chrome, and failing in FF. But just on initial loading.
Changing the browser size won't work until the page is reloaded. I just can't figure out why, or how to solve it

Related

Setting an inline element's percentage css height, relative to it's flexible parent. (Only problems with chrome)

Problem:
I'm trying to make a scalable view for images in a lightbox. I've got a way to make it look good on every size of screen. But, only Google Chrome's behavior to this method is different from the other browsers.
HTML:
<div class="parent">
<span class="helper"></span>
<img src="">
</div>
CSS:
I create a helper element, setting it's display to inline-block and change the vertical-align to middle for both span and img. This makes sure the image will be placed in the middle of it's parent.
To make sure the height and width of the image won't be any bigger than it's parent, I set it both to 90%. (not 100% 'cause I want some padding as well).
So my CSS looks like this:
.parent{
position: absolute;
top: 0;
right: 0;
bottom: 100px;
left: 0;
background-color: #ccc;
text-align: center;
}
.helper{
display: inline-block;
vertical-align: middle;
height: 100%;
}
img{
vertical-align: middle;
max-width: 90%;
max-height: 90%;
}
Fiddle
In this fiddle you can see that it work's in all browsers except for Google Chrome. Chrome ignores the maximum height that's set. Which will allow the image to be bigger than it's parent, not good..
Is there a work-around for this problem?
check this out with pure css , no js/jquery. just you need to wrap your content in div and give height 100% to it, as when you say max-height: 80% it takes 80% of it's parent which was not there.
.parent{
position: absolute;
top: 0;
right: 0;
bottom: 100px;
left: 0;
background-color: #ccc;
text-align: center;
}
.helper{
display: inline-block;
vertical-align: middle;
height: 100%;
}
img{
vertical-align: middle;
max-width: 90%;
max-height: 80%;
}
<div id = "parentDiv" class="parent">
<div style="height: 100%;">
<span class="helper"></span>
<img id = "imgId" src="http://3d-diva.davidmichaeldesigns.com/images/tree-01.png"/>
</div>
</div>
Hope this is what you are looking for :)
you can pass height to image tag dynamically with respect to parents div through javascript.
function setImgHt(){
var imgHeight = document.getElementById('parentDiv').clientHeight;
document.getElementById('imgId').setAttribute("style","height:"+imgHeight+"px");
}
.parent{
position: absolute;
top: 0;
right: 0;
bottom: 100px;
left: 0;
background-color: #ccc;
text-align: center;
}
.helper{
display: inline-block;
vertical-align: middle;
height: 100%;
}
img{
vertical-align: middle;
max-width: 90%;
max-height: 80%;
}
<body onload="setImgHt()">
<div id = "parentDiv" class="parent">
<span class="helper"></span>
<img id = "imgId" src="http://3d-diva.davidmichaeldesigns.com/images/tree-01.png"/>
</div>
</body>
it can be done through jquery as well on document ready call the function which is being called onLoad now.

Inline-block conainting image with height 100% collapsing in FireFox

I have a problem with CSS that's only visible in FireFox (cur.ver. 31).
I am trying to make a responsive layout, with a row of images (with links), that are centered, and having the same height and scale with the viewport width. My approach is to create a container with a fixed aspect ratio, and place the images inside (each image inside a separate <a> tag), center them, and scale their heights to the container height. It's working great, except in FireFox.
To achieve this I applied a display: inline-block; height: 100% to <a> tag and height: 100%; width: auto to <img> tags. For some (unknown) reason FF is not calculating the width of the <a> tag correctly (when it contains described above <img> tag) and it collapses horizontally. The result is, that all <a> with 0 width are placed very close to each other (separated only by white spaces), and the images overlap each other. I get the same result with display: block; float: left; on <a> tags.
The CSS
.container-ratio {
width: 100%;
height: 0;
position: relative;
padding-bottom: 10%;
background: #ddd;
}
.container-inner {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: #ddf;
text-align: center;
}
.block {
display: inline-block;
height: 100%;
background: #f00;
}
.block img {
height: 100%;
width: auto;
display: block;
}
The HTML
<div class="container-ratio">
<div class="container-inner">
<a class="block">
<img src="http://placehold.it/100x80/42bdc2/FFFFFF&text=No1">
</a>
<a class="block">
<img src="http://placehold.it/150x80/242bdc/FFFFFF&text=No2">
</a>
<a class="block">
<img src="http://placehold.it/200x80/c242bd/FFFFFF&text=No3">
</a>
</div>
</div>
I think this is what your trying to do. Demo
You had no width on .block and auto on .block img.
It needs to be percentages.
.container-ratio {
width: 100%;
height: 0;
position: relative;
padding-bottom: 10%;
background: #ddd;
}
.container-inner {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: #ddf;
text-align: center;
}
.block {
display: inline-block;
width:20%;
height: 100%;
background: #f00;
}
.block img {
height: 100%;
width:100%;
display: block;
}
It's been nearly two years since this question was asked, and Firefox still exhibits this behavior.
So, for anyone in the same situation, here's a solution (only tested on Chrome 49.0 and Firefox 45.0.1).
Edit:
Originally, I used inline wrapper divs and two instances of the images, one of which was not displayed and only served as a dummy. It appears this is not necessary, as can be seen here.
All in all, it seems you can't use inline-block that way in Firefox, but all you need to do to get what you want is leave the anchors and images as inline elements. As long as the anchor's parent is a block-level element other than inline-block, and its height is specified, then you'll get the intended result.
If, for some reason, inline-block is really needed, I don't see how to work around this problem.
Note:
Beware of the "font-size: 0;" on the .block class, used to remove spaces between the images. Without this, images are seperated by whitespaces that behave like links. If the images need some space between them, adding some right or left margin as in the fiddle would be a solution.
Also, though the .block class name is no longer appropriate, I left it to stay consistent with the OP.
The modified CSS
.container-ratio {
width: 100%;
height: 0;
position: relative;
padding-bottom: 10%;
background: #ddd;
}
.container-inner {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: #ddf;
text-align: center;
}
.block {
font-size: 0;
}
.block img {
height: 100%;
margin-right: 1%;
}

How can I make this 100% height + column overflow layout work in Firefox and IE?

I have a three-column layout that takes up 100% width and height of the browser (with padding). This layout contains two columns which also take up 100% height and should scroll independently.
Here is a jsfiddle: http://jsfiddle.net/KdZ9A/2/. Here is how it looks in Chrome (desirable -- individual columns scroll):
and Firefox and IE (undesirable -- body is scrolling):
This works perfectly in Chrome; however, the in Firefox and IE (10), the entire page scrolls instead of individual columns scrolling. I only want the columns to overflow and scroll -- not the body. Any idea how to make this work in Firefox and IE?
I've also tried a bit different approach using absolute positioning of the columns' contents: http://jsfiddle.net/KdZ9A/3/.
Here is the HTML I am using:
<div id="container">
<div id="inner">
<div id="palette">palette</div>
<div id="list">
<div class="content"></div>
</div>
<div id="editor">
<div class="content"></div>
</div>
</div>
</div>
I'm using absolute positioning to achieve 100% height and then display of table and table-cell inside that to achieve 100% height of the columnns:
* {
padding: 0;
margin: 0;
}
html, body {
width: 100%;
height: 100%;
}
body {
position: relative;
}
#container {
background-color: #f1f1f1;
position: absolute;
left: 20px;
right: 20px;
top: 20px;
bottom: 20px;
}
#inner {
display: table;
height: 100%;
}
#inner > div {
display: table-cell;
}
#palette {
min-width: 180px;
max-width: 180px;
width: 180px !important;
background-color: pink;
}
#list {
width: 55%;
min-width: 350px;
background-color: cyan;
}
#editor {
width: 45%;
min-width: 400px;
background-color: magenta;
}
.content {
overflow: auto;
height: 100%;
}
I was 5 minutes from giving up and HOLY CRAP...I GOT IT WORKING
http://jsfiddle.net/gFX5E/15/
This is based on the different approach I mentioned. I needed to wrap .content divs and make the wrappers position relative. I also added some headers to the columns.
HTML:
<div class="content-wrap">
<div class="content">
...
</div>
</div>
CSS:
.content-wrap {
position: relative;
height: 100%;
}
.content {
overflow: auto;
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
}
Seems to work in Chrome, Safari, Firefox, and IE8+.
And here is a more semantic HTML5 version which also adds a header to the top: http://jsfiddle.net/gFX5E/20/. I believe this will require use of html5shiv to work in IE8.
If you are willing to settle for a fixed total width, here is how:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box; /* makes filling up easier */
}
html, body {
height: 100%;
}
#container {
position: relative;
width: 980px;
height: 100%;
margin: auto;
background: grey;
}
#palette {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 800px;
background: pink;
}
#list {
position: absolute;
left: 180px;
top: 0;
bottom: 0;
right: 450px;
background: cyan;
overflow-y: auto;
}
#editor {
position: absolute;
left: 530px;
top: 0;
bottom: 0;
right: 0;
background: magenta;
overflow-y: auto;
}
</style>
</head>
<body>
<div id="container">
<div id="palette">Palette</div>
<div id="list" class="content"></div>
<div id="editor" class="content"></div>
</div>
<script>
$(function() {
for (var i=0; i<20; i++) {
$('.content').append('<p>Lorem ipsum [truncated for SO]</p>');
}
});
</script>
</body>
</html>
Demo on this Codepen: http://codepen.io/anon/pen/aqgCm?editors=100.
This is a pretty old post, but I thought I'd comment.
If you display: flex instead of display: table in your 1st example that should fix the issue.
Also setting your scroll container height to 100vh will also do the trick.
You have to understand that the browsers apply scroll only when they understand the size( i.e. height and width) of the content is greater than the size specified for it. In your case, the height you have specified for the div is 100%. This effectively tells the browser to keep increasing the size of the div till all the content fits in completely. Hence, this creates the situation where scroll isn't needed as the browser would 'fit' the entire content within this div.
So if you want the div (or the paragraphs contained in it) to be scrollable, then you would have to specify the height and then tell the browser to provide a scroll for the content that won't fit in the specified size.
I am not sure if you want the individual 'paragraphs' to be scrollable or the entire div( which contains these paragraphs) to be scrollable. In either case, you would need to provide a fixed height for the scroll to be useful. Your paragraph tag would need to have the following CSS applied to it :
p {
height: 200px; /*Some fixed height*/
overflow-y: scroll;
}
Here's an example of this: http://jsfiddle.net/y49C3/
In case you want your div called 'content' to be scrollable (as opposed to the paragraphs), then you would have to apply the aforementioned CSS to the div instead.
.content {
overflow-y: scroll;
height: 500px;
}
You can see that here: http://jsfiddle.net/qF7Mt/1/
I have tested this in Firefox (29) and IE 10 and it works fine!!!
Hope this helps!!!

Square DIV with Content in a Fluid Layout

SO,
I've created a four-column fluid-width layout for a site, and I'm working on placing a fluid square DIV within one of my columns. There are a few techniques I've found to achieve this - namely, setting padding-bottom to the same percentage as the width - but none of these seem to work when the DIV contains content.
Is there a way to maintain a 1:1 (square) ratio on a fluid DIV when that DIV contains content?
Here's my HTML:
<div id="leftmostcolumn">
<div id="logo"></div>
</div>
<div id="leftcolumn"></div>
<div id="rightcolumn"></div>
<div id="rightmostcolumn"></div>
And my CSS:
body {
width: 100%;
height: 100%;
background-color: red;
}
#leftmostcolumn {
position: absolute;
top: 0;
left: 0;
width: 25%;
height: 100%;
background-color: blue;
}
#leftcolumn {
position: absolute;
top: 0;
left: 25%;
width: 25%;
height: 100%;
background-color: green;
}
#rightcolumn {
position: absolute;
top: 0;
left: 50%;
width: 25%;
height: 100%;
background-color: yellow;
}
#rightmostcolumn {
position: absolute;
top: 0;
left: 75%;
width: 25%;
height: 100%;
background-color: gray;
}
#logo {
width:100%;
padding-bottom:100%;
background-color: #aa2d2d;
color: white;
}
​​
And here's a JsFiddle.
The DIV "logo" is the one I'm trying to maintain as a square. Right now, I've used the padding-bottom approach but that doesn't do the trick when there's content in the DIV. Any input is greatly appreciated!
Marca
EDIT:
Getting there...I'm adapting a script I found to find the width of the DIV and then apply that value to the height to keep it a square. However, as it stands now the script doesn't constantly resize the DIV, and it won't allow it to shrink below a certain size. Any thoughts on how to correct either of these issues?
HTML:
<div id="box"></div>
CSS:
​ #box { width: 75%; height: 50px; background-color: black; }​
JQUERY:
$("#box").css("height", function() {
return $(this).width();
});
JsFiddle is here.
This is something I've actually been messing around with for a while, and have come up with a quasi (but not entirely) hacky, CSS-only solution that seems to work on most browsers in the past decade. The trick is to use images, and positioning in a tricky fashion. Consider the following (simplification) of your code.
Markup:
<div class="sqr_box">
your content goes here!
</div>
CSS:
.sqr_box
{
width: 50%; /* or 100px, or 20em, or whatever you want */
border: solid 2px pink;
background-color: grey;
color: white;
}
Now, we can't set the height in terms of percent, so we won't; instead, first we'll go into Photoshop, and make an image that is 2x2 px, transparent, or background-colored. Next we'll add the following to your markup:
<div class="sqr_box">
<img src="images/sizers/2x2.png" class="sizer">
<div class="content">your content goes here!</div>
</div>
and THIS to your CSS:
.sqr_box
{
width: 50%; /* or 100px, or 20em, or whatever you want */
position: relative; /* static positioning is less than ideal for this scenario */
}
.sqr_box > img.sizer
{
display: block; /* images default to an inline-block like thing */
width: 100%;
height: auto; /* CLUTCH!!! this ensures that the image's height changes to maintain proportions with it's width */
visibility: hidden;
}
.sqr_box > .content
{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%; /* Our parent element now has a dynamically assigned height, this will work */
border: solid 2px pink;
background-color: grey;
color: white;
}
Best of all, this will work for any sized ratio of box you'd want! Just change the proportions of the image!
Hope this is all still relevant to you, 3 months later.
-Sandy
Put all four columns in one div. set that div to 100% width and set the font size to 100em
Have each of your four columns have a width of 25em instead of 25%
Have your logo width and height set to 25em each

CSS Working in Chrome but not Firefox ( div height )

I have been building a website and mainly testing it in Chrome.
Recently I realised some of the CSS does not apply in Firefox.
I guess it's probably : main { min-height }
This jFiddle reproduces this error, where the main div doesn't have the height it's supposed to. http://jsfiddle.net/msW9m/
HTML :
<div id='main'></div>
<div id="container"></div>
<div id='footer'>
<div id='footerRelative'>Development by <a href='mailto:'>John Doe</a></div>
</div>​
CSS :
#main {
min-height: 80%;
height: auto;
border: 1px solid #bbbbbb;
margin: 3% 5% 1%;
padding: 10px 10px;
}
#footer {
position: absolute;
left: 50%;
}
#footerRelative {
position: relative;
left: -50%;
font-size: 80%;
}
/*Probably Irrelevant*/
#container {
margin: 0 auto;
margin-top: -300px;
margin-left: -261px;
position: absolute;
top: 50%;
left: 50%;
width: 523px;
height: 600px;
background-image: url('../images/doctorSymbol.jpg');
background-repeat:no-repeat;
background-position:center;
opacity: 0.125;
overflow: hidden;
z-index: -1;
}
However, in Chrome everything works perfectly and the main div has a min-height of 80% . I was wondering if there is a workaround to this or If I am doing something wrong.
Thank you.
Have you tried making body and html 100%?
In some browsers, the body element doesn't keep 100% height until its content is full.
http://jsfiddle.net/HRKRN/
html, body {
height: 100%;
}
Also a possible solution that worked for me: set the div's display to table-cell.
use CSS3 to solve this issue
http://pastebin.com/Q8727Kvt
Align vertically using CSS 3