Whats the reason for flex-wrap not to work? - css

I've looked at other questions on this website and none of them were similar to my problem, applying flex-direction:row; didnt help, applying all kinds of width's (min-width, max-width) didn't help as well.
Am I using wrong units for styling the items in container?
My goal is for the content to wrap in a new row.
HTML and CSS:
body {
margin: 0;
padding: 0;
background-color: #eeeeee;
}
h1, h5 {
padding: 10px;
margin: 0;
}
.pre-header {
text-align: center;
}
#header-content1-1 {
font-size: 1.15em;
margin: 0;
padding: 0;
}
hr {
margin-top: 20px;
margin-bottom: 3px;
}
.container {
display: flex;
background-color: cornflowerblue;
justify-content:space-between;
max-width: 80%;
margin: auto;
align-items: center;
height: 40vh;
flex-wrap: wrap;
}
.flex-item {
background-color: red;
line-height: 9vh;
width: 13%;
text-align:center;
flex-shrink: 3;
}
<!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">
<meta name="description" content="Find out who was Avicii!">
<link rel="stylesheet" href="style.css">
<title>David</title>
</head>
<body>
<header>
<div class="pre-header">
<h1 id="header-content1">Avicii - Tim Bergling</h1>
<h5 id="header-content1-1">Swedish DJ, remixer, record producer, musician, and songwriter</h5>
</div>
</header>
<main>
<hr>
<div class="container">
<div class="flex-item">E</div>
<div class="flex-item">R</div>
<div class="flex-item">I</div>
<div class="flex-item">N</div>
<div class="flex-item">N</div>
<div class="flex-item">N</div>
<div class="flex-item">N</div>
</div>
</main>
<footer>
</footer>
</body>
</html>

One suggested way as mentioned in comments is having an appropriate width (in your case 22%) so it sums up to 100% some items show up in the next row. One can add margin (like margin: 0% 5%) too to add to the width.
There is one way to do that manually, but you will have to add something similar to breaks in your HTML code. Here is a solution inspired by this.
<div class="container">
<div class="flex-item">E</div>
<div class="flex-item">R</div>
<div class="flex-item">I</div>
<div class="flex-item">N</div>
<div class="flex-item">N</div>
<div class="flex-item break"></div>
<div class="flex-item f2">N</div>
<div class="flex-item f2">N</div>
</div>
.break {
flex-basis: 100%;
height: 0;
}
This uses flex-basis.
Have a look at this codepen for demo.
There is also the option to have add one more level of divs inside your container divs as parents to your flex-item. But overall I would suggest to use the dynamic width and not use these methods as they will only add complexity when your number of boxes are dynamic and will probably require some Js too.

Related

Incorrect size of flex child with an image

I have a similar case in my project:
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
.wrapper {
display: flex;
width: 600px;
height: 300px;
}
.container {
display: flex;
width: 100%;
}
img {
height: 100%;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="container">
<div class="image-wrapper">
<img src="https://placehold.co/200x600">
</div>
<h2>text</h2>
</div>
<div>
test
</div>
</div>
</body>
</html>
I have fixed width container (.container) that sets the height of its children to match its own height (due to align-items: stretch; by default). In one of those containers, I have an image (<img>) that I want to be the same height as its parent (.image-wrapper) while maintaining proportions. In the demo, that happens, but the .image-wrapper width is not updated. At least not always...
Sometimes, the image appears like this (incorrect):
...and sometimes, it appears like this (correct):
I think it has to do with the browser not updating the width of .image-wrapper. In the incorrect scenario, it has a width of 200 (the placeholder image's original size), but after the image is resized down to 100x300 (due to its height: 100% and its parent being 300px while having a natural size of 200x600) the parent's width is not updated to reflect that. It should change from 200 to 100, the image's now resized value.
One weird thing is that if the size is incorrect and you add width: 100% to .image-wrapper in the inspector and then remove it, its width is refreshed and is now displayed correctly.
If you download the snippet and open it in your browser, you should see that the image is displayed incorrectly until you open DevTools and disable cache. After that (because the image takes some time to load I guess), the width is set correctly upon refreshing.
This happens on latest Chrome, Firefox and IE11 on Windows 10. Here's a fiddle too.
Why does that happen? How to fix it?
As is, apparently this is a known bug in Chrome, but to my confusion I am also experiencing this in Firefox...
There is 2 solutions to this:
1)
img{
height: 100%;
width: 100px; /* Set a specific width to your image */
}
2) Apparently removing the image-wrapper div also solves this problem immediately.
.wrapper {
display: flex;
flex-flow: row nowrap;
flex-basis: 600px;
height: 600px;
}
.container {
display: flex;
height: 300px;
}
img {
height: 100%;
}
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div class="wrapper">
<div class="container">
<img src="https://placehold.co/200x600">
<h2>text</h2>
</div>
<div>
test
</div>
</div>
</body>
</html>
This might happen when you don't specify explicitly the size of the image; notably, this is a known bug in Chrome.
You can either:
Specify that in either the HTML width attribute, or the CSS width property:
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
.wrapper {
display: flex;
width: 600px;
height: 300px;
}
.container {
display: flex;
width: 100%;
}
img {
height: 100%;
width: 100px; /* 1st solution: you should use fixed width when using CSS */
}
</style>
</head>
<body>
<div class="wrapper">
<div class="container">
<div class="image-wrapper">
<img src="https://placehold.co/200x600" width="100"> <!-- 2nd solution -->
</div>
<h2>text</h2>
</div>
<div>
test
</div>
</div>
</body>
</html>
Use JavaScript to set the HTML width attribute to the actual image size at runtime:
// Give your image a proper ID
window.addEventListener('load', function () {
var img = document.getElementById('img');
// This sets the image's HTML width element
// Notice the self-assignment
img.width = img.width;
})
.wrapper {
display: flex;
width: 600px;
height: 300px;
}
.container {
display: flex;
width: 100%;
}
img {
height: 100%;
}
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div class="wrapper">
<div class="container">
<div class="image-wrapper">
<img src="https://placehold.co/200x600" id='img' />
</div>
<h2>text</h2>
</div>
<div>
test
</div>
</div>
</body>
</html>

text in right column is going below image in left column

EDIT: I was able to fix this problem by switching to a float based layout. Not sure if there is a solution to the problem using an inline-block based grid. (I suppose I could use the position:relative or absolute, but that seems to be a bad idea.) Here's my Codepen: https://codepen.io/mattgwater/pen/yXBqoe (It works if full-screen) Ehsan's answer demonstrates how to basically do this layout too and probably is a better example of good code.
I am trying to build a website based on the template in the picture here. https://assets.themuse.com/uploaded/attachments/14846.png?v=None
However, if I have an image in the left column it causes all the text in the right column to go below the image. How can I fix this problem?
Here is my Codepen: https://codepen.io/mattgwater/pen/yXBqoe?editors=1100#0
My HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/7.0.0/normalize.min.css">
<link rel="stylesheet" href="/Fonts/myFontsWebfontsKit/MyFontsWebfontsKit.css">
<link rel="stylesheet" href="/main.css">
</head>
<body>
<nav>
<div class="col left">
<div>
<h1 class="title">MATT GOLDWATER</h1>
</div>
</div><!--
--><div class="col right">
</div>
</nav>
<div class="nav-content-separator"></div>
<section>
<div class="col left">
<img class="profilepic" src="https://res.cloudinary.com/dyr8j9g6m/image/upload/v1496375439/my-headshot_bxpjqk.png" alt="Matt Goldwater">
<!--<p>yo</p>-->
</div><!--
--><div class="col right">
<p class="about">I want this sentence to be aligned with the top of the image.</p>
</div>
</section>
</body>
</html>
My CSS (I also have normalize CSS)
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
.title {
color: #6fc3c3;
/*font-family: FuturaDCD-Lig;*/
font-weight: bold;
font-size: 32px;
text-align: center;
letter-spacing: .05em;
}
.col {
width: 50%;
display: inline-block;
/*white-space: nowrap;*/
}
.left {
padding-left: 10%;
}
.profilepic {
padding-top: 7%;
height: 450px;
margin: 0 auto;
display: block;
}
.nav-content-separator {
border: 1px solid #e8e8e8;
}
.about {
font-family: Avenir;
}
I changed your code,use wrapper and float and other Properties.
#wrapper {
max-width: 1200px;
width: 100%;
margin: 0 auto;
}
.title {
color: #6fc3c3;
float: left;
}
.right {
float: right;
}
.left {
float: left;
}
ul {
list-style-type: none;
}
li {
display: inline-block;
margin-right: 1%;
}
li a {
color: #ccc;
text-decoration: none;
}
.col {
width: 50%;
box-sizing: border-box;
}
nav {
border-bottom: #ccc solid 1px;
overflow: auto;
}
.profilepic {
max-width: 410px;
width: 100%;
}
<div id="wrapper">
<nav>
<div class="col title"><h2>KRISTA GRAY</h2></div>
<div class="col right">
<ul>
<li>About</li>
<li>Services</li>
<li>Journal</li>
<li>FAQs</li>
<li>Contact</li>
</ul>
</div>
</nav>
<div class="container">
<div class="col left">
<img class="profilepic" src="https://cdn.shopify.com/s/files/1/1424/5850/products/Circular_Stickers_CG_1024x1024.jpg?v=1486690726" alt="Me">
</div>
<div class="right col">
<h4>Lorem Ipsum: common examples</h4>
<p>Lorem ipsum is a pseudo-Latin text used in web design, typography, layout, and printing in place of English to emphasise design elements over content. It's also called placeholder (or filler) text. It's a convenient tool for mock-ups. It helps to outline the visual elements of a document or presentation, eg typography, font, or layout. Lorem ipsum is mostly a part of a Latin text by the classical author and philosopher Cicero. Its words and letters have been changed by addition or removal, so to deliberately render its content nonsensical; it's not genuine, correct, or comprehensible Latin anymore. While lorem ipsum's still resembles classical Latin, it actually has no meaning whatsoever. As Cicero's text doesn't contain the letters K, W, or Z, alien to latin, these, and others are often inserted randomly to mimic the typographic appearence of European languages, as are digraphs not to be found in the original.
</p>
</div>
</div>
</div>
Few modifications in your code:
Give image max-width:100% so that image stay within the parent. Remove display:block from image style.
Add white-space:nowrap in the section style so that the whitespace is ignored. We need to ignore whitespace because .left and .right are set to width:50% and hence even a pixel of whitespace will break the layout.
Demo: http://jsfiddle.net/GCu2D/1952/
.profilepic {
padding-top: 7%;
max-width: 100%;
margin: 0 auto;
display: inline;
}
section {
white-space: nowrap;
}
See your col class have width of 50% and then you are also adding padding-left of 10%. So it is going more than 100%. Play with the col width, make it 40% and it should work.

Centered grid of dynamic cards (divs) with more block elements inside

I want a dynamically generated grid of fixed size cards to be horizontally centered in a container of variable width, basically this: https://foodgawker.com/
My question is similar to Center a grid of Divs (dynamically generated) or How to center a grid of divs? (the example is from there), except they both recomend using display: inline-block instead of float : left, which only works as long as there are no further block elements inside the cards.
Here is the example from the previous question with one block element added inside the card, the whole layout breaks: http://jsbin.com/vozusukigo/1/edit?html,css,output. Also the foodgawker.com uses float : left, not display: inline-block.
Here is a JS Bin for your convenience, I am grateful for any help.
EDIT: The last row should aligned to left as in the example. To my horror the accepted answer to similar question uses JQuery (and none of the flexbox answers have fixed size gaps).
These kinda solutions especially are made easy now thanks to the Flexbox concept in CSS3.
https://jsbin.com/vetanocaxi/1/edit?html,css,output
Having the same HTML, the CSS can be written as below
.ct {
background-color : #ffff00;
display: flex;
justify-content: flex-start; /* center if you want to the center */
align-items: center;
flex-wrap: wrap;
}
.el {
width : 50px;
height : 50px;
background-color : #ff9999;
margin : 5px;
display: flex;
justify-content: center; /* center inside flex items */
align-items: center; /* center inside flex items */
}
No floats required & even better you can easily have complex structure within individual flex items without effecting the outer layout structure.
.ct {
background-color : #ffff00;
display: flex;
justify-content: flex-start; /* center if you want to the center */
align-items: center;
flex-wrap: wrap;
}
.el {
width : 50px;
height : 50px;
background-color : #ff9999;
margin : 5px;
display: flex;
justify-content: center; /* center inside flex items */
align-items: center; /* center inside flex items */
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="ct">
<div class="el"><p>flex</p></div>
<div class="el"><p>flex</p></div>
<div class="el"><p>flex</p></div>
<div class="el"><p>flex</p></div>
<div class="el"><p>flex</p></div>
<div class="el"><p>flex</p></div>
<div class="el"><p>flex</p></div>
<div class="el"><p>flex</p></div>
<div class="el"><p>flex</p></div>
<div class="el"><p>flex</p></div>
<div class="el"><p>flex</p></div>
<div class="el"><p>flex</p></div>
</div>
</body>
</html>
Flexbox can be used to achieve this effect like this: http://jsbin.com/vunubuqobo/edit?html,css,output
Main assumption is a fixed width for all cards. A small nuisance is a bunch of media queries to set .center_wrapper's width right, but that is easy to overcome with Less/SCSS/etc.
Note: use jsbin link above to check out responsiveness.
.cards_wrapper {
background: red;
}
#media(min-width: 122px) {
.center_wrapper { width: 122px; }
}
#media(min-width: 296px) {
.center_wrapper { width: 244px; }
}
#media(min-width: 416px) {
.center_wrapper { width: 366px; }
}
#media(min-width: 524px) {
.center_wrapper { width: 488px; }
}
#media(min-width: 646px) {
.center_wrapper { width: 610px; }
}
.center_wrapper {
display: flex;
flex-wrap: wrap;
padding: 10px;
margin: 0 auto;
background: yellow;
}
.card {
height: 100px;
width: 100px;
border: 1px solid;
margin: 10px;
text-align: center;
}
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<div class="cards_wrapper">
<div class="center_wrapper">
<div class="card">
<img src="./Index - My ASP.NET MVC Application_files/noImageAvailable.png">
</div>
<div class="card">
<img src="./Index - My ASP.NET MVC Application_files/noImageAvailable.png">
</div>
<div class="card">
<p>block element</p>
<img src="./Index - My ASP.NET MVC Application_files/noImageAvailable.png">
</div>
<div class="card">
<img src="./Index - My ASP.NET MVC Application_files/noImageAvailable.png">
</div>
<div class="card">
<img src="./Index - My ASP.NET MVC Application_files/noImageAvailable.png">
</div>
<div class="card">
<img src="./Index - My ASP.NET MVC Application_files/noImageAvailable.png">
</div>
<div class="card">
<img src="./Index - My ASP.NET MVC Application_files/noImageAvailable.png">
</div>
<div class="card">
<img src="./Index - My ASP.NET MVC Application_files/noImageAvailable.png">
</div>
<div class="card">
<img src="./Index - My ASP.NET MVC Application_files/noImageAvailable.png">
</div>
<div class="card">
<img src="./Index - My ASP.NET MVC Application_files/noImageAvailable.png">
</div>
</div>
</div>
</body>
</html>
To be honest I can't see any problem by using display: inline-block and have block elements inside the repeating divs. Also aligning the last row to the left is simple and doesn't require a single line of JavaScript or any complex workarounds.
According to the link you have posted you could achieve the layout with the following HTML structure and CSS code
body {
background: #eee;
}
#wrapper {
font-size: 0;
padding: 10px 0;
}
.item {
width: calc(25% - 4px);
background: white;
overflow: hidden;
border-radius: 3px;
display: inline-block;
font-size: initial;
margin: 2px;
}
p {
padding: 4px 20px;
}
img {
width: 100%;
}
<div id="wrapper">
<div class="item">
<img src="https://photo.foodgawker.com/wp-content/uploads/2016/12/2845923.jpg" alt="" />
<p>All the nutty deliciousness of pecan pies - these no bake Rice Krispie Pecan Pie Cookies are vegan-friendly & dairy-free friendly!</p>
</div>
<div class="item">
<img src="https://photo2.foodgawker.com/wp-content/uploads/2016/12/2845735.jpg" alt="" />
<p>This Barbecue Chicken Cornbread Casserole is an easy dinner that comes together in just 15 minutes!!</p>
</div>
<div class="item">
<img src="https://photo.foodgawker.com/wp-content/uploads/2016/12/2845542.jpg" alt="" />
<p>Vegan Meringue Kisses, made using aquafaba</p>
</div>
<div class="item">
<img src="https://photo2.foodgawker.com/wp-content/uploads/2016/12/2845725.jpg" alt="" />
<p>Healthy spicy creole pulled pork made in the slow cooker! {Gluten Free, Dairy Free, Paleo}</p>
</div>
<div class="item">
<img src="https://photo.foodgawker.com/wp-content/uploads/2016/12/2845855.jpg" alt="" />
<p>Praline chocolates with a crispy dark chocolate coating and a soft caramelized nuts filling. Chocolatey, nutty and insanely delicious!</p>
</div>
</div>

CSS div with margin moving everything

Below is my code for a simple page. I'm trying to have (A) a banner on the top which consists of a logo, a header to its right and then a "sign in/register" link, (B) below all this then I will have the main text of the site.
I would like a large gap between the main text and banner at the top. So I divide the page up with divs. But when I apply a "margin-top" to #main to keep the banner at a certain distance, EVERYTHING, that is, the main text and everything in my banner all move down the page. Same thing happens if I apply a "margin-bottom" to the header element.
I'm kind of new to CSS and HTML but I though I had the hang of it until this. I've scratched my head for ages about this but I can't seem to understand positioning here at all!
<!DOCTYPE html>
<html lang="en">
<head>
<link href="style.css" rel="stylesheet" type="text/css"/>
<meta charset="utf-8"/>
<title>My Page</title>
</head>
<body>
<header id="masthead" role="banner">
<img src="jep.jpeg" alt="My Page">
<h2>Welcome!</h2>
<p>Sign in Register</p>
</header>
<div id="main" role="main">
<!--main text here -->
</div>
</body>
</html>
Here is the CSS code:
#masthead {
position: relative;
}
#masthead img {
position: absolute;
}
#masthead h2 {
position: absolute;
left: 150px;
}
#masthead p {
position: absolute;
right: 10px;
}
#main {
margin-top: 40px;
}
The problem is that all of the absolute positioning removes the elements from the document flow. That means your header has a height of 0px, but everything is still positioned relative to it.
Just give your masthead a height.
JSFiddle
You just need to wrap your elements in their own containers so you can position them a little bit better. You will probably want to define some heights in this also. Including a height on #masthead
Assuming you need a responsive design:
<header id="masthead" role="banner">
<section class="logo">
<img src="jep.jpeg" alt="My Page">
</section>
<section class="title">
<h2>Journal of Electronic Publishing</h2>
</section>
<section class="sign-in">
Sign in Register
</section>
</header>
.logo {
width: 30%;
float: left;
margin-right: 5%;
box-sizing: border-box;
}
.title {
width: 30%;
float: left;
margin-right: 5%;
box-sizing: border-box;
}
.sign-in {
width: 30%;
float: left;
margin-right: 0;
box-sizing: border-box;
}
Note that the total 100% is assuming you include the margins in that calculation. So, 30+30 = 60 + 5 + 5 = 70 + 30 = 100%
Edit: Now that I can see your CSS, your specific issue is the use of position:absolute;. Removing these should get you along the correct path.
I suggest using a table layout. Using 1-row tables for styling is a bit frowned upon by some, but this seems to work:
HTML:
<body>
<header id="masthead" role="banner">
<table>
<tr>
<td><img src="jep.jpeg" alt="My Page"></td>
<td><h2>Welcome!</h2></td>
<td><p>Sign in Register</p></td>
</tr>
</table>
</header>
<div id="main" role="main">
<p>Testing</p>
</div>
</body>
</html>
and CSS:
#masthead {
width: 100%;
}
#masthead table {
width: 100%;
}
#main {
margin-top: 40px;
}
EDIT: Using divs.
This is a bit messy, but it works. It's been a while since I've used div for positioning like this.
HTML:
<body>
<header>
<div class="col">
<div class="content">
<img src="jep.jpeg" alt="My Page">
</div>
<div class="content">
<h2>Welcome!</h2>
</div>
<div class="content">
<p>Sign in Register</p>
</div>
</div>
</header>
<div id="main" role="main">
Testing
</div>
</body>
</html>
CSS:
header {
width: 100%;
}
.col {
height: 100px;
position: relative;
}
.content {
float: left;
width: 33.3%;
}
#main {
margin-top: 50px;
}

Variable body width

I have a simple HTML page with 3 "columns" (300px x 100%) that all have a vertical scrollbar. This works fine when having a window of at least 900 pixels in width. However, when I resize the window to be smaller than the columns take, one (or more) of the columns jump down to fit the window vertically. This is not what I want, because it would require the user to scroll all the way down before being able to see the other column.
What I want is pretty simple: a way to force the browser to fit the columns horizontally, even if it doesn't fit. width: 900px; on the body isn't a solution I want to use because the number of columns (and their width) is variable.
In other words: how do I force a browser to put my elements horizontally on a page and stop moving elements?
[edit]
My current code (well, it's not the actual code, but it does show what the problem is):
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
* {
margin: 0;
padding: 0;
}
body, html {
height: 100%;
}
body {
overflow-x: scroll;
}
.column {
width: 300px;
height: 100%;
float: left;
overflow-x: hidden;
overflow-y: scroll;
}
</style>
</head>
<body>
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
</body>
</html>
The three "columns" need to be in a single container with the container's CSS set to 'nowrap'
<div style='white-space: nowrap;'>
<div id='col1'></div>
<div id='col2'></div>
<div id='col3'></div>
</div>
<!DOCTYPE html>
<html>
<head>
<style>
* { margin: 0px; padding: 0px; }
body, html { height: 100%; }
body {
overflow-x: scroll;
white-space: nowrap; // prevent 'text' from wrapping
}
.column {
display:inline-block; // make them behave like 'text'
width: 300px; height: 100%;
overflow-x: hidden; overflow-y: scroll;
}
</style>
</head>
<body>
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
</body>
</html>
AFAIK there's no cross browser way to force semantic columns (without JavaScript).
here is the answer I gave to a similar question.
HTML:
<div class="parent">
<div class="child">...</div>
<div class="child">...</div>
<div class="child">...</div>
</div>
CSS
.parent
{
display: table-row;
}
.child
{
display: table-cell;
width: 300px;
}
I believe IE < 9 has issues with this, so you'll need to set the sizing and positioning manually with JS for IE.

Resources