The expected result should be that the .item
( green color ) is followed by any element like p
without any empty space like below:
I was trying to do this by translateY
, but it just move the div .item
going up and left an empty white space like the below:
.main {
background-color: gray;
display: flex;
flex-direction: column;
justify-content: center;
margin-top: 150px; /* For illustratoin purpose only to see the result */
padding: 30px;
}
.item {
background-color: green;
height: 200px;
transform: translateY(calc(-50% - 30px)); /* Here is my try */
width: 100%;
}
<div >
<div ></div>
<p>Helloooooooooooooooooooooooooo</p>
</div>
I have also tried margin-top: -50%;
, I thought it should work but it just going up which I think is not "50%", going so much more than -50% although I don't know why like below.
Edited: negative margin will only work if I know exactly what's its height, say its height is 200px, then I can do margin-top: -100px;
. But now the height of .item
is unknown/flexible where the height: 200px;
in the code is just for illustration purposes.
.main {
background-color: gray;
display: flex;
flex-direction: column;
justify-content: center;
margin-top: 150px; /* For illustratoin purpose only to see the result */
padding: 30px;
}
.item {
background-color: green;
height: 200px;
margin-top: calc(-50% - 30px); /* Here is my try */
width: 100%;
}
<div >
<div ></div>
<p>Helloooooooooooooooooooooooooo</p>
</div>
CodePudding user response:
The only way I can think of, is to
create a white background ::before
pseudo element inside of your Item element, that way you can position it at top 50% but most importantly at height 50% - making that height actually relative to the Item's height:
/* QuickReset */
*, ::before, ::after {margin:0; box-sizing: border-box;}
/* Just to visualize */
*, ::before, ::after {
outline: 2px solid red;
outline-offset: -1px;
}
body {
background: #000;
}
.card {
--padd: 30px;
max-width: 70%;
margin: 0 auto;
padding: var(--padd) 0;
}
.card-item {
position: relative;
background-color: #3de821;
margin: 0 var(--padd);
}
.card-item::before {
content: "";
position: absolute;
z-index: -1;
width: calc(100% (var(--padd) * 2));
height: 50%;
top: 50%;
left: calc(var(--padd) * -1);
background-color: #fff;
}
.card-desc {
background-color: #fff;
padding: var(--padd);
}
<div >
<div style="height:140px;">140px height</div>
<div >
Hello.<br>Scroll down.....
</div>
</div>
<div >
<div style="height:250px;">250px height</div>
<div >
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nulla a optio magni. Neque sed repellendus fugiat. Earum necessitatibus deleniti consectetur sequi, nemo iure, omnis molestias minima culpa ipsa rem nam.
</div>
</div>
<div >
<div style="height:60px;">60px height</div>
<div >
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nulla a optio magni. Neque sed repellendus fugiat. Earum necessitatibus deleniti consectetur sequi, nemo iure, omnis molestias minima culpa ipsa rem nam.
</div>
the reason for this solution being: margin
cannot relate to the element height, and translate
cannot act on sibling elements positions.
CodePudding user response:
Use another nested div:
.main {
background-color: gray;
display: flex;
flex-direction: column;
justify-content: center;
margin-top: 150px;
padding: 30px;
padding-top: 0px;
}
.item {
background-color: green;
height: 200px;
width: 100%;
}
.container {
transform: translateY(calc(-50% - 30px));
}
<div >
<div >
<div ></div>
<p>Helloooooooooooooooooooooooooo</p>
</div>
</div>
CodePudding user response:
you can also use position absolute.
.main {
background-color: gray;
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
margin-top: 150px; /* For illustratoin purpose only to see the result */
padding: 30px;
}
.item {
background-color: green;
height: 300px;
width: 70%;
position: absolute;
left: 50%;
bottom: 50%;
transform: translate(-50%, 0);
}
<div >
<div ></div>
<p>Helloooooooooooooooooooooooooo</p>
</div>