Restrict width in relation to the height and vice versa - html

Using CSS I would like to restrict 1 dimension to never exceed a factor of the other.
For example this pseudocode:
max-height: (width * 0.75)px;
Would ensure that the height of the element never exceeds 75% of it's width, but it may be smaller.
Is something like this possible, or am I out of luck?
Edit: Please note that I'm not looking to make the height exactly 75% of the width, but rather I am looking to make sure it doesn't exceed 75%

If the element takes the entire viewport width. You can do something like:
.class {
max-height: 75vw;
}

You can't set the ratio, but there's always padding-bottom!
div {
width: 100%;
padding-bottom: 75%;
}
This code will set div to 4:3 ratio
For 16:9 ratio use padding-bottom: 56.25%
An edit after re-read
What if I suggest using a div inside a div?
<div class="a">
<div class="b">
</div>
</div>
<style>
.a{
width:100%;
padding-bottom: 75%;
background-color: red;
position: relative;
}
.b{
width: 100%;
max-height: 100%;
background-color: white;
position: absolute;
overflow: hidden;
}
</style>
Put the content inside div.b and it will never exceed the 75%

CSS does not allow setting a property based on other's value, you would need to use another approach, such as javascript, for this.
Here's a jQuery example:
var $elem = $('#elem');
$elem.css('max-height', $elem.width() * 0.75 );

Check out this question: Height equal to dynamic width (CSS fluid layout)
Specifically #Kristijan's answer. You will need to adjust the bottom padding.
.some_element {
position: relative;
width: 20%;
height: 0;
padding-bottom: 20%;
}

Related

Scrollbar shows up even though overflow-y is set to 'hidden' [duplicate]

I'm trying to use percentage height with overflow-y:auto; and instead of creating a scroll bar on the side of the div, it's using the page scroll bar.
Here's an example of want I'm getting at: http://jsfiddle.net/hmwe2jty/
Is it possible to use this property with percent height?
TL;DR Use the viewport height/width instead of a percentage. Change 100% to 100vh, and you're done!
EDIT:
The percentages take the precentage of the parent element. For example:
console.log("Parent's width: " + document.getElementById("parent").offsetWidth);
console.log("Child's width: " + document.getElementById("child").offsetWidth);
#parent {
background: yellow;
width: 500px;
height: 150px;
}
#child {
background: orange;
width: 50%;
height: 100px;
}
<div id="parent">
<div id="child">
I am 250px wide!
</div>
</div>
The new CSS3 viewport units use the user's viewport as a base. For example:
console.log("Parent's width: " + document.getElementById("parent").offsetWidth);
console.log("Child's width: " + document.getElementById("child").offsetWidth);
#parent {
background: yellow;
width: 500px;
height: 150px;
}
#child {
background: orange;
width: 50vw;
height: 100px;
}
<div id="parent">
<div id="child">
My width is 50% of the user's viewport, regardless of the size of my parent!
</div>
</div>
Because the body element is a bit weird, it's default behaviour is to shrink to fit is contents. So:
body {
background: yellow;
border: 1px solid red;
}
The body element wraps around it contents, <br>
but the backgound just ignores this behaviour.
So, since the parent element is the body, you will need to use the new vw and vh units. Read a article on CSS Tricks
EDIT 2:
Another way to choose the viewport as parent would be to make the element's position either fixed or absolute. In that instance the parent would become the viewport, thus giving you the needed value.
use this css for div which height must dimensioned in percents of parent element:
.child {
position: absolute;
top: 10px;
bottom: 0px;
}
It is considering 100% of the parent, which is the body. Hence it occupies the height of complete space available. Specify height a lesser amount in % rather than 100 (if you specifically prefer percent). It is upto you what you chose.

The width must be equal to the height of the block [duplicate]

I need to maintain the width of an element as a percentage of its height. So as the height changes, the width is updated.
The opposite is achievable by using a % value for padding-top, but padding-left as a percentage will be a percentage of the width of an object, not its height.
So with markup like this:
<div class="box">
<div class="inner"></div>
</div>
I'd like to use something like this:
.box {
position: absolute;
margin-top: 50%;
bottom: 0;
}
.inner {
padding-left: 200%;
}
To ensure the box's aspect ratio is maintained according to it's height. The height is fluid because of it's % margin - as the window's height changes, the box's height will too.
I know how to achieve this with JavaScript, just wondering if there's a clean CSS-only solution?
You can use an image that has the desired proportions as to help with proportional sizing (images can be scaled proportionally by setting one dimension to some value and other to auto). The image does not have to be visible, but it must occupy space.
.box {
position: absolute;
bottom: 0;
left: 0;
height: 50%;
}
.size-helper {
display: block;
width: auto;
height: 100%;
}
.inner {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(255, 255, 153, .8);
}
<div class="box">
<img class="size-helper" src="//dummyimage.com/200x100/999/000" width="200" height="100">
<div class="inner">
1. box has fluid height<br>
2. img has 2:1 aspect ratio, 100% height, auto width, static position<br>
2.1 it thus maintains width = 200% of height<br>
2.2 it defines the dimensions of the box<br>
3. inner expands as much as box
</div>
</div>
In the above example, box, inner and helper are all same size.
You can use vh units for both height and width of your element so they both change according to the viewport height.
vh
1/100th of the height of the viewport. (MDN)
DEMO
.box {
position: absolute;
height:50vh;
width:100vh;
bottom: 0;
background:teal;
}
<div class="box"></div>
There is another, more efficient way to achieve constant aspect ratio according to height.
You can place an empty svg so you dont have to load an external image.
HTML code:
<svg xmlns="http://www.w3.org/2000/svg"
height="100"
width="200"
class='placeholder-svg'
/>
CSS code:
.placeholder-svg {
width: auto;
height: 100%;
}
Change width/height to achieve desired aspect ratio.
Keep in mind, the svg might overflow.
http://www.w3.org/2000/svg is just a namespace. It doesn't load anything.
If you change placeholder-svg class to:
.placeholder-svg {
width: 100%;
height: auto;
}
then height is adjusted according to width.
Demo 1 Width is adjusted according to height and 2:1 aspect ratio.
Demo 2 same as above, but you can resize easily (uses React)
The CSS trick you wrote, works pretty well to keep ratio width / height on an element.
It is based on the padding property that, when its value is in percent, is proportional to parent width, even for padding-top and padding-bottom.
There is no CSS property that could set an horizontal sizing proportionally to the parent height.
So I think there is no clean CSS solution.
As of 2021 there is a property called aspect-ratio.
Most browsers support it
div {
border: 1px solid;
margin: 8px;
}
.box {
width: 100px;
min-height: 100px;
resize: horizontal;
overflow: auto;
}
.inner1 {
aspect-ratio: 1/1;
}
.inner2 {
aspect-ratio: 3/1;
}
<div class="box">
<div class="inner1"></div>
<div class="inner2"></div>
</div>
Run this snippet and resize the outer div manually to see the inner divs behavior
I can't find a pure CSS solution. Here's a solution using CSS Element Queries JavaScript library.
var aspectRatio = 16/9;
var element = document.querySelector('.center');
function update() {
element.style.width = (element.clientHeight * aspectRatio) + 'px';
}
new ResizeSensor(element, update);
update();
CodePen demo!

Setting multiple divs by height percent to fill parent div

I have a parent div with a max height/width set. I was wondering if it's possible to set the two child divs to automatically adjust their height based on a percentage using just CSS?
HTML:
<div id="parent">
<div id="top"></div>
<div id="bottom"></div>
</div>
CSS:
html, body {
height: 100%;
width: 100%:
}
#parent {
max-width: 400px;
max-height: 600px;
}
#top {
height: 30%;
}
#bottom {
height: 70%;
}
The intended implementation of this would be for a mobile display that fills the screen height proportionally without forcing a vertical scroll.
EDIT:
I now realize that height percentages of the parent will work if you have a fixed parent height. The question still stands as to whether there is a way just using CSS to allow for a flexible height that matches the screen size. It's seems like this will not be possible only using CSS and require JS intervention.
Theres nothing wrong with your code. Just adding a 100% height as well as width to the divs yields what you want. The max-width/height doesn't force any values (leaves height/width at auto). Here is a working fiddle:
http://jsfiddle.net/b6HVa/
#parent {
width: 100%;
height: 100%;
max-height: 600px;
max-witdh: 400px;
}
I think you are doing right, if anything going wrong, please show a demo. Or try to set
#top{max-height: 30%;}
#bottom{max-height: 70%;}
Or add min-height: {some value}px; to your div.

Scale divs of the SAME ROW proportionally to the same height & Have Min Height

So I've seen this post: Can I scale a div's height proportionally to its width using CSS? and it sort of answers my Question. I can get divs to sclae porpotionally as I need. However, what I also need is to set a minimum height for those divs.
In this fiddle http://jsfiddle.net/FBZuB/1/ I have set up what I am trying to accomplish. The BLUE div is a general wrapper that then defines the height of the RED div based on the width of the BLUE div. However when I try to change the min-height on the RED div, the divs that I want to scale AND have a min-height, unexpected results occur.
I would think once I scale DOWN to the min-height point, the div would stop scaling and only change in width. However, it seems like setting the min-height just sets some sort of base point for the whole calculation and everything scales continually. I hope this makes sense.
The RED divs should scale up and down, but at a certain point, when the RED div hits its minimum height, it should stop scaling in height and only in width. I have accomplished this before with pure javascript, but since I read the post above, I am trying to get a CSS only solution.
Here is the code. You can ignore the content for now... I am focuses mainly on the red blocks. Proportionally scale width/height, until it hits the min-height and then it should stop scaling the height and only the width.
HTML
<div style="background: blue; width: 70%;">
<div id="left">
<div class="content"></div>
</div>
<div id="right">
</div>
</div>
CSS
div {
margin: 5%;
float: left;
background: red;
position: relative;
}
#left {
width: 50%;
padding-bottom: 60%;
min-height: 100px;
}
#right {
width: 30%;
padding-bottom: 60%;
min-height: 100px;
}
.content {
position: absolute;
width: 90%;
margin: 5%;
background: green;
top: 0;
left: 0;
height: 90%;
}
Unfortunately plain CSS is unable to calculate any expressions in all browsers except IE, and as such you will have to use at least some JavaScript to dynamically calculate the width.
I would probably do something like this in your html file.
Since you didn't specify how you are resizing your div, I'll assume that it's just when the window resizes.
<body onresize="
var left = document.getElementById('left');
if (left.clientHeight < left.style.min-height) {
left.style.cheight = left.style.min-height;
}
">
</body>

Setting div width as % with min-width is not working. Min-width always wins.

I am having an issue with my width: 20%; being overridden by my min-width: 30px; (see lines 22 and 23 in the css box: http://jsfiddle.net/dLmnX/)
I am also using aspect ratio for the first time: I have picked up and chopped about the code from http://ansciath.tumblr.com/post/7347495869/css-aspect-ratio.
The aspect ratio part of the code:
#aspect {
padding-top: 120%; /* aspect ratio */
}
seems to be working fine, it is just the width in this div:
#shuffle1 {
display: inline-block;
margin: 0px auto;
position: relative;
width: 20%;
min-width: 30px;
}
Any help would be great!
Thank you.
The culprit is the styling for the #two element.
http://jsfiddle.net/dLmnX/2/
#two {
display: inline-block;
}
When you specify width as a percentage, it is relative to the size of the parent element. Because #two was very small, there was no way that 20% would ever be larger than 30px. Elements set to inline-block will try to take up as little space as possible.