I have a flex container, and in that container, I have a bunch of images. Using flexwrap, and a flex-item width of 33%, this presents the images nicely ... in Chrome (that is, they maintain their aspect ratios). In Safari, however, the images get stretched in the vertical direction which looks terrible.
Is there a fix for this?
(Note: For the code snippet below, you will have to open this post in both Chrome and Safari to see what I am talking about)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div class="container">
<img src='https://swipestack.s3.amazonaws.com/s/q/1.jpg' alt='1'>
<img src='https://swipestack.s3.amazonaws.com/s/q/2.jpg' alt='2'>
<img src='https://swipestack.s3.amazonaws.com/s/q/3.jpg' alt='3'>
<img src='https://swipestack.s3.amazonaws.com/s/q/4.jpg' alt='4'>
<img src='https://swipestack.s3.amazonaws.com/s/q/5.jpg' alt='5'>
<img src='https://swipestack.s3.amazonaws.com/s/q/6.jpg' alt='6'>
<img src='https://swipestack.s3.amazonaws.com/s/q/7.jpg' alt='7'>
<img src='https://swipestack.s3.amazonaws.com/s/q/8.jpg' alt='8'>
</div>
</body>
<style>
.container{
display: flex;
flex-wrap: wrap;
overflow: auto;
width: 400px;
height: 550px;
padding: 10px;
background-color: green;
}
.container > * {
width: 33.33333%;
}
</style>
</html>
you can try this, which works only if you give the first and second images the same height of 475px as the others :
<style>
.container {
width: 400px;
height: 550px;
padding: 10px;
background-color: green;
overflow: auto;
}
.container:first-child {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
}
.container > * {
width: 33.33333%;
height: auto;
}
</style>
Related
Image of my current layout
I'm learning flexbox, and I am trying to create a common layout that is found with dashboard kind of templates. These kinds of templates contain a main navigation menu on the left (the sidebar), a top navigation menu for things like user notifications or site themes, and a main content area below the top navigation menu.
The problem that I am facing is that one of my nav list items "B" (it has a white border around it for visibility) is for some unknown reason not being pushed to the bottom of the "purple" div.
I set the height to both the nav and the ul elements to have a height of 100% so that they take up as much vertical space as the body does. So from my understanding adding a margin-top: auto should in fact push B all the way to the bottom.
Is there a fundamental issue with my understanding? And am I on the right track to implementing this kind of theme correctly?
Thank you for your time and for sharing your knowledge!
* {
margin: 0;
padding: 0;
/* box-sizing: border-box; */
/* border: 1px solid black; */
}
body {
display: flex;
height: 100vh;
}
#left {
background-color: aqua;
width: 5rem;
}
.column {
display: flex;
flex-direction: column;
}
.top-left,
.top-right {
padding: 1rem;
background-color: aliceblue;
}
nav {
background-color: red;
height: 100%;
}
ul {
background-color: blueviolet;
height: 100%;
}
nav ul li:last-child {
margin-top: auto;
border: 1px solid white;
}
#right {
background-color: orange;
flex-grow: 1;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="./project.css" rel="stylesheet">
</head>
<body>
<div id="left" class="column">
<div class="top-left">
Logo
</div>
<nav>
<ul>
<li>A</li>
<li>B</li>
</ul>
</nav>
</div>
<div id="right" class="column">
<div class="top-right">
Top right
</div>
<div>
Content
</div>
</div>
</body>
</html>
If you want use margin-top:auto try the following:
ul {
background-color: blueviolet;
height: 100%;
display: flex;
flex-direction: column;
}
You can also try in other ways like :
ul {
display: flex;
}
nav ul li:last-child {
align-self: flex-end;
}
And by grid :
ul {
display: grid;
}
nav ul li:last-child {
align-self: flex-end;
}
Your CSS code is correct but you are applying it to wrong element. The ul should get the flex box property so that all li items are displayed as columns. Apply flex property to ul.
* {
margin: 0;
padding: 0;
/* box-sizing: border-box; */
/* border: 1px solid black; */
}
body {
display: flex;
height: 100vh;
}
#left {
background-color: aqua;
width: 5rem;
}
.column {
display: flex;
flex-direction: column;
}
.top-left,
.top-right {
padding: 1rem;
background-color: aliceblue;
}
nav {
background-color: red;
height: 100%;
}
ul {
display: flex;
flex-direction: column;
background-color: blueviolet;
height: 100%;
}
nav ul li:last-child {
margin-top: auto;
border: 1px solid white;
}
#right {
background-color: orange;
flex-grow: 1;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="./project.css" rel="stylesheet">
</head>
<body>
<div id="left" class="column">
<div class="top-left">
Logo
</div>
<nav>
<ul>
<li>A</li>
<li>B</li>
</ul>
</nav>
</div>
<div id="right" class="column">
<div class="top-right">
Top right
</div>
<div>
Content
</div>
</div>
</body>
</html>
I managed to get B pushed to the bottom by adding the following CSS properties to the ul element:
display: flex;
flex-direction: column;
I am still not sure why this was needed.
I nearly spend 4 hours trying to make this layout. I tried absolute positioning but obviously, It's not responsive.
Image is 660px and Right container is 860px.
<div className="container">
<div className="image-container">
<img src={image} />
</div>
<div className="right-container">
<div className="insde-some-text">
</div></div>
As far as my knowledge goes, you can only do this by position absolute and then changing the widths at certain breakpoints using media queries.
To add to what Khubaib said, you would want to use position: absolute in your .css file. Also, using scalable quantities for the boxes will help you for the certain screen sizes that you want your site displayed on.
Also, you can use position: relative on blue block and make the attribute top: -100px or so. This blue-block will always be relative to its normal position.
.red-block
{
width: 20rem;
height: 20rem;
background-color: red;
position: absolute;
}
.blue-block
{
width: 20rem;
height: 20rem;
background-color: blue;
position: absolute;
top: 50%;
left: 25%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css.css">
<title>Document</title>
</head>
<body>
<div class = "red-block">
</div>
<div class = "blue-block">
</div>
</body>
</html>
You could use this for reference. Simple demonstration using flex and margin.
.wrapper {
width: 100%;
}
.container {
display: flex;
align-items: center;
justify-content: center;
margin-top: 5%;
width: 100%;
}
.right-container {
border: solid red 1px;
border-radius: 5px;
width: 860px;
height: 860px;
background-color: #e1e1e1;
text-align: center;
}
textarea {
height: 80%;
width: -webkit-fill-available;
text-align: center;
background-color: lightblue;
}
.img {
margin-right: -3em;
position: relative;
}
img {
max-width: 100%;
}
<div class="wrapper">
<div class="container">
<div class="img">
<img src="https://dummyimage.com/660x400/000/fff" alt="">
</div>
<div class="right-container">
<textarea placeholder="hello world"></textarea>
<p>foooooooooooooooooooooo</p>
</div>
</div>
</div>
When the height of the parent flex element is set to less than the min-height, the expected result should be for the element to expand to contain its content. This works with flex-direction:row and min-width: min-content, but using literally the same code but with column instead of row and min-height instead of min-width doesn't cause the parent element to expand but instead retain its original height and clipping its' children.
.flex-row{
display: flex;
flex-direction: row;
justify-content: space-around;
height : 200px;
border-style: solid; border-width: 2px; border-color: black;
/* Width is set to 100px but because the min-content is 600px, the width overridden. */
min-width: min-content;
width: 100px;
}
.block-row{
align-self: stretch;
background-color: red;
width: 300px;
border: 2px solid blue;
}
/* Literally same code except flex-col and min-height */
.flex-col{
display: flex;
flex-direction: column;
justify-content: space-around;
min-height: min-content;
border-style: solid; border-width: 2px; border-color: black;
}
.block-col{
align-self: stretch;
background-color: red;
height: 300px;
border: 2px solid blue;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>min-content :(</title>
</head>
<body>
Intended effect works with flex-row min-width
<div class="flex-row" style="width: 100px; height : 200px; ">
<div class="block-row"></div>
<div class="block-row"></div>
</div>
</br>
Doesn't work with same code except min-height :(
</br>
-> Height is set to 100px, but instead of min-height of children causing height to grow, it is stuck at 100px for some reason.
</br>
<div class="flex-col" style="height: 100px; width : 200px; ">
<div class="block-col"></div>
<div class="block-col"></div>
</div>
</body>
</html>
instead of using px use vh that allow you to use the relavite space in the container
I have a issue with css grid , i build a container with two div in it with css grid and i want to adjust container to page center. I use this code :
html{
width: 100vw;
height : 100vh;
}
body{
height : 100%;
}
.container-fluid{
width:100%;
height : 100%;
display:grid;
grid-template-columns: 300px;
grid-template-rows: 200px auto;
justify-content: center;
align-content: center;
border:1px solid red;
}
.logo-container{
background-color: khaki;
}
.form-container{
height :540px;
background-color: lightblue;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="assets/css/style.css">
<link rel="stylesheet" href="assets/css/media-query.css">
<title>Login & Register User With Profile</title>
</head>
<body>
<div class="container-fluid">
<div class="logo-container">
<h1>Logo</h1>
</div>
<div class="form-container">
<h1>Form</h1>
</div>
</div>
<link rel="stylesheet" href="assets/css/all.css">
</body>
</html>
as you see when grid container height bigger then page height a issue occurs (please see code result).
when use height for body tag , grid height overflowing and when delete height from body tag every thing is ok but in this situ container can't adjust container in center of page.
what is problem?
Simplify your code like below:
body {
margin: 0; /* remove default margin */
}
.container-fluid {
min-height: 100vh; /* at least screen height */
display: grid;
grid-template-columns: 300px;
grid-template-rows: 200px auto;
justify-content: center;
align-content: center;
border: 1px solid red;
box-sizing:border-box; /* to consider the border inside the height */
}
.logo-container {
background-color: khaki;
}
.form-container {
height: 540px;
background-color: lightblue;
}
<div class="container-fluid">
<div class="logo-container">
<h1>Logo</h1>
</div>
<div class="form-container">
<h1>Form</h1>
</div>
</div>
Or like below:
body {
margin: 0;
}
.container-fluid {
height: 100vh; /* full height */
display: grid;
grid-template-columns: 300px;
/* first row at 200px max-height and second row at 540px max-height */
grid-template-rows: minmax(auto,200px) minmax(auto,540px);
justify-content: center;
align-content: center;
border: 1px solid red;
box-sizing:border-box;
}
.logo-container {
background-color: khaki;
}
.form-container {
background-color: lightblue;
}
<div class="container-fluid">
<div class="logo-container">
<h1>Logo</h1>
</div>
<div class="form-container">
<h1>Form</h1>
</div>
</div>
I know that we can create a responsive horizontal image easily, like that.
.img-horiz-resp {
max-width:100%;
height:auto;
}
But, in my case I need :
a header on top
a content (for now it can be a simple image)
a footer
Then, when resizing the browser vertically, I wish that the 'content' adapt its size.
I have try here : https://codepen.io/cdemez/pen/qBbKVYp
But without success.
By using VH for the height you can get you image responsive (there are other ways too, but this is simple).
VH is used for how much of the available height that should be used, like percent (%). 100VH is the whole screen from top to bottom, regardless of your screen size.
Now I put the image in the css-file (and used it ONLY as background, not background-image), but if you want to use it in your html-file, remember to set your with to 100%.
https://jsfiddle.net/battleaxe/u07cfbog/#&togetherjs=lbxrukCzHi
HTML:
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
height: 100%;
min-height: 100%;
font-family: Arial, Helvetica, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
}
header {
height: 6vh;
width: 100%;
background-color: #2e4b49;
display: flex;
justify-content: center;
align-items: center;
}
ul {
width: 60%;
display: flex;
justify-content: space-between;
list-style: none;
color: #fff;
text-transform: uppercase;
}
.content {
height: 84vh;
width: 100%;
background: url("https://cdn.socloze.com/cdn/e_663aa122-718e-a8d3-301d-39f64b8523b0/ebdc5bef01506acc759b39f64b9cc917.jpg")
no-repeat center center;
background-size: contain;
/* You can use background-size: cover; if you want the image to cover your whole free space. */
}
footer {
height: 10vh;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
background-color: #2e4b49;
color: #fff;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>Document</title>
</head>
<body>
<header>
<ul>
<li>This</li>
<li>Is</li>
<li>a</li>
<li>Header</li>
</ul>
</header>
<div class="content"></div>
<footer>
<p>This is a footer</p>
</footer>
</body>
</html>
Things you can look up are VH and VW, how the work and how they can be used. Also, try different background-sizes (cover, contain, and so on).
Good Luck!