I have found some very simple masonry layout now the problem is its displaying it on horizontal i want it to display on vertical. tried to change the masonry height but still display horizontally not so sure how
display: flex
behaves with the other flex properties.
This is the layout I would like to achieve
Fiddle is here
HTML:
<div id="masonry">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/1.jpg">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/2.jpg">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/3.jpg">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/4.jpg">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/6.jpg">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/8.jpg">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/9.jpg">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/7.jpg">
</div>
CSS:
body {
margin: 0; background: #131212;
width: 100vw
}
div#masonry {
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 100vw;
font-size: 0;
}
div#masonry img {
width: 50%;
transition: .8s opacity;
}
div#masonry:hover img { opacity: 0.3; }
div#masonry:hover img:hover { opacity: 1; }
->some guide<-
flex-direction: row | row-reverse | column | column-reverse;
in the:
div#masonry img - you can play with width and/or height also, hope that helps :)
Related
so I'd like to put 2 texts around an image (one text on the left, the other right of the image) and center them vertically. Is there other ways than putting position:relative; in the container and position:absolute; to the text (and play with the pixels of top and left to put it in the position that I want) to make the text and image RESPONSIVE in any devices? I want something like this:
Here's my code:
HTML
<div class="socrates-words">
<p class="hello"><strong>Hello!</strong></p>
<p class="socrates-name"><strong>My name is Socrates.</strong></p>
</div>
<div class="container-gif">
<img src="/videos/socrates-video.gif" alt="" id="gif-socrates" />
</div>
CSS
.button-section .container-gif {
position: relative;
bottom: 80%;
}
.button-section .container-gif #gif-socrates {
transform: translate(-50%);
left: 50%;
width: 25%;
position: absolute;
display: none;
}
.button-section .socrates-words {
font-size: 32px;
position: relative;
}
.button-section .socrates-words .hello {
position: absolute;
left: 15%;
top: 17rem;
}
.button-section .socrates-words .socrates-name {
position: absolute;
left: 65%;
top: 17rem;
}
I'm doing my best and I'm a beginner so please no hate comments... Thank you in advance!
You do not have to change your HTML.
This snippet uses a CSS grid of 3 equal columns, tells it to use the contents of the first child rather than the child itself (i.e. the 2 p elements) using display: contents and defines the order of the second p element within the grid and the img containing element.
.container {
display: grid;
width: 100vw;
grid-template-columns: repeat(3, 1fr);
text-align: center;
}
.socrates-words {
display: contents;
}
.socrates-words>* {
display: flex;
align-items: center;
justify-content: center;
}
.socrates-words p:last-of-type {
order: 3;
}
.container-gif {
order: 2;
}
<div class="container">
<div class="socrates-words">
<p class="hello"><strong>Hello!</strong></p>
<p class="socrates-name"><strong>My name is Socrates.</strong></p>
</div>
<div class="container-gif">
<img src="https://picsum.photos/id/1015/50/100" alt="" id="gif-socrates" />
</div>
</div>
Obviously you can alter various dimensions to suit your particular requirement.
Here is an easy example of how you can do it.
just place your image in between the text container and then using display flex you can achieve the result you want.
It is also responsive.
Explanation
I used display: flex; so I can align all the image and text in a row.
I used justify-content: space-evenly; to make the space between the image and test even
I used align-items: center; to make all the text and the image to center from top and bottom.
.socrates-words{
display:flex;
justify-content: space-evenly;
align-items:center;
}
<div class="socrates-words">
<p class="hello"><strong>Hello!</strong></p>
<div class="container-gif">
<img src="https://images.unsplash.com/photo-1672002760123-4c6496489053?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwyfHx8ZW58MHx8fHw%3D&auto=format&fit=crop&w=400&q=60" alt="" id="gif-socrates" />
</div>
<p class="socrates-name"><strong>My name is Socrates.</strong></p>
</div>
I hope you got the answer and also got how it works!
I'm trying to put 4 images in a flexbox div in a parent flexbox, with total height 100%, without stretching out of the parent flexbox. I've searched a lot, but I didn't found something useful.
I have made a minimum example:
html {
height: 100%;
}
body {
height: 100%;
margin: 0;
display: flex;
}
main {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
background-color: yellowgreen;
}
.imgs {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
}
.img100 {
max-width: 100%;
max-height: 100%;
vertical-align: middle;
}
<main>
<!--
Weird. Chromium (Chrome & new Edge) usually renders height 100%,
but not height-responsive; sometimes renders scroll bar.
Firefox always renders the scroll bar result.
-->
<div class="imgs">
<img class="img100" src="https://imgur.com/ruE1EBV.jpg">
</div>
<div class="imgs">
<img class="img100" src="https://imgur.com/ruE1EBV.jpg">
</div>
<div class="imgs">
<img class="img100" src="https://imgur.com/ruE1EBV.jpg">
</div>
<div class="imgs">
<img class="img100" src="https://imgur.com/ruE1EBV.jpg">
</div>
</main>
When opening this example, chromium-based browsers(Chrome, new Edge) usually render height 100%, the desired result, but it is not "height-responsive": the max height of the images remains fixed once the page is fully loaded.
What even worse is, sometimes they give the stretched result with scrollbar; and Firefox always give me the stretched result with scrollbar, which is not what I want.
Try opening this S.O. page in Chromium & Firefox, and run the snippet. The results are different, too.
Chromium (almost always left, rarely right):
Firefox (always):
Any way to achieve what I want? The wrapping div and parent div may be something other than flexbox. I just want the images staying in the div, with width-responsive & height-responsive.
Also, any reason why Chromium browsers' rendering results are not consistent? Is my example missing something?
I know I can use the background image technique, so I can put image in div without changing layout at all. But I want only the image part clickable, so there must be an image element there corresponding to the clickable area.
background-image example:
html {
height: 100%;
}
body {
height: 100%;
margin: 0;
display: flex;
}
main {
flex: 1;
display: flex;
flex-direction: column;
background-color: yellowgreen;
}
a {
flex: 1;
background-image: url('https://imgur.com/ruE1EBV.jpg');
background-repeat: no-repeat;
background-size: contain;
background-position: center;
border: 5px solid red;
}
<main>
</main>
Edit:
Equal row heights in flex-direction: column is okay when the content inside doesn't contain any images. I think the tricky part is the images. They just stretch...
html {
height: 100%;
}
body {
height: 100%;
margin: 0;
display: flex;
}
main {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
background-color: yellowgreen;
}
.imgs {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
border: 5px solid red;
}
.img100 {
max-width: 100%;
max-height: 100%;
vertical-align: middle;
}
<main>
<div class="imgs">
hello
</div>
<div class="imgs">
hello
</div>
<div class="imgs">
hello
</div>
<div class="imgs">
hello
</div>
</main>
Well, I found an easy answer to fix this simple minimum example.
Just add overflow: hidden to .imgs, so images don't grow out of main.
html {
height: 100%;
}
body {
height: 100%;
margin: 0;
display: flex;
}
main {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
background-color: yellowgreen;
}
.imgs {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
.img100 {
max-width: 100%;
max-height: 100%;
vertical-align: middle;
}
<main>
<div class="imgs">
<img class="img100" src="https://imgur.com/ruE1EBV.jpg">
</div>
<div class="imgs">
<img class="img100" src="https://imgur.com/ruE1EBV.jpg">
</div>
<div class="imgs">
<img class="img100" src="https://imgur.com/ruE1EBV.jpg">
</div>
<div class="imgs">
<img class="img100" src="https://imgur.com/ruE1EBV.jpg">
</div>
</main>
Applying this to my actual, much more huge layout did fix my layout.
So all I need to do is to carefully inspect my overflows.
Why Chromium behaves differently: stackoverflow: Why do Chrome and Firefox show different flex layout results?
I have a very simple markup of 4 images, where the goal is to get a 2x2 responsive image grid that will:
Maintain 2x2 fit screen on all screens regardless of size, using only flex.
Keep the images centered and maintain aspect ratio( "cropping" them from
view if needed according to screen )
Be able to transform on hover.
Not change the markup ( and don't ask why )
Try to achieve a situation where a single property ( or min number of ) could
transform the grid to 4 x whatever ( 4 in a row ) meaning not change markup to galley rows of 2..
the markup is :
<div class="container">
<div class="gallery">
<img class="item" src="https://source.unsplash.com/random/" alt="Example image">
<img class="item" src="https://source.unsplash.com/random/" alt="Example image">
<img class="item" src="https://source.unsplash.com/random/" alt="Example image">
<img class="item" src="https://source.unsplash.com/random/" alt="Example image">
</div>
</div>
And the css :
/** Add basic reset **/
.container {
display: flex;
/* flex-wrap: wrap; */
/* justify-items: center; */
justify-content: center;
/* max-height: 100vh; */
height: 100vh;
}
img {
margin: 5px;
transition: all 2s;
flex-basis: 49%;
max-height: 49vh;
align-self: center;
/* max-width: calc(49vh - 10px); */
}
.gallery {
display: flex;
flex-wrap: wrap;
flex: 1 1 49%;
align-items: center;
overflow: hidden;
}
img:hover {
transform: scale (1.1);
}
adding :
img {
object-fit: cover;
}
kind of works, but it has a "hack-ey" feels to it and also have 2 major problems (1) it will indeed "crop" the images - but they are not centered and (2) on hover they will "spill" from container.
I am quit sure that this is NOT the right way to achieve what I need, but not so sure as to what flex-property I am missing, or using wrong here.
Edit I to be more clear attached an image of what I am trying to achieve, where each represents a different size screen / viewport without any scroll.
Images need to be always centered and cropped in edges according to screen ( somewhat like a full-screen background usually works )
Perhaps this may help, although I'm not entirely sure if I fully understand your request.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.container {
display: flex;
flex-flow: row wrap;
height: 100vh;
width: 100vw;
overflow: hidden;
}
.child {
/* FOR 4 IN A GRID */
flex: 1 0 50%;
max-width: 50%;
max-height: 50%;
/* FOR YOUR 4 IN 1 ROW */
/* flex: 1 0 25%;
max-width: 25%; */
/* FOR BOTH */
padding: 5px;
object-fit: none;
}
.child:hover {
transform: scale(1.1);
}
</style>
</head>
<body>
<div class="container">
<img src="https://images-na.ssl-images-amazon.com/images/I/81XYWLSWlOL._SX466_.jpg" class="child">
<img src="https://images-na.ssl-images-amazon.com/images/I/81XYWLSWlOL._SX466_.jpg" class="child">
<img src="https://images-na.ssl-images-amazon.com/images/I/81XYWLSWlOL._SX466_.jpg" class="child">
<img src="https://images-na.ssl-images-amazon.com/images/I/81XYWLSWlOL._SX466_.jpg" class="child">
</div>
</body>
</html>
Updated Version
It's up to you to to add in media queries to set the size of the container itself.
I know this sounds like it's been asked before but I've played around with a lot of techniques I've found from other questions and nothing seems to get the desired effect I need.
I'm trying to make something that will be responsive like this:
Responsive Example gif
I basically need an image to be centered, where the image is at 100% size.
Here is what I tried to get this effect:
I first made a div containing three child divs for "columns". Then inside the center column I made three child divs for "rows". Now I need the image to fill the max width it's allowed while still maintain that square aspect ratio. As well the height of the image should determine the height of the top and bottom rows.
Then it should just be a matter of having the text inside the top and bottom row align to the bottom and top of their divs respectively.
This would look something like this:
HTML Visualization of columns
HTML Visualization of center rows
The issue I'm running into is I can't seem to get the center image to determine the heights of the rows above and below it.
I've tried...
Flexbox
using vh (view height)
and a bit of using calc() but to no luck
Setting aspect ration with padding-top: 100%
What the code looks like
/* .row & .col from materialize.css */
.full {
height: 100vh;
}
.art_top {
height: 10vh;
/* I Don't actually want this fixed though */
padding-bottom: 10px;
display: flex;
}
.art_center {
height: 80vh;
/* I Don't actually want this fixed though */
}
.art_bottom {
height: 10vh;
/* I Don't actually want this fixed though */
padding-top: 10px;
display: flex;
}
#cover_art {
width: 100%;
height: 100%;
background: center / cover no-repeat;
}
#song_name {
align-self: flex-end;
}
#artist_name {
align-self: flex-start;
}
<div class="row">
<div class="col s2 m3 full"></div>
<div class="col s8 m6 full">
<div class="row art_top">
<a id="song_name" class="bold-title"></a>
</div>
<div class="row art_center">
<div id="cover_art"></div>
</div>
<div class="row art_bottom">
<a id="artist_name" class="bold-title"></a>
</div>
</div>
<div class="col s2 m3 full"></div>
</div>
Flexbox makes this kind of layout very straightforward. The trick is selectively allowing items to flex or shrink.
The flex property shorthand takes 3 values for flex-grow, flex-shrink, and flex-basis (the initial width or height depending on flex direction). Just keep clear which divs are serving as flex containers as you get into the details in the layout. It is very common to have divs that are both flex containers and flex items themselves too.
I also recommend using an img element instead of applying the image as a background so you dont have trouble with the aspect ratio in responsive window sizes.
A very nice resource: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
/* .row & .col from materialize.css */
body {
margin: 0;
}
.full {
height: 100vh;
}
.row {
display: flex;
}
.column {
flex: 1 1 auto;
}
.column2 {
background: #b4c2cf;
display: flex;
flex-direction: column;
}
.column1 {
background: #cbb3cc;
}
.column3 {
background: #cbb2b2;
display: flex;
align-items: center;
justify-content: center;
}
.art_top {
flex: 1 0 10vh;
display: flex;
justify-content: flex-start
align-self: flex-end;
}
.art_center {
flex: 1 1 auto;
display: flex;
align-items: center;
justify-content: center;
}
.art_bottom {
flex: 1 0 10vh;
text-align: right;
}
#cover_art {
max-width: 100%;
max-height: 100%;
width: auto;
height: auto;
}
#song_name {
align-self: flex-end;
}
#artist_name {
align-self: flex-start;
}
.bold-title {
display: block;
font-weight: bold;
padding: 10px;
}
.small-box {
background: #8f588c;
height: 100%;
max-height: 70px;
width: 100%;
max-width: 70px;
}
<div class="row full">
<div class="column column1"></div>
<div class="column column2">
<div class="art_top">
<a id="song_name" class="bold-title">My Album Title</a>
</div>
<div class="art_center">
<img id="cover_art" src="https://picsum.photos/400" />
</div>
<div class="art_bottom">
<a id="artist_name" class="bold-title">Artist Name</a>
</div>
</div>
<div class="column column3">
<div class="small-box"></div>
</div>
</div>
I'm making a card. The card has two stacked divs. The top part of the card has an image and the bottom part is just text. What do I do to make sure the top and bottom divs have the same height? I know i could define heights of the divs in pixels, but I don't want to do that because I don't know much text will be on the other cards.
.card {
display: flex;
flex-direction: column;
flex: 1;
}
.cardTop, .cardBottom {
border: 1px solid;
}
img {
display: block;
}
<div class="card">
<div class="cardTop">
<img src="https://placehold.it/200x100" alt="">
</div>
<div class="cardBottom">
<p>text of the card goes here</p>
</div>
</div>
Just use the styling of the flex-box like this :
.card {
display: flex;
flex: 1;
flex-direction: column;
flex-wrap: nowrap;
padding: 5px;
height: 15em; //chose what you want
width: 15em; //chose what you want
}
.card > div {
flex: 1 1 50%;
overflow: hidden;
}
Your 2 divs will split at 50% height of your global .card container height by doing this.
I made a quick example online : https://stackblitz.com/edit/angular-pechib