I have a colored semi-transparent div (.box) in front of some other divs (.textDisplay) containing text. One of these background divs (on the left) displays correctly, with the text faded due to the transparent div overlaid on top of it. The other one, though, doesn't fade at all. I want both divs displaying like the one on the left.
EDIT: I cannot modify the HTML's structure (it's generated by Elm in a nested manner). Is there a way to do this with CSS only?
EDIT 2: It was a stacking context problem due to the transform property. See my answer for further details.
.textDisplay {
height: 100%;
width: 100%;
text-align: center;
}
.box {
width: 200px;
padding: 20px;
background-color: #8CA8DA;
position: absolute;
top: 50%;
left: 50%;
margin-left: 20px;
transform: translateY(-50%);
opacity: 0.8;
}
.behind {
position: absolute;
transform: translate(-50%, -50%);
}
<div class="behind" style="left: 100px; top: 100px; width: 127px; height: 127px;">
<div class="content">
<div>
<div class="textDisplay">Test Text 0</div>
<div class="box" style="z-index: 100;">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi molestie ornare ex et cursus. Donec nibh urna, bibendum nec molestie sed, condimentum ut lacus.
</div>
</div>
</div>
</div>
<div class="behind" style="left: 350px; top: 150px; width: 127px; height: 127px;">
<div class="content">
<div>
<div class="textDisplay">Test Text 1</div>
</div>
</div>
</div>
Like this?
.textDisplay {
height: 100%;
width: 100%;
text-align: center;
}
.box {
width: 200px;
padding: 20px;
background-color: #8CA8DA;
position: absolute;
top: 50%;
left: 50%;
margin-left: 20px;
transform: translateY(-50%);
opacity: 0.8;
}
.behind {
position: absolute;
transform: translate(-50%, -50%);
}
<div class="behind" style="left: 350px; top: 150px; width: 127px; height: 127px;">
<div class="content">
<div>
<div class="textDisplay">Test Text 1</div>
</div>
</div>
</div>
<div class="behind" style="left: 100px; top: 100px; width: 127px; height: 127px;">
<div class="content">
<div>
<div class="textDisplay">Test Text 0</div>
<div class="box" style="z-index: 100;">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi molestie ornare ex et cursus. Donec nibh urna, bibendum nec molestie sed, condimentum ut lacus.
</div>
</div>
</div>
</div>
Put .box outside of .behind. I tweaked the css a bit to demo but you'll get the idea.
.textDisplay {
height: 100%;
width: 100%;
text-align: center;
}
.box {
width: 200px;
padding: 20px;
background-color: #8CA8DA;
position: absolute;
top: 50%;
left: 15%;
margin-left: 20px;
transform: translateY(-50%);
opacity: 0.8;
}
.behind {
position: absolute;
transform: translate(-50%, -50%);
}
<div class="box" style="z-index: 100;">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi molestie ornare ex et cursus. Donec nibh urna, bibendum nec molestie sed, condimentum ut lacus.
</div>
<div class="behind" style="left: 100px; top: 100px; width: 127px; height: 127px;">
<div class="content">
<div>
<div class="textDisplay">Test Text 0</div>
</div>
</div>
</div>
<div class="behind" style="left: 350px; top: 150px; width: 127px; height: 127px;">
<div class="content">
<div>
<div class="textDisplay">Test Text 1</div>
</div>
</div>
</div>
The transform property creates a new stacking context. As the linked article explains, this stacking context is then atomically (as a single thing) incorporated within it's parent stacking context. The z-index defined within it cannot transcend the context. There are diagrams illustrating this much better in the article.
Instead of using transform: translate(-50%, -50%); for centering, we can use left: -50%; top: -50%;, as demonstrated by the modified snippet. There has to be one div with the desired width and height (.behind) who's top left corner is where we want the center of the target div to be. See the .content class for an example of how to achieve the centering of the target div.
Once the div is centered with an alternate method, everything is in the same stacking context. Now a simple z-index: 100 on the desired element (or one of it's children, like in the snippet) will raise it above the rest, achieving the desired transparency effect.
.textDisplay {
height: 100%;
width: 100%;
text-align: center;
}
.box {
width: 200px;
padding: 20px;
background-color: #8CA8DA;
position: absolute;
top: 50%;
left: 50%;
margin-left: 20px;
transform: translateY(-50%);
opacity: 0.8;
}
.content {
left: -50%;
top: -50%;
height: 100%;
width: 100%;
position: absolute; /* or relative */
}
.behind {
position: absolute;
/*transform: translate(-50%, -50%); REMOVED*/
}
<div class="behind" style="left: 100px; top: 100px; width: 127px; height: 127px;">
<div class="content">
<div>
<div class="textDisplay">Test Text 0</div>
<div class="box" style="z-index: 100;">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi molestie ornare ex et cursus. Donec nibh urna, bibendum nec molestie sed, condimentum ut lacus.
</div>
</div>
</div>
</div>
<div class="behind" style="left: 350px; top: 150px; width: 127px; height: 127px;">
<div class="content">
<div>
<div class="textDisplay">Test Text 1</div>
</div>
</div>
</div>
Related
This is the pen I am working on and I want to create something more interesting for my portfolio, but I've stuck on the part when I want to have the same elements on the right side of the screen doing the same expanding but to the other direction (mirrored/flipped/reverted/opposite).
The full code can be viewed in the pen. https://codepen.io/benjaminj/pen/oNqWPRb
As You can see I have used scale but this also flipped and the text inside which is not the end goal of this project. Also when hovering the elements on the right weird tremble occurs which also I don't get from where is coming.
I have designed a container with expanding side where the text of the container is revealed. Also a grid seemed to me the best for positioning the elements. Below is the HTML code:
Because of the pretty weird and complex (for me) design I have used: before and: after for the text.
The elements on the left side are working as a charm, but when I tried to "mirror" those elements on the right side and expand to the center of the screen the troubles started.
But for the element on the right side I used only the scaleX (-1)
.main3 {
display: block;
grid-column-start: 3;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 2;
transform: scaleX(-1);
}
Here is the code
.gridContainer {
display: grid;
grid-template-columns: 100px auto auto 100px;
grid-template-rows: repeat(4, auto);
row-gap: 100px;
}
.main {
display: block;
grid-column-start: 2;
grid-column-end: 3;
}
.main2 {
display: block;
grid-column-start: 2;
grid-column-end: 3;
grid-row-start: 2;
grid-row-end: 3;
}
.main3 {
display: block;
grid-column-start: 3;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 2;
transform: scaleX(-1);
}
.main3 span {
}
.main3 .background::before {
width: 35%;
}
.test {
z-index: 100;
width: 400px;
height: 100px;
background-color: #67ade0;
position: absolute;
border-bottom-style: solid;
border-color: #93cff1;
border-width: 100px;
clip-path: polygon(10% 0%, 5% 50%, 10% 100%, 5% 100%, 0% 50%, 5% 0%);
}
.background {
display: inline-block;
margin-left: 20px;
width: 0px;
height: 200px;
background-color: #e1effa;
clip-path: polygon(95% 0, 100% 50%, 95% 100%, 5% 100%, 0 50%, 5% 0);
transition: width 6.5s, transform 5s;
z-index: 10;
opacity: 0.8;
}
.diamondStatic {
margin-left: 20px;
display: inline-block;
position: absolute;
height: 200px;
width: 400px;
background-color: #c4e0f5;
clip-path: polygon(5% 0, 10% 50%, 5% 100%, 0% 50%);
}
.diamondAnimate {
margin-left: -20px;
display: inline-block;
z-index: 100px;
height: 200px;
width: 400px;
background-color: #c4e0f5;
clip-path: polygon(5% 0, 10% 50%, 5% 100%, 0% 50%);
transition: margin-left 6.5s, transform 5s;
}
.test:hover ~ .background {
width: 400px;
}
.test:hover ~ .diamondAnimate {
margin-left: -45px;
}
.background::after {
margin-top: 10px;
margin-left: 140px;
position: absolute;
content: 'Managed Services';
}
.background::before {
width: 15%;
margin-top: 50px;
margin-left: 50px;
position: absolute;
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla eget erat maximus, mattis ex sed, aliquet arcu. Maecenas eleifend ornare nulla, id placerat turpis pretium quis. Class aptent taciti sociosqu.';
}
.innerBtn {
display: inline;
position: absolute;
margin-top: 150px;
margin-left: 160px;
}
<div class="gridContainer">
<div class="main">
<div class="test"></div>
<div class="diamondStatic"></div>
<span class="background">
<button class="innerBtn">CLICK ME</button>
</span>
<div class="diamondAnimate"></div>
</div>
<div class="main2">
<div class="test"></div>
<div class="diamondStatic"></div>
<span class="background">
<button class="innerBtn">CLICK ME</button>
</span>
<div class="diamondAnimate"></div>
</div>
<div class="main3">
<div class="test"></div>
<div class="diamondStatic"></div>
<span class="background">
<button class="innerBtn">CLICK ME</button>
</span>
<div class="diamondAnimate"></div>
</div>
</div>
As You can see from the visual box of the codepen, the element on the right side is trembling and the text is inverted. This issue seems to be outside of my little knowledge and that's the reason for taking the guts and posting here.
PS: I have also tried to rebuild the whole container on another way ( https://codepen.io/benjaminj/pen/zYWwyeQ) but here I stumbled with the background that I want to be visible only in the expanding area.
For the test being flipped: You just need to transform:scaleX(-1) also the inner div .background
For the hover being shaking, is because the horizontal scroll showing then hiding, so use overflow: hidden in .main
I also improved your code a bit, deleting duplicated properties and other minor stuff
body {
margin: 0;
overflow: hidden
}
.gridContainer {
display: grid;
grid-template-columns: 100px auto auto 100px;
grid-template-rows: repeat(4, auto);
row-gap: 100px;
}
.main {
grid-column: 2 / 3;
overflow: hidden
}
.main2 {
grid-row: 2 / 3;
}
.main3 {
grid-column: 3 / 4;
transform: scaleX(-1);
}
.main3 .background {
transform: scaleX(-1);
}
.test {
z-index: 100;
width: 400px;
height: 100px;
background-color: #67ade0;
position: absolute;
border-bottom-style: solid;
border-color: #93cff1;
border-width: 100px;
clip-path: polygon(10% 0%, 5% 50%, 10% 100%, 5% 100%, 0% 50%, 5% 0%);
}
.background {
display: inline-flex;
margin-left: 20px;
width: 0;
height: 200px;
background-color: #e1effa;
clip-path: polygon(95% 0, 100% 50%, 95% 100%, 5% 100%, 0 50%, 5% 0);
transition: width 6.5s, transform 5s;
opacity: 0.8;
}
.diamondStatic,
.diamondAnimate {
display: inline-block;
position: absolute;
height: 200px;
width: 400px;
background-color: #c4e0f5;
clip-path: polygon(5% 0, 10% 50%, 5% 100%, 0% 50%);
}
.diamondStatic {
margin-left: 20px;
}
.diamondAnimate {
margin-left: -20px;
transition: margin-left 6.5s, transform 5s;
}
.test:hover~.background {
width: 400px;
}
.test:hover~.diamondAnimate {
margin-left: -45px;
}
.background::before {
max-width: 75%;
margin-top: 50px;
margin-left: 50px;
content: attr(data-text)
}
.background::after {
margin-top: 10px;
margin-left: 140px;
position: absolute;
content: attr(data-title);
}
.innerBtn {
display: inline;
position: absolute;
margin-top: 150px;
margin-left: 160px;
}
<div class="gridContainer">
<div class="main">
<div class="test"></div>
<div class="diamondStatic"></div>
<span class="background" data-title="Managed Services" data-text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla eget erat maximus, mattis ex sed, aliquet arcu. Maecenas eleifend ornare nulla, id placerat turpis pretium quis. Class aptent taciti sociosqu.">
<button class="innerBtn">CLICK ME</button>
</span>
<div class="diamondAnimate"></div>
</div>
<div class="main main2">
<div class="test"></div>
<div class="diamondStatic"></div>
<span class="background" data-title="Managed Services" data-text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla eget erat maximus, mattis ex sed, aliquet arcu. Maecenas eleifend ornare nulla, id placerat turpis pretium quis. Class aptent taciti sociosqu.">
<button class="innerBtn">CLICK ME</button>
</span>
<div class="diamondAnimate"></div>
</div>
<div class="main main3">
<div class="test"></div>
<div class="diamondStatic"></div>
<span class="background" data-title="Managed Services" data-text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla eget erat maximus, mattis ex sed, aliquet arcu. Maecenas eleifend ornare nulla, id placerat turpis pretium quis. Class aptent taciti sociosqu.">
<button class="innerBtn">CLICK ME</button>
</span>
<div class="diamondAnimate"></div>
</div>
</div>
I'm writing a website for a restaurant (Not commercially) and need to know why there's so much whitespace to the right side of the page? Take a look
.top-container{
background-color: white;
background-image: url("images/charmlogoTrans.png");
padding: 170px;
text-align: center;
background-position: center;
background-repeat: no-repeat;
background-size:contain;
position: relative;
max-width: 100%;
}
.menuBar{
background-color: rgb(168, 123, 81);
padding: 30px 40px;
text-align: left;
z-index: 3;
}
.content{
padding:16px;
background-color:rgba(230,199,177,255);
margin-left: 2%;
margin-right: 50%;
margin-top: 2%;
border-radius:4px;
position: relative;
z-index: 1;
}
.imgContent{
position: absolute;
z-index: 2;
left: 50%;
width: 100%;
height:auto;
}
.exampleImg{
width: 32%;
height:auto;
}
.sticky {
position: fixed;
top: 0;
width: 100%;
}
.sticky + .content {
padding-top: 102px;
}
<body>
<div class="top-container"></div>
<div class="menuBar" id="menuBar"> The sticky bar</div>
<div class="mainContent">
<div class="imgContent">
<img class="exampleImg" src="Images/example.png" width="300" height="200">
</div>
<div class="content">
<h3>Vestibulum nulla turpis, hendrerit nec sodales vitae, congue at felis. Cras auctor ac quam sed
fermentum. Quisque libero est, aliquam ac lorem a, semper molestie mi. Cras suscipit eu erat eget
hendrerit.
</h3>
</div>
<img src="Images/example.png" width="300" height="200">
<img src="Images/example.png" width="300" height="200">
</div>
</body>
Please excuse me for such messy code, I'm still learning how to do some things. The measurements I'm still working on a bit, but any help is appreciated! If there's anything I've missed, or need to include, please let me know.
That's because imgContent is taking position: absolute, left: 50% so the element will overflow the page because you also set the width of imgContent to 100% there's 3 ways to fix this
set witdth to less than 100% something like 45% is enough
set Left to 0;
use flex box instead that's will be better in fact
Welcome to SO,
Try this!
It seems that the 50% left was adding the whitespace!
body {
margin: 0;
overflow-x: hidden;
width: 100vw
}
.top-container {
background-color: white;
background-image: url("images/charmlogoTrans.png");
padding: 170px;
text-align: center;
background-position: center;
background-repeat: no-repeat;
background-size: contain;
position: relative;
max-width: 100vw;
}
.menuBar {
background-color: rgb(168, 123, 81);
padding: 30px 40px;
text-align: left;
z-index: 3;
}
.content {
padding: 16px;
background-color: rgba(230, 199, 177, 255);
margin-left: 2%;
margin-right: 50%;
margin-top: 2%;
border-radius: 4px;
position: relative;
z-index: 1;
}
.imgContent {
position: relative;
z-index: 2;
width: 100vw;
height: auto;
}
.exampleImg {
width: 32vw;
height: auto;
}
.sticky {
position: fixed;
top: 0;
width: 100vw;
}
.sticky+.content {
padding-top: 102px;
}
<body>
<div class="top-container"></div>
<div class="menuBar" id="menuBar"> The sticky bar</div>
<div class="mainContent">
<<div class="imgContent">
<img class="exampleImg" src="Images/example.png" width="300" height="200">
</div>
<div class="content">
<h3>Vestibulum nulla turpis, hendrerit nec sodales vitae, congue at felis. Cras auctor ac quam sed fermentum. Quisque libero est, aliquam ac lorem a, semper molestie mi. Cras suscipit eu erat eget hendrerit.
</h3>
</div>
<img src="Images/example.png" width="300" height="200">
<img src="Images/example.png" width="300" height="200">
</div>
</body>
I have a image that I would like to shrink in a flexbox column layout. I have read a bunch of pertinent threads but I still can't figure it out.
I want the right column to always have the same height of the left column and the image in the right column to fill the height of the remaining space not taken up by the text. Any thoughts? Thank you!
I would like it to look like this:
Codepen here: https://codepen.io/interzonestudio/pen/qBRPxzg
This is my HTML:
<div class="block-one">
<div class="block-one-left">
<img src="https://via.placeholder.com/300x400" alt="">
</div>
<div class="block-one-right">
<div class="block-one-right-top">
<img src="https://via.placeholder.com/300x400?text=Shrink+Me!" alt="">
</div>
<div class="block-one-right-bottom">
<p>Lorem ipsum dolor sit amet, consectetuer diiscing elit, sed diam nonummy nibh dolor it euismod tincidunt ut laoreet dolore.</p>
</div>
</div>
</div>
and this is my CSS:
.block-one {
width: 50%;
padding: 50px;
background: #9ac1e4;
margin: 0 50px 100px 50px;
display: flex;
min-height: 0;
min-width: 0;
max-width: 100%;
max-height: 100%;
}
.block-one-left {
width: 40%;
padding-right: 50px;
}
.block-one-left img {
width: 100%;
}
.block-one-right {
width: 60%;
display: flex;
flex: 1;
flex-direction: column;
}
.block-one-right-top {
height: 100%;
flex: 1;
}
.block-one-right-top img {
height: 100%;
max-width: 100%;
max-height: 100%;
min-height: 0;
min-width: 0;
width: auto;
object-fit: contain;
}
You can achieve this with a tiny piece of javascript to calculate the difference of left img height minus text height and set the right image height to that difference. Just place these 4 lines javascript in a <script></script>-tag just before the closing body tag.
Working example:
var max_height = document.querySelector('.block-one-left').clientHeight;
var text_height = document.querySelector('.block-one-right-bottom').clientHeight;
var shrink_height = max_height - text_height;
document.querySelector('.block-one-right-top').style.height = shrink_height + 'px';
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.block-one {
display: flex;
width: 600px;
margin: 0 50px 100px 50px;
padding: 25px;
background: #9ac1e4;
}
.block-one-left {
height: 300px;
margin-right: 25px;
}
.block-one-left img {
height: 100%;
}
.block-one-right {
width: 225px;
}
.block-one-right-top img {
height: 100%;
}
.block-one-right-bottom {
padding-top: 25px;
}
<div class="block-one">
<div class="block-one-left">
<img src="https://via.placeholder.com/300x400" alt="">
</div>
<div class="block-one-right">
<div class="block-one-right-top">
<img src="https://via.placeholder.com/300x400?text=Shrink+Me!" alt="">
</div>
<div class="block-one-right-bottom">
<p>Lorem ipsum dolor sit amet, consectetuer diiscing elit, sed diam nonummy nibh dolor it euismod tincidunt ut laoreet dolore.</p>
</div>
</div>
</div>
If you want it to be responsive you have to wrap the 4 lines in a function. Because you have to listen for at least two events (image loaded and window resized) it is much cleaner to call the function instead of having the 4 lines twice in your code.
Working example:
var left_img = document.querySelector('.block-one-left img');
function setHeight() {
var max_height = left_img.clientHeight;
var text_height = document.querySelector('.block-one-right-bottom').clientHeight;
var shrink_height = max_height - text_height;
document.querySelector('.block-one-right-top').style.height = shrink_height + 'px';
}
left_img.addEventListener('load', setHeight);
window.addEventListener('resize', setHeight);
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.block-one {
display: flex;
width: 100%;
padding: 25px;
background: #9ac1e4;
}
.block-one-left {
width: 40%;
margin-right: 25px;
}
.block-one-left img {
width: 100%;
}
.block-one-right {
width: 50%;
}
.block-one-right-top img {
height: 100%;
}
.block-one-right-bottom {
padding-top: 25px;
}
<div class="block-one">
<div class="block-one-left">
<img src="https://via.placeholder.com/300x400" alt="">
</div>
<div class="block-one-right">
<div class="block-one-right-top">
<img src="https://via.placeholder.com/300x400?text=Shrink+Me!" alt="">
</div>
<div class="block-one-right-bottom">
<p>Lorem ipsum dolor sit amet, consectetuer diiscing elit, sed diam nonummy nibh dolor it euismod tincidunt ut laoreet dolore.</p>
</div>
</div>
</div>
I'm working on the sidebar where we have a logo at the top and some bottom div. The middle div "content" has overflow: scroll and contains paragraph(s). So what I need... If I have only one paragraph (or two p) the button div should be positioned absolutely at the bottom of the content and if I have more paragraphs which have a bigger height than "content" div so then the button div will have position static (so will be scrollable).
And I need it only by CSS. Is it possible?
We need IE11+ support.
<div class="sidebar">
<div class="logo">logo</div>
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam tempor egestas ornare. Suspendisse potenti. Integer non euismod nulla. Quisque pretium est sit amet congue rhoncus.</p>
<div class="button">
Button
</div>
</div>
<div class="bottom"></div>
</div>
.sidebar {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 300px;
background-color: grey;
}
.logo {
position: absolute;
width: 100%;
height: 55px;
background-color: red;
}
.bottom {
position: absolute;
bottom: 0;
width: 100%;
height: 100px;
background-color: green;
}
.content {
position: absolute;
top: 55px;
bottom: 100px;
overflow-y: scroll;
}
.button {
display: inline-block;
padding: 1em 0 1em;
text-align: center;
width: 100%;
border-radius: 50px;
background-color: white;
}
You can use flexbox. Add this to your CSS:
.content {
display:flex;
flex-wrap: wrap;
}
.button {
align-self: flex-end;
}
That will render the button always at the end of the content div.
I have dealt with this problem for some days now and it's making me crazy, I want the text inside the circle to move in the same position inside the cirkle div when I make the screen smaller, as illustrated in the picture.
If you have any tips please share!
CSS Code and Html Code:
.circleBase {
border-radius: 50%;
}
.contact-circle {
margin-top: 29%;
margin-left: 4%;
position: fixed;
width: 23%;
height: auto;
padding-top: 23%;
background-color: rgba(255, 86, 86, 0.2);
}
#contact-text {
top: 20%;
bottom: 20%;
left: 18%;
font-size: auto;
position: absolute;
text-align: center;
width: 60%;
opacity: 1;
}
<div class="circleBase contact-circle">
<div id="contact-text">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit,
</p>
</div>
</div>
Use another method to center the text. Here is an idea with flex:
.circleBase {
border-radius: 50%;
}
.contact-circle {
position: fixed;
width: 23%;
height: auto;
padding-top: 23%;
background-color: rgba(255, 86, 86, 0.2);
}
#contact-text {
top: 0;
position: absolute;
bottom: 0;
left: 10%;
right: 10%;
display: inline-flex;
justify-content: center;
align-items: center;
text-align: center
}
<div class="circleBase contact-circle">
<div id="contact-text">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit,
</p>
</div>
</div>
Responsive web site - #media (min-width:450px) and (max-width:900px) { css style }
<div class="circleBase contact-circle">
<div id="contact-text">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit</p>
</div>
</div>
Css #media Example
.circleBase {
height:800px;
width:800px;
}
#media (max-width:479px) {
.circleBase {
height: 400px;
width:400px;
}
}