Maintain aspect ratio of a div with dynamic height - html

I wanted to create a square div by pure CSS what it's height is dynamic and it's width will scale base on height.
As we can see in the snipet below, the container height is dynamic base on its content.
The red square take full height of the container and the width should be equal height.
I know we can maintain aspect ratio of a div base on its width but i can not find a way when the height is dynamic.
Any help would be appreciated! Thanks so much!
Note that: The height is dynamic so the solution with vh did not work and the snipet is just a playground.
#container {
width: 400px;
padding: 20px;
border: solid 1px black;
position: relative;
}
.square {
position: absolute;
top: 0;
right: 0;
bottom: 0;
background-color: red;
width: 100px /*Hmm its just a dummy value*/
}
<div id="container">
<div class="content">
I'm a dynamic content
</div>
<div class="square"></div>
</div>

Here is one other solution:
We can make an inner div inside the main .square div inherits its parent height.
Then, if we rotate that inner div, its height now becomes its width. So all we've got to do at this point, is to hide the overflow from the parent div, and apply some translation so it ends at the correct position.
#container {
width: 400px;
padding: 20px;
border: solid 1px black;
position: relative;
}
.square {
position: absolute;
top: 0;
right: 0;
bottom: 0;
overflow: hidden;
pointer-events: none;
}
.square>div {
background-color: red;
transform: rotate(-90deg) translate(100%, 0%);
width: 100vw;
height: 100%;
transform-origin: 100% 100%;
}
<div id="container">
<div class="content">
<textarea> I'm a dynamic content</textarea>
</div>
<div class="square">
<div></div>
</div>
</div>

Here you go.
Note that I added contenteditable to the content div, so that you can type in the snippet to add lines of text to see the effect. Of course this isn't necessary in your version.
#container {
width: 400px;
padding: 20px;
border: solid 1px black;
position: relative;
}
.square {
position: absolute; z-index:-1;
left:0;
top: 0;
right: 0;
bottom: 0;
background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAANSURBVBhXY/jPwPAfAAUAAf+mXJtdAAAAAElFTkSuQmCC');
background-size:contain; background-position:100% 0;
background-repeat:no-repeat;
}
<div id="container">
<div class="content" contenteditable="true">
I'm a dynamic content
</div>
<div class="square"></div>
</div>
The trick is that the background is now a red square (it's a 1×1 image) which is sized with contain. This is not possible with background-color I'm afraid.

Related

Why can't I set the margin of this wrapper?

I have a problem that I can't figure out despite an hour of YouTube videos and looking on here. I have 4 divs inside of a wrapper. I would like the wrapper to have a top margin of 27px, and a left margin of 2%. For the bottom and right sides, I would like it to automatically expand to the edge of the screen. (Viewport) What am I doing wrong here?
My code is below, and I have a fiddle at
However, the wrapper seems to do nothing and the div content starts at the edge of the screen no matter what I put in the CSS.
.wrapper {
margin: 27px auto auto 2%; // Does nothing
position:absolute;
}
#square1 { position:absolute; top:50%; width:50%;height:50%;left:0;background-color:blue}
#square2 { position:absolute; top:50%; width:50%;height:50%;left:50%;background-color:yellow}
#square3 { position:absolute; top:0; width:50%;height:50%;left:0;background-color:green}
#square4 { position:absolute; top:0; width:50%;height:50%;left:50%;background-color:red}
<div id="wrapper">
<div id='square1'></div>
<div id='square2'></div>
<div id='square3'></div>
<div id='square4'></div>
</div>
To select an element with id (wrapper in your code) you need to use '#' instead of '.'.
If you want to position something absolute, you need to position it direct/indirect parent relative, to let the browser know relative to which element place that absolutely positioned.
Also auto margins on right and left would center element (element is in the center if space from right and left are equal), but to span the element across you need to specify it's width. Keep in mind that margin in percents would be calculated from parent sizes.
Moreover if you have only absolutely position content inside element (wrapper) it would have zero height and you need to specify it explicitly.
As a side note, try to avoid repeting yourself. All squares have same properties, so combine it to new selector (square).
#wrapper {
position: relative;
width: 100%;
height: 100vh;
margin-top: 27px;
margin-left: 2%;
}
.square {
position: absolute;
width: 50%;
height: 50%;
}
#square1 {
top: 50%;
left: 0;
background-color: blue;
}
#square2 {
top: 50%;
left: 50%;
background-color: yellow;
}
#square3 {
top: 0;
left: 0;
background-color: green;
}
#square4 {
top: 0;
left: 50%;
background-color: red;
}
<div id="wrapper">
<div id='square1' class="square"></div>
<div id='square2' class="square"></div>
<div id='square3' class="square"></div>
<div id='square4' class="square"></div>
</div>
selector is incorrect, should be id or class
made wrapper relative so child can be absolute otherwise they will stack to window not parent div
made parent div 100% height and width
There is no point of giving auto margin to right and bottom
CSS comment should be /* */
#wrapper {
margin: 27px auto auto 2%;
position:relative;
width:100%;
height:100vh;
}
#square1 {
position: absolute;
top: 50%;
width: 50%;
height: 50%;
left: 0;
background-color: blue
}
#square2 {
position: absolute;
top: 50%;
width: 50%;
height: 50%;
left: 50%;
background-color: yellow
}
#square3 {
position: absolute;
top: 0;
width: 50%;
height: 50%;
left: 0;
background-color: green
}
#square4 {
position: absolute;
top: 0;
width: 50%;
height: 50%;
left: 50%;
background-color: red
}
<div id="wrapper">
<div id='square1'></div>
<div id='square2'></div>
<div id='square3'></div>
<div id='square4'></div>
</div>
your wrapper is not class, it is id. Thats why you should use #wrapper. And it actually works:
just because of position: absolute you don't see the result, because position: absolute works so, it's mean you are using it in wrong way. Read about position. The same result we can get with code below, or with flexs or grids.
#wrapper {
margin: 27px auto auto 2%;
height: 100vh;
}
.square {
width: 49.5%;
height: 50%;
display: inline-block;
}
#square1 {
background-color: blue;
}
#square2 {
background-color: yellow;
}
#square3 {
background-color: green;
}
#square4 {
background-color: red;
}
<div id="wrapper">
<div id='square1' class="square"></div>
<div id='square2' class="square"></div>
<div id='square3' class="square"></div>
<div id='square4' class="square"></div>
</div>

Position fixed and width 25% not taking correct width

I have two divs. outer div taking 25%. And the inner div is placed at the bottom (position: fixed; bottom: 0; width: 25%; border-top: 1px solid red) But this is not taking 25%.
I am adding border for this div. So there is an white space is showing because of the width.
HTML:
<div id="main-div">
<div id="outer-div">
<div id="div-1"></div>
<div id="div-2">
<div id="inner-div"></div>
</div>
</div>
</div>
CSS:
#main-div{
height: 100%;
width: 100%;
display: table;
}
#outer-div {
width: 100%;
}
#div-1, #div-2 {
width: 100%;
}
#inner-div {
position: fixed;
bottom: 0; width: 25%;
border-top: 1px solid red;
}
How to apply exactly apply 25% width to inner-div which has position fixed ?
UPDATE Added js fiddle in comment
Remove your body margin . This issue because of you don't remove your body margin you can simply fix this
body {
margin:0;
}
body {
margin:0;
}
#main-div{
height: 100%;
width: 100%;
display: table;
}
#outer-div {
width: 100%;
}
#div-1, #div-2 {
width: 100%;
}
#inner-div {
position: fixed;
bottom: 0; width: 25%;
border-top: 1px solid red;
}
<body>
<div id="main-div">
<div id="outer-div">
<div id="div-1"></div>
<div id="div-2">
<div id="inner-div"></div>
</div>
</div>
</div>
</body>
The real reason why inner-div has more width than outer-div is because inner-div has position: fixed applied to it.
Now when you apply position: fixed, it makes the element position relative to the viewport.
So, in this case inner-div is relative to the body which has some user-agent margin styles applied. To make them have same width apply margin: 0 to the body.
Also, apply box-sizing: border-box to outer-div to exclude the border in the width.
I have updated the fiddle for you. So both divs have the same width.
https://jsfiddle.net/nashcheez/uur2h5w3/4/
Fixed position is relative to the browser window hence percentage values will be relative to the <html> element (http://www.w3schools.com/cssref/pr_class_position.asp). Although experimental position:sticky might accomplish what you need since it is relative to the viewport (parent relative element).
You can use below css for this
#inner-div {
box-sizing: border-box;
}
You can check updated fiddle
You need to reset body for browser. For this reason "inner-div" is taking space.
body{margin:0;padding:0;}
body{margin:0;padding:0;}
#main-div{
height: 100%;
width: 100%;
display: table;
background: blue none repeat scroll 0 0;
border: 1px solid blue;
}
#outer-div {
width: 25%;
border: 1px solid green;
}
#div-1 {
width: 100%;
}
#div-2 {
display: table;
height: 0;
padding-right: 2px;
width: 100%;
}
#inner-div {
text-align: center;
position: fixed;
bottom: 0;
width: 25%;
border-top: 1px solid red;
padding-bottom: 27px;
padding-top: 10px;
}
<div id="main-div">
<div id="outer-div"> //list
<div id="div-1"> //parent-scrol
<div id="div-2"> //scroll
<div id="div-3"> //inner-list
<div id="inner-div">wefffef</div> //create-new
</div>
</div>
</div>
</div>
</div>

Prevent equal height to dynamic width div from overlaping content below

Anyone know how I can prevent an equal height to dynamic width div from overlapping the content below. The div needs to expand to contain content in narrow viewports.
#caeth suggested moving the div below to be inside the div above, which works: http://jsfiddle.net/534k9e2n/5/ but I'm looking for a solution that doesn't require this.
Here's the code:
<div class="holder">
<div class="shape"></div>
<div class="shape_outer">
<div class="shape_inner">Content...</div>
</div>
</div>
<div class="shape_below"></div>
...
.holder {
display: inline-block;
position: relative;
width: 50%;
}
.shape {
margin-top: 100%;
}
.shape_outer {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.shape_inner {
background: #ddd;
min-height: 100%;
width: 100%;
}
.shape_below {
background: #111;
width: 200px;
height: 200px;
}
and a JSFiddle: http://jsfiddle.net/534k9e2n/4/
Thanks B.
Try this:
.shape {
margin:20px;
}
What you are doing is create a hidden field around the div.I think you can delete the shape-outer.

Height equal to dynamic width (CSS fluid layout) + Expand to contain overflow

Hi — is it possible to have a div with it's height equal to a fluid width expand to contain its content within a narrow viewport?
I figured out a work around with a solid colour div: http://jsfiddle.net/2nprw0xq/
But not with a border: http://jsfiddle.net/534k9e2n/
Here's the code I'm using. Thanks, B.
<div class="holder">
<div class="shape"></div>
<div class="shape_outer">
<div class="shape_inner"> Text... </div>
</div>
</div>
.
.holder {
display: inline-block;
position: relative;
width: 50%;
}
.shape {
margin-top: 100%;
}
.shape_outer {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
border: 1px solid #111;
}
.shape_inner {
padding: 20px;
}
Move border to your inner element and then add 100% width and 100% min-height, like this:
.shape_inner {
border: 1px solid #111;
padding: 20px;
min-height: 100%;
width: 100%;
}
Check it out: http://jsfiddle.net/534k9e2n/1/

How to have a div expand to the height of his sibling div

I've been searching for a while, but couldn't find a solution.
I have a div containing 2 columns of content.
<div id="container">
<div id="content1">
Content1
</div>
<div id="content2">
<span style="font-size: 1500px;"> Stretch height</span>
</div>
</div>
and the CSS:
#container {
height: 100%;
}
#content1 {
position: absolute;
top: 0;
left: 0;
width: 50%;
float:right;
background-color: pink;
min-height: 100%;
height: auto;
}
#content2 {
position: absolute;
top: 0;
right: 0;
width: 50%;
float:left;
background-color: red;
min-height: 100%;
height: auto;
}
Currently, #content1 has the height of 100% while #content2 was expanded to fit its content.
This way the background color of #content1 appears only at the top and when scrolling down you can see it's not colored.
How can I overcome that? (without using JS)
Instead of using min-height: 100%, you can use bottom: 0. When both the top and bottom attributes are set to 0 it will fill the whole height (if the position is set to absolute, that is).