I am having trouble laying out my items in a gallery. I would like to be able to display an image in a horizontal or vertical format and have it fit within a fixed 300px x 300px box and align to the bottom of the box. I would like the "attribution" to line up with the right edge of the image. Here is a picture of the desired layout.
Picture of desired layout
This is the html:
.gallery {
display:flex;
gap: 10px;
}
.gallery_item_square {
height: 450px;
width: 300px;
background: brown;
}
.gallery_square {
height: 300px;
display: flex;
background: green;
}
.gallery_description {
height:auto;
width:100%;
}
.image_attribution {
display:flex;
flex-direction:column;
align-items:flex-end;
}
.image_square {
width: 100%;
height: 100%;
background: black;
display:flex;
flex-direction:column;
align-items:flex-end;
}
.gallery_attribution {
width: 100%;
background: orange;
display: flex;
}
.image {
height:100%;
background: green;
width:
}
.image_contain {
width: 100%;
height: 100%;
object-fit:contain;
object-position: bottom;
}
.attribution {
float:right;
}
<div class="gallery">
<div class="gallery_item_square">
<div class="gallery_square">
<div class="image_attribution">
<div class="image_square">
<div class="image">
<img class="image_contain" src="https://acrossky.github.io/Images/3W6A8814.jpg">
<span class="attribution"> ARC/Qedema</span>
</div>
</div>
</div>
</div>
<div class="gallery_description">
<p>This is a description</p>
</div>
</div>
<div class="gallery_item_square">
<div class="gallery_square">
<div class="image_attribution">
<div class="image_square">
<div class="image">
<img class="image_contain" src="https://acrossky.github.io/Images/3W6A8817.jpg">
<span class="attribution"> ARC/Qedema</span>
</div>
</div>
</div>
</div>
<div class="gallery_description">
<p>This is a description</p>
</div>
</div>
</div>
I am unable to make the image fit within the box. Ive tried use "object-fit:contain" but to no avail. I would be grateful for any help you can offer.
Update: the code is almost working. The last item is to make the attribution align with edge of the image. align attribution to edge of image Here is the latest version of the code in Codepen.
https://codepen.io/acrossky/pen/KKoNdPX
Maybe something like this:
.gallery {
display: flex;
gap: 10px;
}
.gallery_item_square {
height: 450px;
width: 300px;
background: brown;
}
.gallery_square {
height: 300px;
width: 100%;
display: flex;
justify-content: center;
background: green;
}
.gallery_description {
width: 100%;
height: auto;
}
.image_attribution {
display: flex;
flex-direction: column;
align-items: flex-end;
}
.image_square {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: flex-end;
}
.gallery_attribution {
width: 100%;
background: orange;
display: flex;
justify-content: center;
}
.image {
height: 100%;
width: 100%;
}
.image_contain {
width: 100%;
height: 100%;
object-fit: contain;
object-position: bottom;
}
.attribution {
display: block;
}
<div class="gallery">
<div class="gallery_item_square">
<div class="gallery_square">
<div class="image_attribution">
<div class="image_square">
<div class="image">
<img class="image_contain" src="https://acrossky.github.io/Images/3W6A8814.jpg">
<span class="attribution"> ARC/Qedema</span>
</div>
</div>
</div>
</div>
<div class="gallery_description">
<p>This is a description</p>
</div>
</div>
<div class="gallery_item_square">
<div class="gallery_square">
<div class="image_attribution">
<div class="image_square">
<div class="image">
<img class="image_contain" src="https://acrossky.github.io/Images/3W6A8817.jpg">
<span class="attribution"> ARC/Qedema</span>
</div>
</div>
</div>
</div>
<div class="gallery_description">
<p>This is a description</p>
</div>
</div>
</div>
Related
I'm trying to make messages shows from bottom to top, like on whatsapp, you will see the latest messages and it will start from bottom and for older messages you need to scroll up.
I'm using display: flex; and justify-content: flex-end; which seems to display correctly (from bottom).
But the problem is that I can't scroll to top, it does not let me.
How can I fix this?
body {
background-color: #000;
height: 100%;
width: 100%;
}
.box {
width: 800px;
height: 200px;
background-color: lightblue;
}
.container {
width: 100%;
height: 100%;
overflow-y: auto;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
.header {
display: flex;
justify-content: center;
align-items: center;
margin: 10px 0;
background: red;
}
.message {
margin: 10px;
}
.message.player {
background-color: #ccc
}
.message.me {
background-color: lightgreen;
}
<body>
<div class="box">
<div class="container">
<div class="header">
<span>Yesterday</span>
</div>
<div class="message player">
<span>Message from friend 1</span>
</div>
<div class="message player">
<span>Message from friend 2</span>
</div>
<div class="message player">
<span>Message from friend 3</span>
</div>
<div class="header">
<span>Today</span>
</div>
<div class="message me">
<span>Message from me 1</span>
</div>
<div class="message me">
<span>Message from me 2</span>
</div>
<div class="message me">
<span>Message from me 3</span>
</div>
</div>
</div>
</body>
There is a hack how to do it with CSS with flex-direction: column-reverse for a wrapper, which I attached as an example. But it probably would be better to make it explicitly with JavaScript using Window.scroll() method.
.test {
width: 30px;
height: 30px;
}
.test:nth-of-type(2n + 1) {
background: yellow;
}
.wrapper {
height: 300px;
overflow: auto;
display: flex;
flex-direction: column-reverse;
}
<div class="wrapper">
<div class="div">
<div class="test">1</div>
<div class="test">2</div>
<div class="test">3</div>
<div class="test">4</div>
<div class="test">5</div>
<div class="test">6</div>
<div class="test">7</div>
<div class="test">8</div>
<div class="test">9</div>
<div class="test">10</div>
<div class="test">11</div>
<div class="test">12</div>
<div class="test">13</div>
<div class="test">14</div>
<div class="test">15</div>
<div class="test">16</div>
<div class="test">17</div>
<div class="test">18</div>
<div class="test">19</div>
<div class="test">20</div>
</div>
</div>
It is because you are forcing your .container div to be of fixed height (i.e 100% of its parent). Remove the height: 100%; and overflow-y: auto; from .container and set overflow-y: auto; on your .box div.
body {
background-color: #000;
height: 100%;
width: 100%;
}
.box {
width: 800px;
height: 200px;
background-color: lightblue;
overflow-y: auto;
}
.container {
width: 100%;
/* height: 100%;
overflow-y: auto; */
display: flex;
flex-direction: column;
justify-content: flex-end;
}
.header {
display: flex;
justify-content: center;
align-items: center;
margin: 10px 0;
background: red;
}
.message {
margin: 10px;
}
.message.player {
background-color: #ccc
}
.message.me {
background-color: lightgreen;
}
I have this mockup, there are some nested containers. some of the link-class have multiple elements (par and ref) and I want them to display next to each other if there's space, but responsively move them below each other when total width gets smaller.
It works somewhat, but I expect (want) the link-element containing two childs to return to the same width as the link-element with one single child as it wraps.
For some reason, it remains wider than the single-child ones.
Any hints appreciated!
Code:
let name = 'world';
:global(body) {
margin: 0;
padding: 0
}
.main {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
background-color: gray;
}
.Container {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
background-color: lightblue;
padding: 3px
}
.linkContainer {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 3px;
background-color: salmon;
}
.par {
width: 80vw;
max-width: 300px;
background-color: red
}
.links {
display: flex;
flex-flow: row wrap;
padding: 3px;
background-color: orange
}
.ref {
background-color: olive;
width: 30vw;
max-width: 100px
}
.item {
width: 80vw;
max-width: 300px;
background-color: steelblue
}
<div class="main">
<div class="Container">
<div class="item">
header
</div>
<div class="linkContainer">
<div class="links">
<div class="par">
some text
</div>
</div>
<div class="links">
<div class="par">
some text
</div>
</div>
<div class="links">
<div class="par">
some text
</div>
</div>
<div class="Container">
<div class="item">
another header
</div>
<div class="linkContainer">
<div class="links">
<div class="par">
some text
</div>
<div class="ref">
a ref
</div>
</div>
<div class="links">
<div class="par">
some text
</div>
</div>
<div class="links">
<div class="par">
some text
</div>
<div class="ref">
a ref
</div>
</div>
</div>
</div>
</div>
</div>
</div>
you could simply add a max-width:300px; to .links and have the box in size but then you couldn't have the desired stacking effect you wanted so i went a bit further and with the help of css variables and media queries and adding a class .single to single .pars which didn't have a .ref after them, i came up with this:
:root {
--ref-size: 100px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.main {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
background-color: gray;
}
.Container {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
background-color: lightblue;
padding: 3px
}
.links {
min-width: 300px;
display: flex;
flex-flow: row wrap;
padding: 3px;
background-color: orange;
}
.par {
width: calc(100% - var(--ref-size));
background-color: red;
}
.ref {
background-color: olive;
width: var(--ref-size);
}
.item {
width: 80vw;
max-width: 300px;
background-color: steelblue
}
#media all and (max-width:300px){
.par{
width: 100%;
}
}
#media all and (min-width: 300px){
.par.single{
width: 100%;
}
}
<div class="main">
<div class="Container">
<div class="item links">
header
</div>
<div class="links">
<div class="par single">
some text
</div>
</div>
<div class="links">
<div class="par single">
some text
</div>
</div>
<div class="links">
<div class="par single">
some text
</div>
</div>
<div class="item links">
another header
</div>
<div class="links">
<div class="par">
some text
</div>
<div class="ref">
a ref
</div>
</div>
<div class="links">
<div class="par single">
some text
</div>
</div>
<div class="links">
<div class="par">
some text
</div>
<div class="ref">
a ref
</div>
</div>
</div>
</div>
I stumbled upon an issue with image centering within a flexbox with direction:column.
Imagine you have two elements within a flexbox, where the first one contains an image:
<div class="container">
<div class="image-container">
<img class="img" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg">
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
.container {
height: 300px;
background-color: green;
display: flex;
flex-direction: column;
.image-container {
flex: 1;
align-self: center;
.img {
height: 100%;
}
}
.another-flex-child {
flex: none;
background-color: red;
}
}
I would expect the image to be center horizontally within the div, but it appears the left border of the image is exactly at the center of the div.
When I replace the image with another div which contains some text it is placed as expected.
Can anybody explain to me whats happening there?
Checkout this fiddle
Because your <div> that contains the image (and has align-self: center on it) is by default a block-level element, and has a width of 100% by default. As such, it is constrained in relation to the parent.
In order to have your image centered correctly, you'll want to add display: contents with:
container .image-container {
display: inline;
}
This can be seen in the following:
.container {
height: 300px;
background-color: green;
display: flex;
flex-direction: column;
}
.container .image-container {
flex: 1;
align-self: center;
display: contents;
}
.container .image-container .img {
height: 100%;
}
.another-flex-child {
flex: none;
background-color: red;
}
.spacer {
height: 20px;
}
<div class="container">
<div class="image-container">
<img class="img" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg">
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
<div class="spacer"></div>
<div class="container">
<div class="image-container">
<div>Properly centered content</div>
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
The issue is that you are using an SVG with no intrinsic dimension and only an intrinsic ratio so it's like your image has a width equal to 0 which make its centred container with a width equal to 0, too.
Here is before using height:100%
.container {
height: 300px;
background-color: green;
display: flex;
flex-direction: column;
}
.image-container {
flex: 1;
align-self: center;
border:2px solid blue;
}
.img {
/*height: 100%;*/
}
.another-flex-child {
flex: none;
background-color: red;
}
.spacer {
height: 20px;
}
<div class="container">
<div class="image-container">
<img class="img" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg">
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
<div class="spacer"></div>
<div class="container">
<div class="image-container">
<div>Properly centered content</div>
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
After setting height:100% the image will fill all the space and will keep its ratio but you will have an overflow because the browser will not go back to calculate the width of the container again:
.container {
height: 300px;
background-color: green;
display: flex;
flex-direction: column;
}
.image-container {
flex: 1;
align-self: center;
border:2px solid blue;
}
.img {
height: 100%;
}
.another-flex-child {
flex: none;
background-color: red;
}
.spacer {
height: 20px;
}
<div class="container">
<div class="image-container">
<img class="img" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg" >
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
<div class="spacer"></div>
<div class="container">
<div class="image-container">
<div>Properly centered content</div>
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
To avoid this give the image a width and make sure to add min-height:0 to the container to allow it to shrink
.container {
height: 300px;
background-color: green;
display: flex;
flex-direction: column;
}
.image-container {
flex: 1;
align-self: center;
border:2px solid blue;
min-height:0;
}
.img {
height: 100%;
}
.another-flex-child {
flex: none;
background-color: red;
}
.spacer {
height: 20px;
}
<div class="container">
<div class="image-container">
<img class="img" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg" width="250">
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
<div class="spacer"></div>
<div class="container">
<div class="image-container">
<div>Properly centered content</div>
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
If you were initially using an image with intrinsic dimension you won't have this issue and you don't need to define a width. You will only need to add min-height:0 to avoid the overflow:
.container {
height: 300px;
background-color: green;
display: flex;
flex-direction: column;
}
.image-container {
flex: 1;
align-self: center;
border:2px solid blue;
min-height:0;
}
.img {
height: 100%;
}
.another-flex-child {
flex: none;
background-color: red;
}
.spacer {
height: 20px;
}
<div class="container">
<div class="image-container">
<img class="img" src="https://picsum.photos/id/1/400/400">
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
<div class="spacer"></div>
<div class="container">
<div class="image-container">
<div>Properly centered content</div>
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
Note that the above doesn't work the same way in Firefox and you will need to add text-aling:center to make sure it works the same everywhere:
.container {
height: 300px;
background-color: green;
display: flex;
flex-direction: column;
}
.image-container {
flex: 1;
align-self: center;
border:2px solid blue;
text-align:center;
min-height:0;
}
.img {
height: 100%;
}
.another-flex-child {
flex: none;
background-color: red;
}
.spacer {
height: 20px;
}
<div class="container">
<div class="image-container">
<img class="img" src="https://picsum.photos/id/1/400/400">
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
<div class="spacer"></div>
<div class="container">
<div class="image-container">
<div>Properly centered content</div>
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
You will notice that the difference is related to the width calculation of the container which a bit complex due to the use of height:100%
Things may get worse if the size of the image is very small:
.container {
height: 300px;
background-color: green;
display: flex;
flex-direction: column;
}
.image-container {
flex: 1;
align-self: center;
border:2px solid blue;
text-align:center;
min-height:0;
}
.img {
height: 100%;
}
.another-flex-child {
flex: none;
background-color: red;
}
.spacer {
height: 20px;
}
<div class="container">
<div class="image-container">
<img class="img" src="https://picsum.photos/id/1/50/50">
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
<div class="spacer"></div>
<div class="container">
<div class="image-container">
<div>Properly centered content</div>
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
In Firefox text-align:center will do nothing and you may need a nested flexbox container
.container {
height: 300px;
background-color: green;
display: flex;
flex-direction: column;
}
.image-container {
flex: 1;
align-self: center;
justify-content:center;
border:2px solid blue;
display:flex;
min-height:0;
}
.img {
height: 100%;
}
.another-flex-child {
flex: none;
background-color: red;
}
.spacer {
height: 20px;
}
<div class="container">
<div class="image-container">
<img class="img" src="https://picsum.photos/id/1/50/50">
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
<div class="spacer"></div>
<div class="container">
<div class="image-container">
<div>Properly centered content</div>
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
The below is almost the same issue you were having with the initial SVG that can fixed with this same code but it won't remove the overflow:
.container {
height: 300px;
background-color: green;
display: flex;
flex-direction: column;
}
.image-container {
flex: 1;
align-self: center;
display:flex;
justify-content:center;
border:2px solid blue;
}
.img {
height: 100%;
}
.another-flex-child {
flex: none;
background-color: red;
}
.spacer {
height: 20px;
}
<div class="container">
<div class="image-container">
<img class="img" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg" >
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
<div class="spacer"></div>
<div class="container">
<div class="image-container">
<div>Properly centered content</div>
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
Another intresting thing to note is that your initial code may work fine if you add height:100% to the container making the calculation of the nested height easier:
.container {
height: 300px;
background-color: green;
display: flex;
flex-direction: column;
}
.image-container {
flex: 1;
align-self: center;
border:2px solid blue;
box-sizing:border-box;
height:100%;
}
.img {
height: 100%;
display:block;
}
.another-flex-child {
flex: none;
background-color: red;
}
.spacer {
height: 20px;
}
<div class="container">
<div class="image-container">
<img class="img" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg" >
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
<div class="spacer"></div>
<div class="container">
<div class="image-container">
<div>Properly centered content</div>
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
Add the justify-content like below:
.image-container {
flex: 1;
align-self: center;
justify-content:center;
}
it should works
I am using a centred div to contain an image and some text but want my title to have the same margin/alignment as the text. Right now the title is placed on the extreme left of the page and I want it to have a responsive margin on the left.
.row {
margin: auto;
max-width: 1150px;
display: flex;
align-items: center;
img {
width: auto;
}
}
<div class="container-fluid">
<h1>Choosing a Console</h1>
<div class="row">
<div class="col-sm" id="textbox">
<p>
Some Text
</p>
</div>
<div class="col-sm" id="img">
<img style="height: 350px" src="which.png" alt="Which One">
</div>
</div>
</div>
there are two ways you could do this;
Add margin-left to the div h2 tag or add a container
.row {
margin: auto;
max-width: 1150px;
display: flex;
align-items: center;
img {
width: auto;
}
}
.container-fluid h1 {
margin-left: 150px;
}
or you can over complicate it like I do and contain containers, I have added border outlines so you understand what that container is containing, if you wish to move the h1 and p text, you can margin-left them both.
.row {
max-width: 1150px;
height: auto;
border: 1px solid red;
}
.rowTextContainer {
float: left;
width: auto;
margin-left: 50px;
}
.rowText {
text-align: center;
border: 1px solid blue;
}
.row img {
width: auto;
padding-left: 20px;
}
<div class="row">
<div class="rowTextContainer">
<div class="rowText">
<h1>Title Text</h1>
<p>Text here.</p>
</div>
</div>
<img src="https://via.placeholder.com/350.png">
</div>
.row {
margin: auto;
max-width: 1150px;
display: flex;
flex-direction: column;
align-items: center;
}
.col-sm {
display: flex;
flex-direction: row;
margin-left: 10%;
}
img {
width: auto;
margin-left: 10px;
}
<div class="container-fluid">
<h1>Choosing a Console</h1>
<div class="row">
<div class="col-sm" id="textbox">
<p>
Some Text go ahead . . . . .
</p>
<img style="height: 350px" src="https://picsum.photos/200" alt="Which One">
</div>
</div>
</div>
I hope it will solve your problem.
I have tried using overflow: hidden; for each element but it does not seem to be doing anything
The html looks like this, the display is to have the 2 divs side by side (stacks ontop for smaller screens). The left side div will also be on top of the right side div. I have a screen shot and fiddle too.
.sec {
background-color: red;
min-height: 100vh;
overflow: hidden;
}
.sec2 {
background-color: blue;
min-height: 100vh;
overflow: hidden;
}
.img1 {
max-width: 100%;
position: absolute;
}
.img1 {
z-index: 1;
}
.leftCol {
z-index: 10;
width: 50%;
}
.info-row {
display: flex;
flex-direction: row;
margin-left: 10vw;
margin-right: 200px;
}
.rightCol {
width: 50%;
}
<section class="sec">
<div class="info-row">
<div class="leftCol info-column">
<h1>haheaheh</h1>
<p>teataetetat</p>
</div>
<div class='rightCol info-column'>
<img class="img1" src='https://kasonbloom.files.wordpress.com/2017/08/lamb-2.jpg' />
</div>
</div>
</section>
<section class="sec2">
<div class="info-row">
<div class="leftCol info-column">
<h1>asdfasdfasdf</h1>
<p>basfbasdfbasdfba</p>
</div>
<div class='rightCol info-column'>
</div>
</div>
</section>
https://jsfiddle.net/gtrnrd9r/2/ keep result view at a point where the image breaks through the section
Add position:relative; to your outer section .sec and it will work fine.
.sec {
background-color: red;
min-height: 100vh;
overflow: hidden;
position:relative;
}
.sec2 {
background-color: blue;
min-height: 100vh;
overflow: hidden;
}
.img1 {
max-width: 100%;
position: absolute;
}
.img1 {
z-index: 1;
}
.leftCol {
z-index: 10;
width: 50%;
}
.info-row {
display: flex;
flex-direction: row;
margin-left: 10vw;
margin-right: 200px;
}
.rightCol {
width: 50%;
}
<section class="sec">
<div class="info-row">
<div class="leftCol info-column">
<h1>haheaheh</h1>
<p>teataetetat</p>
</div>
<div class='rightCol info-column'>
<img class="img1" src='https://kasonbloom.files.wordpress.com/2017/08/lamb-2.jpg' />
</div>
</div>
</section>
<section class="sec2">
<div class="info-row">
<div class="leftCol info-column">
<h1>asdfasdfasdf</h1>
<p>basfbasdfbasdfba</p>
</div>
<div class='rightCol info-column'>
</div>
</div>
</section>
.rightCol needs his own width and height if i'm not mistaken. overflow doesn't work with the parent element.