Yandy_Viera
Yandy_Viera

Reputation: 4380

Setting the width depending on the height of its parent

The global problem:

I want to set the width of an element depending on the parent's height, I know that you can use padding-top to set the height depending on the parent's width, maybe someone knows a trick for my case.

A possible solution(trick) to The global problem would be setting height: 100% to the element and then rotate(90deg) that would simulate that it has the width equal to the parent's height but that don't fit my case.

The specific problem ( Maybe it's possible to do some workaround):

Simplified problem:

I want a dynamic square element that has width and height = x where x = parent's height.

enter image description here


Full problem:

I want something like this

enter image description here

where x = d / sqrt(2) (Pythagorean theorem)

so as you can see "d" is the parent's height, I try with

.blue{
    background: #1AA9C8;
    width: 200px;
    height: 100px;
    position: relative;
    margin: 25px auto;
}

.blue:before{
    content: '';
    position: absolute;
    right: calc(100% - 36px);
    top: 15px;
    background: firebrick;    
    -webkit-transform: rotate(45deg);
    transform: rotate(45deg);
    height: calc(100% / 1.41);/*this worked because height depends on the parent's height (div.blue)*/
    width: 70.9px; /* calc(100% / 1.41) here is my problem  because width depends on the parent's width and I don't know how to make it depends on the parent's height
}
<div class="blue"></div>

Note that I set a fixed width because I don't know how to make it depends on the height of div.blue

Here a jsfiddle example to do some workaround.

I would be grateful if someone could help me.

ONLY CSS

Upvotes: 12

Views: 18950

Answers (5)

Karousuo
Karousuo

Reputation: 1

Although I know this question is very old, if someone reads this answer in the future, there is currently a way to do it with aspect-ratio:

.blue {
  position: relative;
  width: 200px;
  height: 100px;
  background-color: #1AA9C8;
  margin: 25px auto;
}

.blue::before {
  content: '';
  position: absolute;
  left: 0%;
  top: 50%;
  height: calc(100% / 1.41);
  aspect-ratio: 1 / 1;
  transform: translate(-50%, -50%) rotate(45deg);
  background-color: firebrick;
}
<div class="blue"></div>

aspect-ratio specifies a fixed aspect ratio between height and width. In this case, with an aspect-ratio of 1 / 1, the width, which is set to auto by default, will now have the same measurement as the height.

Upvotes: 0

John Slegers
John Slegers

Reputation: 47111

I've come up with two practical implementations for your problem. One option requires one additional wrapper. The other requires two.

Both options allow you to configure height AND width, albeit in a different way.

For your specific use case, option 1 is the best approach.

Option 1

This option requires only one additional wrapper div. You define the values for the height of your rectangle and the value of width - height (defined as a padding). The width and height of the square are adjusted automatically.


The Fiddle :

http://jsfiddle.net/w9wgb72e/9/

The code :

.bluecontainer {
    width: 100px; /* set height of rectangle */
    margin: 8px auto;
    padding-right: 100px; /* this value equals height - width of the rectangle */
    background: #1AA9C8;
}

.ratiocontainer {
    width: 100%;
    margin-left: -49.6%;
    position: relative;
    padding-bottom: 100%;
}

.ratiocontainer:before {
    content: '';
    background: firebrick;
    padding: 35.4%;
    margin: 14.5%;
    float: left;
    -webkit-transform: rotate(45deg);
    transform: rotate(45deg);
}
<div class="bluecontainer">
    <div class="ratiocontainer">
    </div>
</div>


Option 2

This option requires two additional wrapper divs. You define the values for the height and width of your square and the width of your rectangle. The height of the rectangle is automatically adjusted to allow the rectangle to wrap around the square.

The Fiddle :

http://jsfiddle.net/w9wgb72e/10/

The code :

.bluecontainer {
    width: 200px; /* set width of rectangle */
    margin: 8px auto;
    background: #1AA9C8;
}

.ratiocontainer {
    width: 100px; /* set width & height of red square */
}

.stretchy-square {
    width: 100%;
    padding-bottom: 100%;
    position: relative;
    margin-left: -50%;
}

.stretchy-square:before {
    content: '';
    background: firebrick;
    margin: 15%;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    -webkit-transform: rotate(45deg);
    transform: rotate(45deg);
}
<div class="bluecontainer">
    <div class="ratiocontainer">
        <div class="stretchy-square"></div>
    </div>
</div>

Upvotes: 0

wwwmarty
wwwmarty

Reputation: 858

Just for kicks and giggles, here is an interesting attempt that makes use of vertical percentages (padding), as explained here: http://www.impressivewebs.com/vertical-percentages-css/

.d1 {
	margin-left: 50px;
	width: 50%;
	background-color: #CCCCFF;
	border: solid black 1px;
}

.d2 {
	width: 25%;
	background-color: #FF6666;
	border: solid black 1px;
	padding-top: 25%;
	margin: 5%;
	margin-left: -13%;
	transform: rotateZ(45deg);
}
<div class="d1">
	<div class="d2"></div>
</div>

View full page mode and resize... everything scales nicely, almost :P

Upvotes: 1

wiktus239
wiktus239

Reputation: 1420

Addressing your specific, yet not full, problem:

I want a dynamic square element that has width and height = x where x = parent's height.

The dynamic square can be an image, and the parent a div.

<div class="parent-container">
    <img class="image" src="{{imageUrl}}" />
</div>

Now for this setup you give the parent a desired height and tell the element (image) to take it all. Like this:

.parent-container {
    height: 400px;   
}

.image {
    height: 100%;
}

This way, the width is not of your concern.


Edit

Modifying the CSS to this:

.parent-container {
    height: 400px;
    overflow: hidden;
}

.image {
    height: 70.92%;
    position: relative;
    transform: translate(-50%, 0)rotate(-45deg);
    top: 14.4%;
}

Should address the "Full Problem".

Please, mind that the height and top values are rough calculations and should be re-carried out.

The fiddle to boot: https://jsfiddle.net/0pok1bf0/

Upvotes: 6

K K
K K

Reputation: 18109

You may try this with the pseudo elements. However, you will still need to set the border-width if not height/width.

Demo: http://jsfiddle.net/lotusgodkk/GCu2D/752/

CSS:

.box {
    position:relative;
    background-color:#7092BE;
    width:500px;/*sample*/
    height:150px;/*sample*/
    margin:0 auto;
}
.box:before {
    position: absolute;
    content:"";
    right: 100%;
    border-style: solid;
    border-color: transparent #880015 transparent transparent;
    top: 0;
    bottom: 0;
    border-width:75px;
}
.box:after {
    position: absolute;
    content:"";
    left: 0;
    border-style: solid;
    border-color: transparent transparent transparent #880015;
    top: 0;
    bottom: 0;
    border-width:75px;
}

HTML:

<div class="box"></div>

Upvotes: 0

Related Questions