Flexbox in css grid: how to position the flex items - css

I am new to using flexbox to position items within a css grid layout. The grid layout is three large cells 10%, 35% and 55% of viewport. In the second grid cell (marked "b"), I use flexbox to position a header and a subheader.
My problem is that I am not able to accurately position the header and subheader within the grid cell "b". Also, the header is takes up too much space in the vertical direction, thereby pushing the subheader too low.
Here is the html code:
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<title>Welcome to Project</title>
<link href="css/main.css" rel="stylesheet" type="text/css">
</head>
<body class="site">
<div class="grid">
<div class="a">
<div class="a_left">
<div>Logo for Project</div>
<div class="topnav">
<a class="active" href="#home">Home</a>
News
Contact
About
</div>
</div>
</div>
<div class="b">
<div class="b_left">
<h1>This is the main header, it's longer than the subheader</h1>
</div>
<div class="b2_left">
<h3>This is the subheader</h3>
</div>
</div>
<div class="c">
<h2>This is grid-template-row c</h2>
</div>
</div>
</body>
</html>
Here is the css code:
#charset "utf-8";
body{
background-color: black;
margin-top: 0;
margin-bottom: 0;
margin-left: 0;
margin-right: 0;
}
.grid {
display: grid;
width: 100vw;
height: 100vh;
grid-template-rows: 10% 35% 55%;
}
.grid > * {
background-color: darkgray;
color: white;
padding: 2em;
}
.a{
display: grid;
background-color: lightgray;
font-family: sans-serif;
color: green;
font-size: 16pt;
}
.a_left{
display: flex;
text-align: left;
vertical-align: left;
flex-wrap: nowrap;
justify-content: space-between;
}
.a_right{
display: flex;
height: 100%;
flex-wrap: nowrap;
justify-content: right;
vertical-align: right;
}
.b{
display: grid;
background-color: white;
font-family: sans-serif;
color: blue;
font-size: 16pt;
}
.b_left{
display: flex;
flex-flow: row;
flex-grow: 0;
text-align: left;
vertical-align: left;
flex-wrap: nowrap;
justify-content: left;
height: 0px;
max-height: 0px;
flex-direction: row;
align-items: flex-start;
}
.b2_left{
display: flex;
flex-flow: row;
flex-grow: 0;
text-align: left;
vertical-align: left;
flex-wrap: nowrap;
justify-content: left; /*space-between*/
height: 0px;
max-height: 0px;
flex-direction: row;
align-items: flex-start;
}
.c{
display: grid;
background-color: black;
font-family: sans-serif;
color: black;
font-size: 16pt;
}
li {
display: inline;
}
site-nav{
margin-top: 0px;
}
.topnav {
align-content: right;
justify-content: center;
overflow: hidden;
background-color: #333;
height: 100%
}
.topnav a {
float: left;
color: #f2f2f2;
padding: 14px 16px;
text-decoration: none;
font-size: 17px;
}
.topnav a:hover {
background-color: #ddd;
color: black;
}
.topnav a.active {
background-color: #4CAF50;
color: white;
}
h1{
color: blue; /*deepskyblue;*/
font-family: sans-serif;
font-size: 28pt;
text-indent: 30px;
height: 0vh; /*0px*/
width: auto;
}
h2{
color: lightgray; /*deepskyblue;*/
font-family: sans-serif;
font-size: 12pt;
text-indent: 12px;
}
h3{
color: gray;
font-family: sans-serif;
font-size: 18pt;
text-indent: 85px;
}
a:link { color: green; }
a:visited { color: blue; }
a:hover { color:red; }
.site{
max-width: 100%;
max-height: 100%;
display: grid;
}
My questions are: (1) how can I precisely position the starting point of each of the header (within b_left) and subheader (within b2_left), and (2) how do I set the max height for the flex container that holds each of the two.
I have done a lot of research on this, and I have mixed and matched properties, but flexbox and grid both have a lot of properties and I still haven't found the right combo.
Thanks very much for any help.
EDIT: one possibility is to use position: absolute for each, and on the subheader set top: 150px, but I hope there is any way to do this without absolute positioning.

(1) how can I precisely position the starting point of each of the header (within b_left) and subheader (within b2_left:
The starting point is given with the properties of justify-content (start, between, end).
Second, I dont get it correctly, do you want to position the header above the subheader with flexbox?
If yes, maybe you want to set flex-direction: column; because this put all elements inside one above another.
In this link you can find more information about justify-content an its posible values
how do I set the max height for the flex container that holds each of the two.
I'm not sure if flexbox admit max height configuration, because its height is calculated depending on container's size.
Hope this can help you.

Related

CSS Flexbox: Gettings headings with background colors to fit the text

I'm trying to get and h1 and h2 to have background colors around the text. Because it's Flexbox, the background colors fill the entire row, not just the text.
I added display: inline; to each heading. Now the background colors fit the text, but because the display is no longer flex, the text is next to one another instead of the H2 being underneath.
Not sure what to do here. The actual page is here: https://www.ihfanh.com/
Here's a simplified version of the HTML and CSS.
<section>
<div>
<h1>This is a heading one</h1>
<h2>This is a heading 2</h2>
</div>
</section>
CSS
section { display: flex; flex-direction: column; }
div { -webkit-flex: 1; flex: 1; }
h1, h2 { display: inline; }
h1 { background: #F00; color: #FFF; font-size: 60px; padding: 8px 24px; }
h2 { background: #554c55; color: #FFF; font-size: 30px; margin-top: 16px; padding: 8px 24px; }
Add width: fit-content; instead of display: inline
section { display: flex; flex-direction: column; }
div { -webkit-flex: 1; flex: 1; }
h1, h2 { width: fit-content;}
h1 { background: #F00; color: #FFF; font-size: 60px; padding: 8px 24px; }
h2 { background: #554c55; color: #FFF; font-size: 30px; margin-top: 16px; padding: 8px 24px; }
<section>
<div>
<h1>This is a heading one</h1>
<h2>This is a heading 2</h2>
</div>
</section>

Align text vertically to middle not taking affect

I need to align text near an icon to middle.
See the admin word near the user icon in this sandbox:
https://codesandbox.io/s/fragrant-morning-267l5
I have this css, but it's not taking affect:
.HeaderToolbar {
background-color: black;
color: white;
fill: white;
width: 100%;
margin: 0 auto;
align-items: baseline;
vertical-align: middle;
/*white-space: nowrap;*/
}
I would suggest you to use elements like header, nav and div for layout along with flexbox instead of going for table to layout your header.
Please check following code. It shows basic mark up for header component with navigation and logo.
header {
width: 100vw;
height: 54px;
}
.header {
width: 100%;
max-width: 1000px;
margin: 0 auto;
display: flex;
align-items: center;
padding: 0 8px;
}
.logo {
flex: 1;
}
nav {
flex: 2;
display: flex;
justify-content: flex-end;
}
button {
padding: 8px 12px;
color: white;
border: none;
cursor: pointer;
}
.ghost {
color: black;
background: transparent;
}
<header>
<div class='header'>
<div class="logo">
<h2>Logo</h2>
</div>
<nav>
<button>Projects</button>
<button>Projects</button>
<button class='ghost'>Admin 😳</button>
<button>Profile</button>
</nav>
</div>
</header>
You need to add a class to your element and then add a css to your class:
display: flex;
justify-content: flex-start;
align-items: center;

How to arrange elements vertically with flexbox and css

I have three elements in my HTML that I would like to arrange vertically (stacked if you will), regardless of size (which is dynamic for some of the elements).
I have tried using flexbox and the usual advice on the net but it does not seem to work.
.intro {
font-family: monospace;
font-size: 24px;
color: #455934;
padding-top: 25px;
padding-right: 50px;
padding-bottom: 5px;
padding-left: 50px;
align-self: flex-start;
}
.recipe {
background-color: rgba(255, 255, 255, .6);
margin: auto;
min-height: 400px;
height: auto !important;
height: 400px;
width: 75%;
box-sizing: border-box;
display: flex;
display: -ms-flexbox;
display: -webkit-flex;
flex-direction: column;
-webkit-flex-direction: column;
align-items: flex-start;
-webkit-align-items: flex-start;
justify-content: left;
}
.recipe a:link,
a:visited,
a:active {
color: #cda44c;
font-family: monospace;
font-size: 18px;
padding-top: 5px;
padding-right: 50px;
padding-bottom: 5px;
padding-left: 50px;
align-self: flex-start;
}
.recipe a:hover {
color: white;
align-self: flex-start;
}
.recipe_image {
padding-top: 5px;
}
<div class="recipe">
<p class="intro">
{{label}}
</p>
<a href='test.html'>
Rezept von {{source}}
</a>
<br>
<a href='test.html'>
<img src='C:/users/fabian.nguyen/03 - Customer Analytics/Bots/Flask Test/static/rock.gif' alt="TEST" class="recipe_image">
</a>
</div>
You can see the resulting HTML (rendered via Flask but that is not the issue) here:
https://nachhaltig-kochen.herokuapp.com/getrecipe
Instead of stacking into a column (1. Label 2. Text-Link 3. Image-Link) they arrange in a row of equally sized divs.
EDIT:
Thanks to Pete, the solution is simply to remove any flex box reference as the elements should (and do) naturally stack vertically without any other style.

Two-column card layout for desktop and mobile

Here's my fiddle: https://jsfiddle.net/b6q7pmkg/
I'm trying to achieve two-column cards where it always stays two column regardless on mobile or desktop.
So something like this:
On desktop:
On mobile:
Here's what I have so far.. but not quite there..
.cardContainer {
max-width: 30rem;
}
css:
.root {
display: inline-block;
width: 100%;
border: 1px solid rgb(221, 221, 221);
color: rgb(90, 90, 90);
}
.link {
vertical-align: bottom;
text-decoration: none;
cursor: pointer;
}
.imageContainer{
display: inline-block;
vertical-align: top;
width: 40%;
}
image {
-o-object-fit: cover;
object-fit: cover;
width: 100%;
height: auto;
display: block;
}
.content {
display: inline-block;
vertical-align: top;
width: 60%;
padding: 1rem;
}
.large .title {
font: 400 1.1875rem/1.263 'Avenir Next W01', 'Helvetica Neue', 'Helvetica', 'sans-serif';
font-size: 1.1875rem;
line-height: 1.263;
letter-spacing: 0.0125rem;
font-weight: 700;
}
.body {
margin-top: 1rem;
color: rgb(139, 139, 139);
display: block;
}
.description {
margin-bottom: 0;
font-size: inherit;
margin-top: 1rem;
}
Here's a model with a basic css.
The important thing to know here is the double flexbox; one flexbox for card (img/paragraph), and one flexbox for all the cards, with a flex-wrap: wrap; to make sure they're doing their job right.
I use this flexbox cheat sheet to remember exactly how flexbox works :)
Here's a copy of the jsfiddle code :
section{
display: flex;
flex-wrap: wrap;
}
article{
display: flex;
flex-direction: row;
border: 1px solid black;
width: 300px;
}
<section>
<article>
<img src="http://lorempixel.com/150/100/" />
<p>
Some text.
</p>
</article>
<article>
<img src="http://lorempixel.com/151/100/" />
<p>
Some text.
</p>
</article>
<article>
<img src="http://lorempixel.com/150/101/" />
<p>
Some text.
</p>
</article>
</section>
edit: I just made an edit of the fiddle with grey text and vertically centered paragraphs :)
You can do this with CSS Grid as well:
Put all of your cards in a <div class="grid-container">, add the following lines in your CSS:
.grid-container{
display: grid;
grid-gap: 20px; /*that's optional, for the space between your cards*/
grid-template-columns: repeat(auto-fit, 300px);
}

Flex-box ignores wrapped children's margin (margin collapse)

Given the following HTML:
<div class="outer">
<div>
<div class="inner">A</div>
</div>
</div>
<div class="outer">
<div class="inner">B</div>
</div>
and the following CSS (prefix free):
.outer {
display: box;
box-orient: vertical;
height: 100px;
width: 100px;
background: red;
margin: 10px;
}
.inner {
height: 50px;
margin-top: 10px;
background: green;
}
Here is a CodePen.
A is wrapped in a <div> so it's margin gets ignored.
Q: How can I achieve B's behavior for A (margin) with the flex box model?
Note: The div wrappers can go multiple levels deep
Targeting: latest Chrome/Safari/iOS
Thank you very much for your help!
Edit: Thanks to #JoséCabo I came up with this:
.outer {
display: flex;
flex-direction: column;
height: 100px;
width: 100px;
background: red;
margin: 10px;
}
.inner {
height: 50px;
margin-top: 10px;
background: green;
}
CodePen
Chrome:
Safari:
Unfortunately it doesn't work in Safari as mentioned by #cimmanon, so I still need some help.
What you're looking at actually has nothing to do with Flexbox, but what's called margin collapse
.outer div {
border: 1px solid;
}
The addition of the border has prevented the margin from collapsing. Rather than relying on margins, I would recommend placing a padding on the parent container:
.outer {
padding-top: 10px;
}
Example:
.wrapper {
background: #eef;
border: 1px solid darkgray;
}
.container {
display: flex;
flex-wrap: wrap;
margin: -1em;
}
.item {
flex-grow: 1;
margin: 1em;
border: 1px solid black;
padding: 1em;
min-width: 6em;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div class="wrapper">
<div class='container'>
<div class='item'>item</div>
<div class='item'>item</div>
<div class='item'>item</div>
<div class='item'>item</div>
<div class='item'>item</div>
<div class='item'>item</div>
</div>
</div>
</body>
</html>
Now, to cover all of your prefixes, you need something like this:
.outer {
display: -moz-box;
display: -webkit-flexbox;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-moz-box-orient: vertical;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
height: 100px;
width: 100px;
background: red;
margin: 10px;
}
Finally I came up with the right solution (for my specific problem).
.outer {
display: flex;
flex-direction: column;
height: 100px;
width: 100px;
background: red;
margin: 10px;
}
.inner {
height: 50px;
margin-top: 10px;
background: green;
display: inline-block;
width: 100%;
}
CodePen
I'm using display: inline-block on .inner to disable margin collapsing and then compensate for the lost width with width: 100%.
All the credit goes to cimmanon for pointing me in the right "margin collapse" direction

Resources