How can I make flexbox overlay with object-fit working properly - css

This may be a begginer question, but I just can't seem to figure it out.
HTML:
<div id = "upper">
<input id = "leftBigArrow" class = "button" type="button">
<div id = "picBox">
<img id = "bigPic" src="images/IMG_1744.JPG" alt="">
<div id = "overlay">
<div id = "olText">
<h1>Title</h1>
<p>Description</p>
</div>
</div>
</div>
<input id = "rightBigArrow" class = "button" type="button">
</div>
CSS:
#upper {
display: flex;
background: white;
box-shadow: 0px 0px 7px 2px #313131;
}
#picBox {
width: 800px;
height: 600px;
background-color: #8D918D;
display: flex;
}
#pigPic {
object-fit: contain;
object-position: center;
z-index: 1;
}
#overlay {
align-self: flex-end;
width: 100%;
height: 20%;
background-color: black;
color: white;
opacity: 0.6;
margin: 0;
font-size: 80%;
z-index: 2;
}
#olText {
display: flex;
width: 100%;
height: 100%;
flex-direction: column;
justify-content: center;
}
h1, p {
margin-left: 20px;
}
h1 {
margin-top: 0;
margin-bottom: 10px;
}
p {
margin-top: 0;
margin-bottom: 0;
}
In #picBox I have 2 items, an image (#bigPic) with object-fit attribute and a div with a div with 2 text items (#overlay). I want to have the overlay over the image. Overlay height is 20% at the bottom of #picBox and the 2 text items in #olText need to be arranged as css shows. If I use position absolute and relative, it messes up the object-fit. So how can I make this work as I intended?

In CSS, if you want to overlay an element, that element's position (in this case #picBox) needs to be set to relative first. Then the position of the element you want on top (#overlay) should be set to absolute. See the example below.
#upper {
display: flex;
background: white;
box-shadow: 0px 0px 7px 2px #313131;
}
#picBox {
width: 800px;
height: 600px;
background-color: #8D918D;
display: flex;
position: relative;
}
#pigPic {
object-fit: contain;
object-position: center;
z-index: 1;
}
#overlay {
align-self: flex-end;
width: 100%;
height: 20%;
background-color: black;
color: white;
opacity: 0.6;
margin: 0;
font-size: 80%;
z-index: 2;
position: absolute;
}
#olText {
display: flex;
width: 100%;
height: 100%;
flex-direction: column;
justify-content: center;
}
h1,
p {
margin-left: 20px;
}
h1 {
margin-top: 0;
margin-bottom: 10px;
}
p {
margin-top: 0;
margin-bottom: 0;
}
<div id="upper">
<input id="leftBigArrow" class="button" type="button">
<div id="picBox">
<img id="bigPic" src="https://www.w3schools.com/tags/img_pink_flowers.jpg" alt="">
<div id="overlay">
<div id="olText">
<h1>Title</h1>
<p>Description</p>
</div>
</div>
</div>
<input id="rightBigArrow" class="button" type="button">
</div>

Related

Overlay for a grid item

I am using React and I am trying to have an overlay over each grid item in a grid. But, what all I try, the overlay seems to come below each grid item and not over the grid item. Even if I use the position: absolute it is not working !
Here's the code I am using for the grid (React):
<div className="home__itemSection">
<div className="item">
<div className="item__container">
<div className="container__imageDiv">
<img
src={""}
alt=""
/>
</div>
<div className="container__detailSection">
<p>{""}</p>
<h6>{""}</h6>
</div>
</div>
<div className="item__overlay">
<h1>{""}</h1>
<h1>{""}</h1>
</div>
</div>
</div>
css:
.home__itemSection {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
margin: 30px 170px 0 170px;
transition: ease all 0.5s;
}
.item {
background-color: #f1f1f1;
height: 350px;
width: 212px;
margin: 0 3rem 1rem 3rem;
height: fit-content;
font-family: "Poppins", sans-serif;
display: flex;
align-items: flex-start;
}
.container__imageDiv {
height: 318px;
width: 212px;
}
.container__imageDiv > img {
height: 318px;
width: 212px;
}
.container__detailSection {
height: 44px;
width: 212px;
display: flex;
flex-direction: column;
align-items: flex-start;
padding-top: 5px;
}
.container__detailSection > p {
color: black;
font-size: 13px;
font-weight: 300;
line-height: initial;
}
.container__detailSection > h6 {
padding-left: 1.8rem;
font-weight: 500;
font-size: 1rem;
}
.item__overlay {
height: 252px;
width: 212px;
background-color: black;
}
Any help is greatly appreciated !
Thank You !
Please add position: relative; on item(parent tag of overlay)
.item{
position: relative;
}
.item .item__overlay{
position: absolute;
left: 0;
top: 0;
}
An element with position absolute is relative to the next parent element with relative (or absolute) positioning.
Add position relative to home__itemSection. Also use height and with to cover all the container:
.home__itemSection {
...
position: relative;
}
.item__overlay {
...
position: absolute;
height: 100%;
width: 100%;
}

how can i fit image to square and center it vertically and horizontally [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
Did try already several flex arguments but none of them worked like selg-align and self-content.
So the idea is the fit the image to the square and center it vertically and horizontally...
Does anybody can help with this thanks...
I am unsure of the why i need to edit this topic... it's just a simple question on how to fit the image in the square and center it vertically and horizontally (obvious to such square)... Don't understand where is the confusion about the question...
My examples is at https://jsfiddle.net/ej3814sn/
.five {
height: 20%;
border: 1px solid #fff;
}
.five-a {
float: left;
color: white;
}
.five-b {
float: right;
color: white;
}
Thanks in advance
You need to wrap your img in a div and outside of five - Using float is not a good idea at all in modern browsers.
Use flex to achieve your desired results and it is very responsive in modern browsers as well. Also set the height of .one to auto make sure img always centered and below the numbers.
Live Demo:
#import url('https://fonts.googleapis.com/css2?family=Montserrat:wght#400;500;600&display=swap');
* {
font-family: 'Montserrat', sans-serif;
}
html,
body {
height: 100%;
width: 100%;
}
body {
display: flex;
align-items: center;
justify-content: center;
}
.one {
width: 80%;
height: 80%;
display: flex;
flex-direction: row;
background: #232323;
opacity: 0.9;
}
.two {
width: 50%;
}
.four {
width: 100px;
height: auto;
margin-left: 10px;
margin-top: 10px;
border: 2px solid #fff;
display: flex;
flex-direction: column;
}
.five {
height: 20%;
display: flex;
justify-content: space-between;
}
.five-a {
color: white;
margin-left: 5px;
}
.five-b {
color: white;
margin-right: 5px;
}
img {
width: 90%;
height: auto;
}
.img-div {
display: flex;
justify-content: center;
align-items: center;
}
/*fit image to the square and center it*/
<body>
<div class="one">
<div class="two">
<div id="tree">
<div id="0" class="four">
<div class="five">
<div class="five-a">1</div>
<div class="five-b">10</div>
</div>
<div class="img-div">
<img src="https://logodownload.org/wp-content/uploads/2015/04/whatsapp-logo-1-1.png">
</div>
</div>
</div>
</div>
</div>
</body>
The best way, to position elements, is to use position property. Notice that I have made a change in HTML code as well. Put the image out of five element. Now talking about CSS, position both img and five as absolute. You would have to set top to 0, width to 100% for five. And for img, just set self-align to center.
#import url('https://fonts.googleapis.com/css2?family=Montserrat:wght#400;500;600&display=swap');
* {
font-family: 'Montserrat', sans-serif;
}
html,
body {
height: 100%;
width: 100%;
}
body {
display: flex;
align-items: center;
justify-content: center;
}
.one {
width: 80%;
height: 80%;
display: flex;
flex-direction: row;
background: #232323;
opacity: 0.9;
}
.two {
width: 50%;
}
.four {
float: left;
width: 100px;
height: 100px;
margin-left: 10px;
justify-content: center;
margin-top: 10px;
border: 2px solid #fff;
display: flex;
flex-direction: column;
position: relative;
}
.five {
height: 20%;
width: 100%;
position: absolute;
top: 0;
}
.five-a {
float: left;
color: white;
margin-left: 5px;
}
.five-b {
float: right;
color: white;
margin-right: 5px;
}
img {
width: 90%;
position: absolute;
height: auto;
align-self: center;
}
/*fit image to the square and center it*/
<body>
<div class="one">
<div class="two">
<div id="tree">
<div id="0" class="four">
<div class="five">
<div class="five-a">1</div>
<div class="five-b">10</div>
</div>
<img src="https://logodownload.org/wp-content/uploads/2015/04/whatsapp-logo-1-1.png">
</div>
</div>
</div>
</div>
</body>
I think you are looking to center the image in the .five div, yes?
EDIT: Remove the image tag and place your image as a background of the element you wish to center it in... Then add no-repeat, 0% to position and set the bg size to 100%, however change the height of the element to 100% as well...
.five {
height: 100%;
background-image: url(https://logodownload.org/wp-content/uploads/2015/04/whatsapp-logo-1-1.png);
background-repeat: no-repeat;
background-position: 0% 0%;
background-size: 100%;
}
#import url('https://fonts.googleapis.com/css2?family=Montserrat:wght#400;500;600&display=swap');
* {
font-family: 'Montserrat', sans-serif;
}
html,
body {
height: 100%;
width: 100%;
}
body {
display: flex;
align-items: center;
justify-content: center;
}
.one {
width: 80%;
height: 80%;
display: flex;
flex-direction: row;
background: #232323;
opacity: 0.9;
}
.two {
width: 50%;
}
.four {
float: left;
width: 100px;
height: 100px;
margin-left: 10px;
margin-top: 10px;
border: 2px solid #fff;
display: flex;
flex-direction: column;
}
.five {
height: 100%;
background-image: url(https://logodownload.org/wp-content/uploads/2015/04/whatsapp-logo-1-1.png);
background-repeat: no-repeat;
background-position: 0% 0%;
background-size: 100%;
}
.five-a {
float: left;
color: white;
margin-left: 5px;
}
.five-b {
float: right;
color: white;
margin-right: 5px;
}
/*fit image to the square and center it*/
<div class="one">
<div class="two">
<div id="tree">
<div id="0" class="four">
<div class="five">
<span class="five-a">1</span>
<span class="five-b">10</span>
<img src="">
</div>
</div>
</div>
</div>
</div>

Keep the whole page (the horizonal scrollbar position) center when zooming in

I know how to keep elements center but now I want the whole page center (i.e. the horizonal scrollbar should be in the middle) when zooming in. Now the scrollbar is at the very left end when zooming in.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
width: 100%;
height: 100%;
margin: 0 auto;
}
#p {
width: 100%;
display: flex;
justify-content: space-around;
align-items: center;
}
.c1,
.c2,
.c3 {
margin: 1rem;
min-width: 15rem;
height: 5rem;
text-align: center;
}
.c1 {
background-color: red;
}
.c2 {
background-color: green;
}
.c3 {
background-color: blue;
}
<div id="p">
<div class="c1">
aaa
</div>
<div class="c2">
bbb
</div>
<div class="c3">
ccc
</div>
</div>
You can see when it zooms in to a certain level the red div will be out of the view and cannot be reached.
This impossible with only CSS. You can consider using Javascript.
const container = document.querySelector("#p");
const centerEl = document.querySelector(".center-element");
container.scrollLeft = centerEl.offsetLeft + centerEl.offsetWidth / 2 - container.offsetWidth / 2;
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
width: 100%;
height: 100%;
margin: 0 auto;
}
#p {
width: 100%;
display: flex;
/* removed:
justify-content: space-around;
align-items: center;
*/
overflow-x: scroll; /* added. so that it does not affect the whole page. */
}
.c1,
.c2,
.c3 {
margin: 1rem;
min-width: 15rem;
height: 5rem;
text-align: center;
}
.c1 {
background-color: red;
}
.c2 {
background-color: green;
}
.c3 {
background-color: blue;
}
<div id="p">
<div class="c1">
aaa
</div>
<div class="c2 center-element">
bbb
</div>
<div class="c3">
ccc
</div>
</div>

Overlay on a flexbox while keeping responsivness

With the below code, I am trying to make an overlay for a "progress bar" with text, I need the flex to make it responsive,
BUT the only way I know to make an overlay is to use things like fixed or absolute position, which breaks the layout, is there a way to keep it responsive and have an overlay with dynamic width (for displaying progress).
.master{
display: flex;
}
.item{
border-right: 1px solid black;
padding-right: 5px;
display: inline-block;
text-align: center;
padding: 15px 0;
flex-grow: 1;
flex-basis: 0;
}
<div style='border:1px solid black;margin: 0 auto;'>
<div class='master'>
<span class="item">a</span>
<span class="item">b</span>
<span class="item">c</span>
</div>
<div id='overlay' style='background-color:red;opacity:0.7;width:100%;height:100%;'></div>
</div>
Absolute position will not break the layout...assuming you have set the positioning context on the parent?
.parent {
position: relative;
}
.master {
display: flex;
}
.item {
border-right: 1px solid black;
padding-right: 5px;
display: inline-block;
text-align: center;
padding: 15px 0;
flex-grow: 1;
flex-basis: 0;
}
#overlay {
position: absolute;
background-color: red;
opacity: 0.7;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
<div class="parent">
<div class="master">
<span class="item">a</span>
<span class="item">b</span>
<span class="item">c</span>
</div>
<div id="overlay"></div>
</div>

keep the first element vertically centered with the next elements following below

I have three elements currently vertically centered in a container through flex:
<div class="parent">
<div class="first">A</div>
<div class="second">B</div>
<div class="third">C</div>
</div>
with CSS:
.parent {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 800px;
}
Looking like:
I would like to change it so the first element is vertically centered and the other elements follow:
Ideally this could be done simply through flex but so far I cannot find a solution. Any help greatly appreciated.
If your elements have a fixed size, you could accomplish this with a wrapping div
which size is the same as the first element and let the following elements just overflow.
.parent {
height: 125px;
background-color: palegreen;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.item-container,
.item {
width: 200px;
height: 30px;
}
.item {
display: flex;
justify-content: center;
align-items: center;
border: 1px solid red;
}
.second {
height: 50px;
}
<div class="parent">
<div class="item-container">
<div class="item first">A</div>
<div class="item second">B</div>
<div class="item third">C</div>
</div>
</div>
If you can change the HTML structure, it's possible: Put the second and third elements into a wrapper DIV and put that one into the first. Then center the first one (not necessarily with flex - see below) and apply position: relative to it, and apply position: absolute and according position settings to the wrapper. For details see the snippet below.
.parent {
height: 500px;
border: 1px solid blue;
}
.first {
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
height: 100px;
width: 300px;
background: #ccc;
}
.wrap1 {
position: absolute;
top: 100%;
width: 100%;
height: auto;
border: 1px solid green;
}
.second {
background: #eee;
height: 50px;
}
.third {
background: #aaa;
height: 80px;
}
<div class="parent">
<div class="first">A
<div class="wrap1">
<div class="second">B</div>
<div class="third">C</div>
</div>
</div>
</div>
ADDITION: Actually it's also possible with flex:
.parent {
height: 500px;
border: 1px solid blue;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.first {
position:relative;
height: 100px;
width: 300px;
background: #ccc;
}
.wrap1 {
position: absolute;
top: 100%;
width: 100%;
height: auto;
border: 1px solid green;
}
.second {
background: #eee;
height: 50px;
}
.third {
background: #aaa;
height: 80px;
}
<div class="parent">
<div class="first">A
<div class="wrap1">
<div class="second">B</div>
<div class="third">C</div>
</div>
</div>
</div>

Resources