I have a background image which has on top another div containing some elements.
I success to add the white-container on top of the background div using grid-template-area.
I try to do the same thing only using grid and not position. But text hello world doesn't go on top of love icon using grid area love-svg.
I think perhaps because img tag has no closed tag, but can't find a way to solve this problem.
HTML
<div class="container">
<img src="/images/site/trust_pilot_bg_mb.jpg" >
<div class="white-container">
<div class="love-section">
<img class="love-ico" src="/images/site/love_svg_icon.svg"><h2 class="hello">Hello world</h2> </img>
</div>
</div>
</div>
SCSS
.container {
display: grid;
justify-items: center;
grid-template-areas: "content-wrapper";
&>* {
grid-area: content-wrapper;
}
img {
width: 100%;
}
.love-section
{
display: grid;
background-color: white;
top: 40px;
position: relative;
}
.love-ico {
width: 100px;
grid-template-areas: "love-svg";
}
.hello {
color: red;
grid-area: love-svg;
}
}
In blue this is what I want to achieve. Please note that I want the text to be on top of the love logo but allow it to be bigger than it.
if you want to use grid to do that, you'll need to play with the align-self, and justify-self for the grid-item.
Now there are several ways to do that with grid, the way you are using it is not the simplest.
I'm proposing just one here:
html,
body {
margin: 0;
padding: 0;
}
#grid {
display: grid;
grid-template-rows: repeat(7, 1fr);
grid-template-columns: repeat(7, 1fr);
gap: 0;
width: 100vw;
min-height: 100vh;
}
#div1 {
grid-area: 1 / 1 / 8 / 8;
}
#div1 img,
#div2 img {
width: 100%;
height: 100%
}
#div2 {
grid-area: 3 / 3 / 6 / 6;
}
#div3 {
grid-area: 4 / 4 / 5 / 5;
align-self: center;
justify-self: center;
}
<div id="grid">
<div id="div1">
<img src="https://picsum.photos/300/200">
</div>
<div id="div2">
<img class="love-ico" src="https://picsum.photos/300/200">
</div>
<div id="div3">
<h2>Hello world</h2>
</div>
</div>
Now I don't know if it's mandatory for you to use grid, otherwise the old technic of relative, absolute works too:
html,
body {
margin: 0;
padding: 0;
}
#container {
position: relative;
background-image: url("https://picsum.photos/300/200");
width: 100vw;
height: 100vh;
}
#container img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
#container h2 {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<div id="container">
<img class="love-ico" src="https://picsum.photos/300/200">
<h2>Hello world</h2>
</div>
Related
I'm trying to put text on top of two images that are side by side and together fill out the entire site. Here is the code:
HTML:
<div class="main">
<img src="city.jpg" class="city" alt="city">
<img src="couple.jpg" class="couple" alt="couple">
</div>
CSS:
.main {
display: flex;
justify-content: space-between;
width: 100%;
height: 152.5vh;
}
.city {
flex-basis: 50%;
height: 100%;
object-fit: cover;
display: block;
}
.couple {
flex-basis: 50%;
height: 100%;
object-fit: cover;
display: block;
}
Both of the images are side by side without any space in between. I want to add text to the middle of the side so sort of on top of both images. What could I try to do?
I have looked online to find a solution but nothing worked or was simply too hard to understand and to implement. Thank you in advance!
personally I wouldn't do that with flex but with grid
Simple grid 2rows, 2 cols.
text div take 2 cells of first row, and image on second row, each in 1 cell
body {
margin: 0;
padding: 0;
}
.main {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: auto 1fr;
max-width: 100%;
height: 152.5vh;
}
.text {
grid-area: 1 / 1 / 2 / 3;
align-self: center;
justify-self: center;
color: #222222;
}
.city {
grid-area: 2 / 1 / 3 / 2;
width: 100%;
height: 100%;
}
.couple {
grid-area: 2 / 2 / 3 / 3;
width: 100%;
height: 100%;
}
.city img,
.couple img {
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="main">
<div class="text">
1 title for 2 image
</div>
<div class="city">
<img src="https://picsum.photos/id/237/800/600" alt="city">
</div>
<div class="couple">
<img src="https://picsum.photos/id/85/800/600" alt="couple">
</div>
</div>
so to answer your latest comment "thats right. over the two images on the center"
we still can use grid for images, in add here I put the grid in position relative, and the text in absolute. You can play with top value.
body {
margin: 0;
padding: 0;
}
.main {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr;
max-width: 100%;
height: 152.5vh;
position: relative;
}
.text {
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
color: #222222;
}
.city {
grid-area: 1 / 1 / 2 / 2;
width: 100%;
height: 100%;
}
.couple {
grid-area: 1 / 2 / 2 / 3;
width: 100%;
height: 100%;
}
.city img,
.couple img {
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="main">
<div class="text">
1 title for 2 image
</div>
<div class="city">
<img src="https://picsum.photos/id/237/800/600" alt="city">
</div>
<div class="couple">
<img src="https://picsum.photos/id/85/800/600" alt="couple">
</div>
</div>
I got 2 columns grid with following layout:
My issue is that when I use images inside the right column (1 image inside each box)..Images overflow and whole grid kind of acts weird.
It looks something like this:
Codepen Link: https://codepen.io/kazmi066/pen/MWXGgaL?editors=1100
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.grid {
background: green;
width: 100%;
max-height: 70vh;
display: grid;
gap: 20px;
grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
}
.col1 {
height: 100%;
background: red;
}
.col2 {
height: 100%;
background: orange;
}
.box1 {
width: 100%;
height: 50%;
border: 1px solid black;
}
.box2 {
width: 100%;
height: 50%;
border: 1px solid blue;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="grid">
<div class="col1"></div>
<div class="col2">
<div class="box1"><img src="https://images.unsplash.com/photo-1600585154340-be6161a56a0c?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8N3x8fGVufDB8fHx8&w=1000&q=80" alt="property"/></div>
<div class="box2"><img src="https://images.unsplash.com/photo-1600585154340-be6161a56a0c?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8N3x8fGVufDB8fHx8&w=1000&q=80" alt="property" /></div>
</div>
</div>
I want the images to adjust inside the boxes perfectly without the need of custom height and width so that any size of image can work in this scenario.
fit would be object-fit: contain; for the image not cover.
but if the ratio of the image is not the ratio of the box, you'll have blank
you can put the image in background of box1, box2... with a background size cover. It will cover entirely and clipped the overflow. If box ratio "totally" different of the image, lot of image can be clipped, but it's not so often.
I've found a way, only CSS, nothing is changed in your HTML
2 points:
1- it's using clip-path
2- image fill box space, but are clipped otherwise blank space
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.grid {
background: green;
width: 100%;
max-height: 70vh;
display: grid;
gap: 2vh;
grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
grid-template-rows: 100%;
}
.col1 {
background: red;
}
.col2 {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 34vh 34vh;
background: orange;
justify-content: center;
}
.box1 {
width: 100%;
border: 1px solid black;
clip-path: inset(0);
}
.box2 {
width: 100%;
border: 1px solid blue;
clip-path: inset(0);
}
img {
width: 100%;
object-fit: contain;
}
<div class="grid">
<div class="col1"></div>
<div class="col2">
<div class="box1"><img src="https://images.unsplash.com/photo-1600585154340-be6161a56a0c?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8N3x8fGVufDB8fHx8&w=1000&q=80" alt="property" /></div>
<div class="box2"><img src="https://images.unsplash.com/photo-1600585154340-be6161a56a0c?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8N3x8fGVufDB8fHx8&w=1000&q=80" alt="property" /></div>
</div>
</div>
based on your grid max-height in vh, I defined all others same kind of values in vh. Lot more consistent and avoid some little strange pixels or lines here or there depending of window size.
I put a nested grid inside col2 where box1 box2 go. box have a clip-path with inset 0, meaning clipping everything out.
The solution that worked for me:
I used grid-auto-rows to create 2 rows with specific height.
Then added span to adjust the column accordingly to cover both rows.
.grid {
width: 100%;
border: 1px solid red;
display: grid;
gap: 14px;
grid-template-columns: repeat(12, 1fr);
grid-auto-rows: 280px 280px;
}
.col1 {
height: 100%;
grid-column: 1/8;
grid-row: span 2;
background: red;
}
.col2 {
grid-column: 8/13;
height: 100%;
background: orange;
}
.col2 img:first-child {
margin-bottom: 11px;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
#media (max-width: 768px) {
.grid {
grid-auto-rows: 220px 120px;
}
.col1 {
grid-column: 1/13;
}
.col2 {
grid-column: 1/13;
grid-row: span 2;
}
}
<div class="grid">
<div class="col1">
<img src="https://images.unsplash.com/photo-1600585154340-be6161a56a0c?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8N3x8fGVufDB8fHx8&w=1000&q=80" alt="property"/>
</div>
<div class="col2">
<img src="https://images.unsplash.com/photo-1564013799919-ab600027ffc6?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8YmVhdXRpZnVsJTIwaG91c2V8ZW58MHx8MHx8&w=1000&q=80" alt="property"/>
<img src="https://images.pexels.com/photos/186077/pexels-photo-186077.jpeg?cs=srgb&dl=pexels-binyamin-mellish-186077.jpg&fm=jpg" alt="property" />
</div>
</div>
Final output now:
Solution-2: Found Another better solution with Grid-template-areas I guess which looks more cleaner:
.grid {
width: 100%;
border: 1px solid red;
display: grid;
gap: 14px;
grid-template-areas:
"mainImage mainImage otherImage1"
"mainImage mainImage otherImage1"
"mainImage mainImage otherImage2"
"mainImage mainImage otherImage2"
}
.mainImage {
grid-area: mainImage;
}
.otherImage1 {
grid-area: otherImage1;
}
.otherImage2 {
grid-area: otherImage2;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="grid">
<img src="https://images.unsplash.com/photo-1600585154340-be6161a56a0c?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8N3x8fGVufDB8fHx8&w=1000&q=80" alt="property" class="mainImage" />
<img src="https://images.unsplash.com/photo-1564013799919-ab600027ffc6?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8YmVhdXRpZnVsJTIwaG91c2V8ZW58MHx8MHx8&w=1000&q=80" alt="property" class="otherImage1" /> <img src="https://images.pexels.com/photos/186077/pexels-photo-186077.jpeg?cs=srgb&dl=pexels-binyamin-mellish-186077.jpg&fm=jpg" alt="property" class="otherImage2" />
</div>
<h1>something else here</h1>
i need to overlaying div to div like this img the gray div should cover the yellow div in the upper right corner
I tried it like this, but yellow does not get into the position I need
.grid {
display: grid;
/* grid-auto-rows: 100px;
grid-auto-columns: 100px; */
}
.item-1 {
grid-row: 1 / 2;
grid-column: 5 / 4;
}
.item-2 {
grid-row: 2 / 3;
grid-column: 2 / 4;
}
.item-1 img {
width: 200px;
height: 170px;
}
.item-2 img {
width: 368px;
height: 350px;
}
<div class="grid">
<div class="item-1">
<img src="img/square.png" alt="">
</div>
<div class="item-2">
<img src="img/Rectangle 24.png" alt="">
</div>
</div>
You should be able to do this simply by doing this.
Just place the element you want inside the element you want it to overlap, give it a position absolute and just assign the left/right values.
.box1 {
background: yellow;
position: relative;
width: 200px;
height: 200px;
margin: 100px;
}
.box2 {
background: gray;
position: absolute;
width: 200px;
height: 200px;
right: 120px;
top: 120px;
}
<div class="box1">
<div class="box2"></div>
</div>
This question already has an answer here:
Put one div next to two vertical divs
(1 answer)
Closed 1 year ago.
I am looking for the simplest method, to position three images in the following way using CSS and HTML
Image number 2 and 3 should be of 50% width and height of image number 1.
Thank you in advance
You can use a grid to do so
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
width: 100%;
grid-gap: 4px;
}
img {
max-width: 100%;
}
img:first-child {
max-width: unset;
height: 100%;
width: 100%;
object-fit: cover;
grid-row: span 2;
}
<div class="grid">
<img src="https://images.unsplash.com/photo-1618326985678-88285545a9aa?crop=entropy&cs=srgb&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYyMDc5OTgyNA&ixlib=rb-1.2.1&q=85" alt="">
<img src="https://images.unsplash.com/photo-1618326985678-88285545a9aa?crop=entropy&cs=srgb&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYyMDc5OTgyNA&ixlib=rb-1.2.1&q=85" alt="">
<img src="https://images.unsplash.com/photo-1618326985678-88285545a9aa?crop=entropy&cs=srgb&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYyMDc5OTgyNA&ixlib=rb-1.2.1&q=85" alt="">
</div>
.container{
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
height: 100px;
width: 100px;
}
#img1{
grid-row: 1/3;
grid-column: 1/2;
border: red solid 1px;
}
#img2{
border: blue solid 1px;
}
#img3{
border: green solid 1px;
}
<div class="container">
<div id="img1"></div>
<div id="img2"></div>
<div id="img3"></div>
</div>
I would honestly go with Charles Lavalard's grid solution above, but wanted to show a flex solution that takes in that the images may not fit the designated space.
html, body {
margin: 0px;
}
.container {
display: flex; /* display side by side */
align-items: stretch; /* stretches the .right div */
}
.container img {
object-fit: cover; /* clips image if it's too big */
}
.left, .right {
flex: 1 1 auto; /* fills out the width */
flex-basis: 50%;
}
.right {
display: flex;
flex-direction: column;
}
.small {
flex: 1 1 auto; /* fills out the height */
}
<div class="container">
<img class="left large" src="https://picsum.photos/150/300">
<div class="right">
<img class="small" src="https://picsum.photos/300/100">
<img class="small" src="https://picsum.photos/300/100">
</div>
</div>
There are numerous ways to do this, but i think flex box is the right approach if you want to further align the text inside one of the divs.
A simple method will be to use 3 child divs and wrap it around 2 parent divs and finally 1 grandparent div. Use flex box with direction row on the grandparent div content. Then specify on col2 to be flex-direction column.
.content {
display: flex;
flex-direction: row;
}
.col2 {
display: flex;
flex-direction: column;
}
.first {
background-color: red;
height: 100vh;
width: 50vw;
}
.second {
background-color: green;
height: 50vh;
width: 50vw;
}
.third {
background-color: yellow;
height: 50vh;
width: 50vw;
}
<div class="content">
<div class="col1">
<div class="first">lst</div>
</div>
<div class="col2">
<div class="second">2nd</div>
<div class="third">third</div>
</div>
</div>
img {
height:300px;
width:150px;
border:1px solid white
}
.rows {
display:flex;
flex-direction:column;
}
.container {
display:flex;
flex-direction:row;
}
.rows img{
height:150px;
width: 75px;}
<div class="container">
<img src="https://cdn5.vectorstock.com/i/1000x1000/40/49/cityscape-vertical-3-vector-19094049.jpg">
<div class="rows">
<img src="https://cdn5.vectorstock.com/i/1000x1000/40/49/cityscape-vertical-3-vector-19094049.jpg">
<img src="https://cdn5.vectorstock.com/i/1000x1000/40/49/cityscape-vertical-3-vector-19094049.jpg">
</div>
</div>
I have a page designed like this:
main {
display: flex;
}
div {
width: 50px;
height: 50px;
margin: 2px;
text-align: center;
}
.div1 {
background-color: green;
}
.div2 {
background-color: red;
}
<main>
<section>
<div class="div1">A</div>
<div class="div1">B</div>
<div class="div1">C</div>
</section>
<section>
<div class="div2">D</div>
<div class="div2">E</div>
<div class="div2">F</div>
</section>
</main>
I am applying responsiveness. I would like to know if it is possible to use only css to organize the divs this:
The only way I see to achieve the layout with a <section> tag present separating each div1 and div2 would be to use positioning each child elements left and top positions relative to the parent. It is very static and likely has a high potential of breaking with content and scrolling, etc...
Not recommended... see the hidden snippit below to see that working
.main section {
position: relative;
}
.one {
position: absolute;
left: 0;
top: 0;
}
.four {
position: absolute;
left: 55px;
top: 0;
}
.two {
position: absolute;
left: 0;
top: 55px;
}
.three {
position: absolute;
left: 55px;
top: 55px;
}
.five {
position: absolute;
left: 0;
top: 110px;
width: 210%;
overflow: auto;
}
.six {
position: absolute;
left: 0;
top: 165px;
width: 210%;
overflow: auto;
}
div {
width: 50px;
height: 50px;
margin: 2px;
text-align: center;
}
.div1 {
background-color: green;
}
.div2 {
background-color: red;
}
<div class="main">
<section>
<div class="div1 one">1</div>
<div class="div1 two">2</div>
<div class="div1 three">3</div>
</section>
<section>
<div class="div2 four">4</div>
<div class="div2 five">5</div>
<div class="div2 six">6</div>
</section>
</div>
A more cohesive approach would be to get rid of the <section> tags and use a grid layout...
You still have the classes div1 and div2 for alternate styling. Using the grid layout you can create a grid-template-area using the grid-area on individual class names for each element.
While you still have your child elements laid out incrementally one, two, three, four, etc... You can move a child element anywhere in the grid pattern using the grid-template-area calling on the elements grid-area value.
In the following example, each div has a class representing its position in the original layout, one, two, three, etc...
Note the column and row fr units... very literal in its approach. Visualize two columns each separated equally per column, then four rows, each separated equally per row, then we add the elements with the grid-template-area...
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr 1fr;
grid-template-area:
"one four"
"two three"
"five five"
"six six";
}
html {
--width: 100%;
--height: 100%;
}
#main {
display: flex;
justify-content: center;
}
div {
display: flex;
align-items: center;
justify-content: center;
}
.grid-container {
height: 400px;
width: 200px;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr 1fr;
grid-gap: 2px 2px;
grid-template-areas: "one four" "two three" "five five" "six six";
}
.one {
grid-area: one;
width: var(--width);
height: var(--height);
}
.two {
grid-area: two;
width: var(--width);
height: var(--height);
}
.three {
grid-area: three;
width: var(--width);
height: var(--height);
}
.four {
grid-area: four;
width: var(--width);
height: var(--height);
}
.five {
grid-area: five;
width: var(--width);
height: var(--height);
}
.six {
grid-area: six;
width: var(--width);
height: var(--height);
}
.div1 {
background-color: green;
}
.div2 {
background-color: red;
}
<div id="main">
<div class="grid-container">
<div class="div1 one box">A</div>
<div class="div1 two box">B</div>
<div class="div1 three box">C</div>
<div class="div2 four box">D</div>
<div class="div2 five box">E</div>
<div class="div2 six box">F</div>
</div>
</div>
yes you could by using orders like this .div1 {order: __}