CSS: Keeping a div's height relative to its width [duplicate] - javascript

This question already has answers here:
Maintain the aspect ratio of a div with CSS
(37 answers)
Closed 7 years ago.
My question is very similar to this question: CSS: 100% width or height while keeping aspect ratio?
I have a div whose position is fixed. The width of the div must be 100% and its height exactly 1/6th of its width. Is there a -webkit-calc() way of doing this?
Note: JS solutions are not preferred as a zoom/orientation change can affect the width/height.

Is this what you are after? I'm not using -webkit-calc() at all. I've inserted a 1px by 6px image into a outer div which has position: fixed applied to it, and set the image to have a width of 100% and position: relative. Then I have added an inner div which is absolutely positioned to be as high and wide as its ancestor.
Now you can change the width of the outer div, and the images' width: 100% setting will ensure that both the outer and the inner div's are guaranteed to always have a height equal to 1/6th of their width (or at least as close to exactly equal as it can get, the heights will be rounded off to the closest whole number of pixels). Any content could go inside the inner div.
HTML
<div>
<div></div>
<img src="https://dl.dropboxusercontent.com/u/6928212/sixbyone.png" />
</div>
CSS
html, body {
margin: 0px;
padding: 0px;
}
div {
position: fixed;
width: 100%;
}
div > div {
position: absolute;
top: 0px;
right: 0px;
bottom: 0px;
left: 0px;
}
img {
width: 100%;
display: block;
position: relative;
}
Here's a jsFiddle showing the requested behaviour.

You can also use the solution I described in Responsive square columns.
It is based on the fact that % padding-top/bottom and margin-top/bottom are calculated according to the whidth of the parent element.
Adapted to your situation it would look like this :
FIDDLE
HTML :
<div class="wrap">
<div class="content">
</div>
</div>
CSS :
.wrap{
position:fixed;
width:100%;
padding-bottom:16.666%; /* 100x1/6 = 16.666...*/
}
.content{
position:absolute;
top:0;
bottom:0;
left:0;
right:0;
}

you can always set div width like this:
$('#div1').css("width", $('#div1').height()/6);
EDIT:
or you could use something like this:
/* Firefox */
width: -moz-calc(100% / 6);
/* WebKit */
width: -webkit-calc(100% / 6);
/* Opera */
width: -o-calc(100% / 6);
/* Standard */
width: calc(100% / 6);
This is only an example-..But it is impossible to get height of a div in a pixels in the css file..you need to use jquery for that
EDIT:
height 1/6 of a width
$('#div1').css("height", window.width()/6);

you could use jquery, e.g.$('.someclass').css('width', 180);
$('.someclass').css('height', $('.someclass').width() / 6);
moved the second suggestion from the comment for readability
$('.btnResize').click(function() { $('.div').css('height', $('.div').width()/6);});

Related

Horizontally and vertically centered iframe with aspect ratio 16:9 that uses as much screen estate as possible without being cropped anywhere

Requirements:
The HTML: The iframe HAS to be inside of a containing div. See code down below.
The CSS: The container should be able to have ANY valid width and height using the vw and vh viewport units. Se code down below.
Yes, the width and height HAS to be in vw and vh.
The static video preview image should NEVER be cropped.
The static video preview image should NOT have any black bars above and below (letterboxing).
The static video preview image should NOT have any black bars to the left or to the right (pillarboxing).
The static video preview image should use as much space estate as possible inside the div that contains it.
The static video preview image should ALWAYS keep its aspect ratio of 16:9.
Scrollbars should NEVER appear.
The static video preview image should be centered vertically as well as horizontally inside the div that contains it.
Responsive Web Design.
When resizing the browser or viewport all of the above requirements should be fulfilled.
HTML:
<div class="container">
<iframe></iframe>
</div>
CSS:
.container {
width:90vw;
height:50vh;
}
Same solution, but no extra markup for keeping the ratio.
JsFiddle with same comments totally not needed.
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8">
<title>Fully Container Centred Iframe</title>
<meta name="generator" content="PSPad editor, www.pspad.com">
<style>
.container {
display:table-cell; /* (specs: omitted table parts, the browser will insert mandatory elements in the dom tree) */
position:relative;
padding:; /* optional, margins ignored */
width:100vw; /* any value */
height:1vh; /* will expand by the :before element */
overflow:hidden; /* hide eventual black bars */
background:tan; /* bg-colors just for demo testing */
vertical-align:middle;
text-align:center;
}
.container:before {
display:block;
padding-top:56%; /* keeps the 16/9 ratio for the AP */
height:0;
background:red;
content:"\a0";
}
.container iframe {
position:absolute; /* to be ratio consistent */
top:-.5%;
left:-.5%; /* overflow eventual black bars */
border:0;
width:101%; /* grow some to avoid thinner black bars */
height:101%;
overflow:hidden; /* for html5 browsers the html attribute is depreciated */
background:gold;
}
</style>
</head><body>
<div class="container">
<iframe scrolling="no" src=""></iframe>
</div>
</body></html>
Using JavaScript, you can listen for the resize event, which fires whenever the browser's window changes shape. Then, with some simple algebra you can calculate the dimensions of the iframe based on the dimensions of the container. Here is a demo that shows all of the requirements.
"use strict";
var container = document.querySelector('.container');
var frame = container.querySelector('iframe');
function resizeVideo() {
frame.width = frame.height = 0;
var width = container.offsetWidth;
var height = container.offsetHeight;
if (height * (16 / 9) <= width) {
frame.height = height;
frame.width = height * (16 / 9);
} else {
frame.width = width;
frame.height = width * (9 / 16);
}
}
window.addEventListener('load', resizeVideo);
window.addEventListener('resize', resizeVideo);
.container {
width: 90vw;
height: 50vh;
display: table-cell;
text-align: center;
vertical-align: middle;
}
<div class="container">
<iframe src="https://www.youtube.com/embed/BKhZvubRYy8" frameborder="0" allowfullscreen></iframe>
</div>
if you want Responsive use
.container, iframe {
width:100%;
height:auto;
}
.container {
width:90vw;
height:50vh;
}
.container iframe {
width: 100%;
height: 100%;
}
Seems to work quite nicely in this fiddle https://jsfiddle.net/1q10L7hj/
why don't you just use the calc method to get the aspect ratio width you are wanting?
HTML
<div class="container">
<iframe src="" frameborder="0"></iframe>
</div>
SCSS
<style>
$width = 80vw;
.container {
width: $width;
height: calc(($width/16) * 9);
position: relative;
}
iframe {
position: absolute;
width: 100%;
height: 100%;
top: 50%;
left: 50%;
-webkit-transform: translate(+50%, -50%);
transform: translate(+50%, -50%);
}
</style>
then you can change the width of it anywhere and apply whatever positioning you want on the container div and the iframe with follow suit
I think the table-cell display could solve this. Just apply it on the container so the iframe is the content
According to specs the browser will insert dummy elements where it needs to render the cell correctly and fully centre and to contain its content and if it need, grow with it.
The requirements: I think some of them is beyond the scope of your question, they will also depend on what is loaded in the iframe, out of control of this container document. My suggested code is simple, but I believe it meets all requirements possible for the iframe parent and still be crossbrowser friendly.
The forbidden black bars and the mandatory aspect ratio could still be at fault in the loaded document. If you can't control whats loaded, the last option might be the "srcdoc" and "seamless" attributes, but that would exclude e.g. all IE versions.
JsFiddle with some comments totally not needed. Hope the edit below solves the case.
Anyway, I had fun! Thanks! :)
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8">
<title>Fully Container Centred Iframe</title>
<meta name="generator" content="PSPad editor, www.pspad.com">
<style>
.container {
display:table-cell;
padding:;
width:100vw;
height:20vh;
background:tan;
vertical-align:middle;
text-align:center;
}
.container .ratio{
display:inline-block;
position:relative;
padding-bottom:56%;
width:100%;
height:0;
overflow:hidden;
vertical-align:middle;
}
.container iframe {
position:absolute;
top:-1%;
left:-1%;
border:0;
width:102%;
height:102%;
overflow:hidden;
vertical-align:middle;
}
</style>
</head><body>
<div class="container">
<div class="ratio">
<iframe scrolling="no" src=""></iframe>
</div>
</div>
</body></html>
I have gotten the result you wanted, I however had to add an extra div as the parent of the .container class. This JSFiddle should work for users on chrome (Windows desktop version) however when I tried to use the same fiddle on Edge and IE11 I found that it would create the undesired letter-box effect due to the image cover zooming too far out.
HTML
<div id="wrapper">
<div class="container">
<iframe scrolling="no" src="https://www.youtube.com/embed/YL9RetC0ook" frameborder="0" allowfullscreen>
</iframe>
</div>
</div>
CSS
body {
margin: 0;
}
#wrapper {
width: 90vw;
height: 50vh;
}
.container,iframe {
width: 100%;
height: 100%;
}
I am not sure if this works for Firefox, so perhaps if you have Firefox you can try it on my JSFiddle. However for Chrome (at the very least) this should be the solution you where looking for as stated by the requirements you listed.
I would recommend using a JavaScript window.resize listener to solve this kind of an issue. Cannot write code today cause I have a pretty tight schedule, but I'll try writing an algo:
On window resize, compute window width (wW) and window height (wH);
Determine container width (cW) as per wW (say cW = wW-10 to get almost all the width available - you can omit the -10 if you want);
Determine container height (cH) as per cW computed above: cH = cW * 9 / 16;
Now, if cH > wH (i.e. the container is not fitting into the screen vertically because it is too wide), we should revise cW as per available window height. In this case, cH = wH-10 (to get almost all the vertical space available - again, you can omit the -10 if you want) and then cW = wH * 16 / 9;
You should have a valid cW and cH now to make you container fit into the window without going out of the screen and you can apply it to the container.
To center the container to the screen, use position: absolute, left: 50%; top: 50%; in your CSS. When you update the cW and cH, also update margin-left: -(cW/2); margin-top: -(cH/2);
This is the concept - you can improvise as per your needs. I hope it helps.

centering a div in a container larger than 100%

i need to center a div in the viewport in a container larger then 100%.
assuming it's 160% large, i prepared this fiddle:
https://jsfiddle.net/mz0bbz14/2/
usually i would go for:
position:absolute;
top:50%;
left:50%;
transform:translate(-50%,-50%);
but this works only when its container is 100% large.
it's solved with this css
position:absolute;
top:50%;
text-align: center;
transform:translate(0,-50%);
width: 100vw;
but the vw unit doesn't work on older android browsers and i need to support it. I can't use jQuery and i don't know how to center it with pure javascript.
i tried setting .div to half the width of the container, but the text inside the div doesn't visually center.
i can't find a solution. any ideas? thanks
If I understand your problem correctly, you want the red .div centered in the left 100% of the parent container that has a width of 160% of the view port.
In that case, you need to adjust the left offset to be 50% of 100%/160%, which is 31.25%.
body,html {
height: 100%;
}
.cont-inner {
width:160%;
height: 100%;
background: hotpink;
position:relative;
}
.div {
position:absolute;
top:50%;
left: 31.25%;
transform:translate(-50%,-50%);
background:red;
padding:50px; /* smaller size for demo in snippet window */
}
<div class="cont-inner">
<div class="div">
asd
</div>
</div>
You need to change the left property.
It needs to be in the middle of the visible part of the container.
Since it's 160%, it is
(100 / 160) * 0.5 -> 31.25%
body,html {
height: 100%;
}
.cont-inner {
width:160%;
height: 100%;
background: hotpink;
position:relative;
}
.div {
position:absolute;
top:50%;
left:31.25%;
transform:translate(-50%,-50%);
background:red;
padding:100px;
}
<div class="cont-inner">
<div class="div">
asd
</div>
</div>
;
I wanted to place an answer with modified left property, but I already see them, so here's some other attempt with position:static freeing inner div from its parent
https://jsfiddle.net/mz0bbz14/9/
It just doesn't force you to stick with 160%.
If you need to support older browsers you shall use Javascript to make sure it will work since all CSS solution require hard-coding values.
var parent = document.querySelector('.cont-inner'),
child = parent.querySelector('div');
child.style.left = ((window.innerWidth / 2) - (child.offsetWidth / 2)) + 'px';
child.style.top = ((window.innerHeight / 2) - (child.offsetHeight / 2)) + 'px';
Example: https://jsfiddle.net/9syvq2r2/

Changing footer position to be at the bottom of page until it hits content

(I am looking for an HTML/CSS fix but if there really is none then JS (prefereably JQuery) works for me)
I have two main divs inside my page, I have the #maincontent and the #footer.
Basically, I want the footer to always sit at the bottom on the page:
#footer{
position:fixed;
bottom:0;
}
BUT I do not want it to overflow on the #maincontent when the page is too small.
For the sake of the question the page can be thought of as simple as:
<body>
<div id="maincontent">Dynamic Content</div>
<div id="footer">StaticContent</div>
</body>
My problem is that I can do one or the other, either I fix it to the bottom of the page but when I make the viewport < (footer + maincontent) the footer sits on top of the content. I want the footer to always be at the bottom of the page but disappear off page before it overtakes the main content.
Add a class to the footer with jQuery that changes it to position: absolute when the viewport is too small.
$(document).ready(function() {
var height = $(window).height();
function windowHeight() {
height = $(window).height();
}
windowHeight();
$(window).resize(function() {
windowHeight();
});
if (height < 600) { //arbitrary height value you can set yourself
$('#footer').addClass('not-fixed');
} else {
$('#footer').removeClass('not-fixed');
}
});
If you know your footer's height whatever happens to the window height, or its content :
Just add a "padding-bottom" to your body or main content that matches the footer's height.
If you don't know your footer's height. This is trickier, as you will probably need some javascript to calculate the height of the footer, the height of the main content, compare the sum of both with the window height, and if it doesn't fit, add some adequate bottom padding to the body / main content.
EDIT :
Ok I understand, I think this jsfiddle should do the trick : http://jsfiddle.net/ah4XA/2/
The javascript would be :
$(document).ready(function () {
function updateFooter () {
var footerH = $("#main-footer").height();
var contentH = $("#main-content").height();
var windowH = $(window).height();
if ( contentH + footerH > windowH) {
$("#main-footer").removeClass("fixed");
} else {
$("#main-footer").addClass("fixed");
}
}
$(window).resize(function () {
updateFooter();
});
updateFooter();
});
If I understand what you're looking for, you want the footer to stay on the bottom of the window regardless of the page content, but also not overlap the page as the window is resized vertically.
One possible solution is to switch between position:absolute; and position: fixed; with a media query. So past a certain height it's fixed, but below that the footer position:absolute;.
EXAMPLE FIDDLE
CSS:
#media all and (max-height:300px) {
#footer {
background: red; <- added for testing
position: absolute;
}
}
The only drawback to this approach is that you need to know the height to set the switchover to. This may be tricky, but position:fixed;.
The simplest solution would be to position footer at the bottom permanently and increase the z-index of your maincontent so that it comes over the footer if window size is decreased.
NOTE: This is not the only way to do this.
JSFIDDLE DEMO
Sample CSS
#maincontent{
height : 400px;
background-color : green;
/*
position : relative is added to enable z-index.
*/
position:relative;
/*
z-index will bring it above footer,
if window size is reduced.
*/
z-index: 1;
width : 100%;
}
#footer{
height : 100px;
width : 100%;
background-color : black;
/* Below two properties will
postion footer at the bottom of the page.
*/
position : fixed;
bottom : 0;
color : white;
}
You should play with CSS position property to get this done.
EDIT:
Here is another CSS solution :
The maincontent and footer are wrapped in a bodyContainer div its position is set to relative and then footer is positioned w.r.t it.
JSFIDDLE DEMO 1 Footer is below body and not shown.
JSFIDDLE DEMO 2 Footer is shown since body height is less.
HTML
<div id="bodyContainer">
<div id="maincontent">Dynamic Content
</div>
<div id="footer">StaticContent</div>
</div>
CSS
#bodyContainer {
min-height: 100%;
position: relative;
}
#maincontent{
height : 800px;
background-color : green;
padding-bottom: 60px;
width : 100%;
}
#footer{
background-color: black;
bottom: 0;
color: #FFFFFF;
height: 48px;
position: absolute;
width: 100%;
}

Resize div to largest possible size when constrained by size of parent div and a aspect-ratio [duplicate]

This question already has answers here:
How to Auto-Resize a DIV with CSS while keeping Aspect Ratio?
(2 answers)
Closed 9 years ago.
Background:
I have the html:
<div id="container">
<div id="page"></div>
</div>
Where #container is a fluid element that's width and height is determined by the window size.
Question:
What I am trying to do is programtically set the height and width of #page so it occupys the largest size it can while being constrained by:
It must not be larger than #container
It must maintain a given aspect ratio e.g. 16:9
The part I am struggling with most its making it fill the largest size it can relative to the parent div.
Any help would be much appreciated.
Thanks
I'm not sure on my actual syntax, but the idea should work just fine.
var container = document.getElementById('container');
var page = document.getElementById('page');
var scale = Math.min(container.width / 16, container.height / 9)
page.width(scale * 16);
page.height(scale * 9);
You could also achieve the desired effect without the use of Javascript by setting the aspect ratio in the containing elements padding-top: 56.25%;. The page element will need to be anchored, for example top: 0; right: 0; and set you width/height to 100%. Here is an updated JSFiddle for your review: CLICK HERE
HTML:
<div id="container">
<div id="page"></div>
</div>
CSS:
#container{
position: relative;
padding-top: 56.25%; /*16:9 aspect ratio*/
background:#ff0;
}
#page{
position: absolute;
width:100%;
height: 100%;
top: 0;
right: 0;
background:red;
opacity: 0.5;
}
use this JQuery code:
jsFiddle
var parentw = $("#page").parent().width();
$("#page").height(function(){
return parentw*9/16;
});

resizing and centering an <img> inside a div and keeping aspect ratio

I have a div that has a fixed size of 500x500. Inside this div I have an image tag which can be dynamic. Meaning that it can have a size of a square, a rectangle (width > height), or a vertical rectangle (height > width). The issue is that I don't want this image to be squished, I wanted to keep the aspect ratio of the image. So say the image size is 1000x250, then I want it to be resized as 500x125 and then centered on this 500x500 box. If the size is 500x1000 then we wanted it to be resized as 250x500 and then centered with white spacing on the left and right.
Is there an easy way to do this using purely css or do I need javascript in order to do this? and how?
Here's the structure of what I have now:
<div class="product-large" style="position: relative; overflow: hidden;"><img src="/images/store_logos/9ae3d8f75c80d5a48bf59f975e8450c9e8b7a9d9.jpeg" alt=""><img src="/images/store_logos/9ae3d8f75c80d5a48bf59f975e8450c9e8b7a9d9.jpeg" class="zoomImg" style="position: absolute; top: -236.43249427917618px; left: -188.05491990846681px; opacity: 0; width: 1024px; height: 714px; border: none; max-width: none;"></div>
Updated for vertical centering - jQuery required.
HTML
<div class="product-large">
<img src="image1.jpg">
</div>
<div class="product-large">
<img src="image2.jpg">
</div>
CSS
.product-large {
width:500px;
height:500px;
border:1px red solid;
position:relative;
}
.product-large img {
max-width:500px;
max-height:500px;
width:auto;
height:auto;
position:absolute;
top:50%;
left:50%;
}
Javascript (jQuery)
$(".product-large img").each(function () {
//get height and width (unitless) and divide by 2
var hWide = ($(this).width()) / 2; //half the image's width
var hTall = ($(this).height()) / 2; //half the image's height, etc.
// attach negative and pixel for CSS rule
hWide = '-' + hWide + 'px';
hTall = '-' + hTall + 'px';
$(this).addClass("js-fix").css({
"margin-left": hWide,
"margin-top": hTall
});
});
New Fiddle: http://jsfiddle.net/Asvdk/2/
I think you can do:
#conatiner {
line-height:500px;
height:500px;
width:500px;
}
#img {
max-width: 100%;
max-height:100%;
display: block;
margin: 0 auto;
vertical-align: middle;
}
minimal partial example here: http://jsfiddle.net/cahs4/
I didn't do the vertical alignment but you can see what I mean
If you're consider to use jQuery, then you can have a look at the ImgCenter jQuery plugin here.

Categories