Responsive aspect ratios with pure css: how to fill container's height? - html

I have a div (the one with class container) with fixed height (which is supposed to be dynamic and not known in advance) which contains another div (the one with class fixed-aspect-ratio).
I would like the inner div to fill the container's height while keeping a fixed aspect ratio of 1:1.
The commonly used trick to achieve fixed aspect ratios is to exploit padding: in fact when declaring percentages instead of fixed values for padding, the percentage is calculated based on the WIDTH of the element in question, even if we are declaring a vertical value such as padding-top or padding-bottom.
This makes padding a great trick to exploit if you want to fill the container's WIDTH, but not if you want to fill the container's HEIGHT.
Is it possibile to achieve it using CSS only? No javascript thanks.
Ideally I would love to have CSS units complementary to the viewport ones, but relative to the container. Something like:
cw (container width)
ch (container height)
cmin (container min)
cmax (container max)
Would be freaking awesome.
<!DOCTYPE html>
<html>
<head>
<style>
.container {
background-color: green;
height: 30vh;
}
.fixed-aspect-ratio {
background-color: red;
width: 100%;
padding-top: 100%;
/* 1:1 Aspect Ratio */
position: relative;
/* If you want text inside of it */
}
/* If you want text inside of the container */
.text {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
</style>
</head>
<body>
<div class="container">
<div class="fixed-aspect-ratio">
<div class="text">Some text</div>
<!-- If you want text inside the container -->
</div>
</div>
</body>
</html>
https://www.w3schools.com/code/tryit.asp?filename=FLJBS4J2MTWS

There is no similar CSS solution for height, as the padding-bottom for width.
Besides script, here is a this trick I have used, where I place an img, with a data url SVG (could be a Base64 png as well) to avoid an extra roundtrip to the server, having a square size.
By setting its height to 100%, it will keep its parent, being inline block, a square, and with visibility: hidden hide it.
Stack snippet
.container {
background-color: green;
height: 50vh;
}
.fixed-aspect-ratio {
display: inline-block;
background-color: red;
height: 100%;
position: relative;
}
.fixed-aspect-ratio img {
display: block;
height: 100%;
visibility: hidden;
}
.text {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
<div class="container">
<div class="fixed-aspect-ratio">
<img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10'><rect width='10' height='10'/></svg>">
<div class="text">Some text</div>
<!-- If you want text inside the container -->
</div>
</div>

Set height to 100% and width to x%
<!DOCTYPE html>
<html>
<head>
<style>
.container {
background-color: green;
height: 30vh;
}
.fixed-aspect-ratio {
background-color: red;
height: 100%;
width: 10%;
/* 1:1 Aspect Ratio */
position: relative;
/* If you want text inside of it */
}
/* If you want text inside of the container */
.text {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
</style>
</head>
<body>
<div class="container">
<div class="fixed-aspect-ratio">
<div class="text">Some text</div>
<!-- If you want text inside the container -->
</div>
</div>
</body>
</html>

Related

Position div below responsive inline-block divs

I have a grid of divs, each responsive to the browser size so that their width changes in proportion to their height (their ratio stays the same). I'd like a separate div (its height determined only by the text it contains) to sit underneath all these, creating additional space for itself at the foot of the page. At the moment it sits under the first row. Is there a solution?
Thanks for your help.
https://jsfiddle.net/Ly008adL/
CSS:
* {
margin: 0;
padding: 0;
}
.wrapper {
width: 100%;
display: inline-block;
position: relative;
}
.wrapper:after {
padding-top: 71%;
display: block;
content: '';
}
.main {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
}
.ratio {
display: inline-flex;
float: left;
width: 50%;
height: 100%;
}
.red {
background-color: red;
}
.yel {
background-color: yellow;
}
.foot {
position: relative;
}
HTML:
<div class="wrapper">
<div class="main">
<div class="ratio yel"></div>
<div class="ratio red"></div>
<div class="ratio red"></div>
<div class="ratio yel"></div>
<div class="ratio yel"></div>
<div class="ratio red"></div>
</div>
</div>
<div class="foot">
<p>Text for the foot of the page </p>
</div>
A friend helped me figure out a potential solution involving dividing the height by the number of rows, but I'm not sure on the total number of rows yet so something more flexible would be ideal...
The css ratio trick you are using was being applied to the .wrapper and not the individual elements.
I simply removed it from the .wrapper and applied it to the individual .ratio elements. I also had to double the padding-top from 71% to 142% to maintain the right ratio because these elements were 50% width and not 100% like the .wrapper was.
I also changed the .main div to position:relative; so that all the children would render out properly and so the .foot div would render after it.
See the updated fiddle here.

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

Make flash file scale to div width and maintain height according to its aspect ratio

We're having a problem to make a flash file scale 100% according to the parent div width, while still maintaining the height according to its aspect ratio.
Please check out the code on jsFiddle (http://jsfiddle.net/LgegF) or paste the below code into an empty html-page:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
<script type="text/javascript">
swfobject.embedSWF("http://www.diescon.net/yellowfestival/400x400.swf", "flash-content", "100%", "100%", "9.0.0", '', null, {wmode: 'transparent'});
</script>
<style type="text/css">
body {
background-color: #ccc;
margin: 0;
}
#container {
width: 400px; /* Fixed width according to page template */
height: auto; /* Container height should adapt to the content, we do not want to set a fixed height here */
background-color: pink; /* Background of container */
position: absolute;
top: 0;
left: 0;
}
#flash-content {
width: 400px; /* Fill the width of the parent, could be fixed but ideally 100% */
height: 100%; /* We want the height of the flash object/flash content to scale according to the aspect ratio of the swf, we do not want to set a fixed height here */
}
/* This is what we really want */
#what-we {
width: 400px;
height: auto;
background-color: pink;
position: absolute;
top: 0;
right: 0;
}
#really-want {
width: 100%;
height: 400px; /* This is what we really want, but without setting this height fixed */
background-color: yellow;
}
</style>
</head>
<div id="container">
<div id="flash-content"></div>
</div>
<div id="what-we">
<div id="really-want">
<span>This is what we really want</span>
</div>
</div>
</body>
</html>
I have a similar problem and I find this page that was very useful:
http://css-tricks.com/NetMag/FluidWidthVideo/Article-FluidWidthVideo.php
Based on what I've learn on this article, I propose to change your HTML code to:
<div id="container">
<div class="videoWrapper">
<div id="flash-content"></div>
</div>
</div>
And to change your CSS code by adding:
.videoWrapper {
position: relative;
padding-bottom: 100%; /* 1:1 */
padding-top: 0px;
height: 0;
}
.videoWrapper object, .videoWrapper embed, {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
You can see the result here:
http://jsfiddle.net/LgegF/56/
Hope this help.
PatBriPerso
It appears what you are looking for is
width: 100%;
height: auto;
Let me know how that works out.
-Brian
Ommit the css height declaration for the flash container alltogether. Swf's usually do scale (or you can set their scale behaviour in your embed/swfobject options), so if you just restrict the width, the height of the swf itself scales accordingly.
[edit:]
Working fiddle (with very rudimentary swf embed code): http://jsfiddle.net/LgegF/1/
You notice how the swf scales when scaling the browser. The white on top and bottom of the swf is due to the object inclusion, swfobject or the tags give you controll over how the swf itself scales (scale mode, align, valign, etc). What you notice though, is how the swf uses the container's width to determine its size, i.e. fitting the width and scaling the height accordingly.

CSS width and margin as percent not behaving as I want

<html>
<head>
<style>
html, body {
background-color: red;
height: 100%;
width: 100%;
overflow: hidden;
}
* { margin: 0; padding:0; }
.topbar {
min-width: 100%;
min-height: 50%;
background-color: green;
}
.fill {
min-width: 100%;
min-height: 50%;
background-color: white;
}
.container {
min-width: 100%;
min-height: 50%;
background-color: blue;
}
</style>
</head>
<body>
<div class="topbar">
"topbar
<div class="fill">
"fill"
<div class="container">
"container"
</div>
</div>
</div>
</body>
</html>
Why "fill" is not taking the complete 50% of its containing element "topbar" on the screen?
Why "container" is not taking complete 50% of its containing element "fill" on the screen?
Separate Question:
My goal is to create a layout which can fit almost all screens desktops/laptops. I am not focusing on phone screen layouts for now. I am trying to use width and height as percentages for my layout. Please suggest if that is the right approach or point me to alternatives.
Because the body's height is uncertain.You need a parent dom
When you use percentage for height and width, it's important that the parent element has specific size in pixel...
in this case "topbar" class should have size in pixel