I am trying to put together a diagram in CSS of a flow chart. I have attached below a picture. Is there a simple way to do this? I've been Googling around quite a bit looking for examples, but I don't know what to call this.
Can you please let me know how to do this? Or if this is something common, what I can Google to find more information.
By using CSS Flex you could achieve something like:
body {font: 16px/1.4 sans-serif;}
.chart-row,
.chart-col {
display: flex;
gap: 1em;
}
.chart-row {
flex-direction: row;
}
.chart-col {
flex-direction: column;
}
.chart-pill,
.chart-rect{
padding: 1em;
text-align: center;
border: 2px solid #999;
}
.chart-pill {
flex: 1;
border-radius: 1em;
border-style: dashed;
}
.chart-rect{
flex: 0;
margin: auto 0;
background: #eee;
}
.chart-line-h {
height: 2px;
min-width: 3em;
background: #999;
margin: auto -1em;
}
<div class="chart-row">
<div class="chart-pill chart-col">
<div class="chart-rect">alpha</div>
</div>
<div class="chart-line-h"></div>
<div class="chart-pill chart-col">
<div class="chart-rect">beta</div>
<div class="chart-rect">gamma</div>
<div class="chart-rect">delta</div>
</div>
<div class="chart-line-h"></div>
<div class="chart-pill chart-col">
<div class="chart-rect">gamma</div>
</div>
</div>
I'll just add an answer because I can't write any comments yet, although I'm not new at CSS...
Yes, you can use Flexbox but I will also add CSS Grid, as the combination of both can give you more flexibility if you're planning on making bigger charts...
Once you get it working, it's pretty easy to use...
Copy and paste this code in your code editor and display it in your browser.
( if you use VSCode you can use the liveServer extension)
Then go to the dev tools inside your browser (Ctrl+Shift+i) and click the icon to select an element (the one on top at the very left hand side).
Then, inside the first div, you will see a label with the word grid, click it and you'll see the grid on your screen.
Finally, you just have to fill the rows and columns with the figures as in one of those old battleship games, or a 2D Cartesian Coordinate System.
Keep in mind that when placing your items on the Grid, it's better to use the lines instead of the areas of the rows and columns, as it's much easier to understand it this way.
So for instance, in this case, connector1 goes from vertical line 9 to vertical line 10, or the first figure fills the space between line 5 and line 9, and so on.
Hope it helps!
By the way, I changed colours as it's easier for the explanation..
HTML :
<!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="styles.css">
<title>Document</title>
</head>
<body>
<!-- GRID FLOWCHART -->
<div class="flowchart">
<!-- FIRST FIGURE -->
<div class="set" id="set1">
<div class="box"><p>alpha</p></div>
</div>
<!-- FIRST CONNECTOR -->
<div class="connector" id="connector1"></div>
<!-- SECOND FIGURE -->
<div class="set" id="set2">
<div class="box"><p>beta</p></div>
<div class="box"><p>gamma</p></div>
<div class="box"><p>delta</p></div>
</div>
<!-- SECOND CONNECTOR -->
<div class="connector" id="connector2"></div>
<!-- THIRD FIGURE -->
<div class="set" id="set3">
<div class="box"><p>gamma</p></div>
</div>
</div>
</body>
</html>
CSS :
body {
width: 100vw;
height: 100vh;
background-color: #d3d3d3;
}
/* ****** GENERIC SHAPES : ********** */
.flowchart {
display: grid;
grid-template-columns: repeat(24, 1fr);
grid-template-rows: repeat(12, 1fr);
width: fit-content;
height: fit-content;
grid-gap: 2px;
}
.set {
min-width: 100px;
min-height: 100px;
border: 2px dashed blue;
border-radius: 15px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.box {
width: 80%;
height: 15%;
background-color: rgb(255, 255, 255);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin: 4%;
padding: 6%;
border: 1px solid black;
/* border-radius: 5px; */
font-family: Verdana, Geneva, Tahoma, sans-serif;
font-size: 0.9em;
}
.connector {
width: 120%;
max-height: 3px;
background-color: black;
transform: translateX(-6%);
}
/* ************* FIGURES : ************* */
#set1 {
grid-column: 5/9;
grid-row: 5/12;
}
#set2 {
grid-column: 10/14;
grid-row: 5/12;
}
#set3 {
grid-column:15/19;
grid-row: 5/12;
}
/* ******** CONNECTORS : *********** */
#connector1 {
grid-column: 9/10;
grid-row: 8/9;
}
#connector2 {
grid-column: 14/15;
grid-row: 8/9;
}
Related
I have five rows in a grid layout.
There is a header row at the top.
I want the content row to fill everything it can of the available space.
I want the footer row to be at the bottom.
Between the header, content and footer rows I have two rows which just adds height spacing at 15px.
Here is HTML-code:
<!DOCTYPE html>
<html lang="en">
<head>
<title>App</title>
<link rel="stylesheet" href="styles.css">
</head>
<body class="body">
<div class="headerRow">
<div>Title</div>
<div>Fill</div>
<div>Image</div>
</div>
<div style="height: 15px;"></div>
<div>
content
</div>
<div style="height: 15px"></div>
<div class="footerRow">
<div>foo</div>
<div>bar</div>
</div>
</body>
</html>
Here is my CSS-code:
.body {
margin: 15px;
background: lime;
display: grid;
grid-template-rows: auto auto 1fr auto auto;
}
.headerRow {
display: grid;
grid-template-columns: auto 1fr auto;
background-color: #2196F3;
}
.footerRow {
display: grid;
grid-template-columns: auto auto;
background-color: red;
}
I got my "headerRow" to show three columns with the middle column to fill every available space with this line in the CSS:
grid-template-columns: auto 1fr auto;
So I tried this line in the .body-block in my CSS:
grid-template-rows: auto auto 1fr auto auto;
But that didn't work :'(
What is the problem?
Maybe like this:
html, body {
margin: 0;
padding: 0;
height: 100%;
}
.container {
margin: 15px;
background: lime;
display: grid;
grid-row-gap: 15px;
align-content: space-between;
height: 100%;
}
.headerRow {
display: grid;
grid-template-columns: auto 1fr auto;
background-color: #2196F3;
justify-items: center;
}
.footerRow {
display: grid;
grid-template-columns: auto auto;
background-color: red;
justify-content: space-between;
}
<!DOCTYPE html>
<html lang="en">
<div class="container">
<head>
<title>App</title>
<link rel="stylesheet" href="styles.css">
</head>
<body class="body">
<div class="headerRow">
<div>Title</div>
<div>Fill</div>
<div>Image</div>
</div>
<div>
content
</div>
<div class="footerRow">
<div>foo</div>
<div>bar</div>
</div>
</div>
</body>
</html>
Why not use hr tag for adding space instead of another rows. Also if you want to make the three columns inside headerRow, Try adding float : left or adding columns from bootstrap would solve your problem.
I have some follow up questions after trying #Nikola Pavicevic solution:
Question 1:
In the html, body CSS-block the height: 100% seems to do the trick for me.But it makes the page in my web browser to have a vertical scrollbar.This scrollbar seems to be needed to show the "footer"-row.Is there anyway to decrease the height of the content row so the header row and footer row is always displayed?
Question 2:
The "content-row" seems to not fill all space available in the page.
I can see this by putting a background in the "content-row".
Is there a way to make sure the "content-row" fills all available space?
But keeps the "header-row" and "footer-row" visible.
Updated HTML:
<!DOCTYPE html>
<html lang="en">
<div class="container">
<head>
<title>App</title>
<link rel="stylesheet" href="styles.css">
</head>
<body class="body">
<div class="headerRow">
<div>Title</div>
<div>Fill</div>
<div>Image</div>
</div>
<div class="spacerRow"></div>
<div class="contentRow">
content
</div>
<div class="spacerRow"></div>
<div class="footerRow">
<div>foo</div>
<div>bar</div>
</div>
</div>
</body>
</html>
Updated CSS
html, body {
margin: 0;
padding: 0;
height: 100%;
}
.container {
margin: 15px;
background: lime;
display: grid;
align-content: space-between;
height: 100%;
}
.headerRow {
display: grid;
grid-template-columns: auto 1fr auto;
background-color: #2196F3;
justify-items: center;
}
.footerRow {
display: grid;
grid-template-columns: auto auto;
background-color: red;
justify-content: space-between;
}
.spacerRow {
height: 15px;
background-color: yellow;
}
.contentRow {
background-color: purple;
}
Auto-fit and auto-fill in CSS grid not working correctly, grid should generate new rows when screen width gets smaller. instead, the track gets smaller and never generates new rows.
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
.grid{
outline: 3px solid;
width: 90%;
height: 50px;
margin: 90px auto;
display: grid;
align-items: stretch;
grid-template-columns: repeat( auto-fit, minmax(300px,1fr));
grid-auto-flow: column;
}
.grid__item {
/--height: 100px/
background: dodgerblue;
font-family: sans-serif;
color: #fff;
text-align: center;
/*width: 300px;
height: var(--height);
line-height: var(--height);*/
}
.grid__item--one{
}
.grid__item--second{
background: darkorange;
}
.grid__item--third{
background: slateblue;
}
.grid__item--fourth{
background: tomato;
}
<section class="grid">
<div class="grid_item grid_item--one">#1</div>
<div class="grid_item grid_item--second">#2</div>
<div class="grid_item grid_item--third">#3</div>
<div class="grid_item grid_item--fourth">#4</div>
</section>
Why CSS grid no generate automatically the new rows? I follow YouTube tutorials and documentation on the internet and nothing appears to works.
Why CSS grid no generate automatically the new rows? I'm following YouTube tutorials. and documentation on the internet. and nothing appears to work. Do I need to update on anything?
It is because of the property grid-auto-flow. By mentioning this property you are telling CSS to alter the default auto-flow algorithm. This results in giving all the min-width (300px) to at-least one element when screen size gets smaller.
Removing it made it behave as expected, here is the code:
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
.grid{
outline: 3px solid;
width: 90%;
height: 50px;
margin: 90px auto;
display: grid;
grid-template-columns: repeat( auto-fill, minmax(300px,1fr));
}
<section class="grid">
<div class="grid_item grid_item--one">#1</div>
<div class="grid_item grid_item--second">#2</div>
<div class="grid_item grid_item--third">#3</div>
<div class="grid_item grid_item--fourth">#4</div>
</section>
Please check your HTML code since you are using BEM notation you missed an underscore in your grid items.
So I am teaching myself HTML and gave myself a little project that involved having a sidebar with a lot of menu items (34). To do this I used a column flexbox inside of a CSS grid. I expected the sidebar to be implemented with a scrollbar, which I did manage to do, but it cuts off the first and last few menu items and I have no idea why. I've looked all over for an explanation for this but, I can't find anything related to this particular issue.
I've tried changing out the elements I use for the menu items (h2, div, p,...) but the problem remains, even using the least space consuming element. I've looked up flexbox properties and still I can't find anything relevant.
I'm wondering now if it is even a good idea to use flexbox inside of a CSS grid. Am I missing something obvious? Is the approach I'm taking advisable?
As I said, I've just started teaching myself and I would really appreciate any feedback from more experienced programmers out there.
Thanks.
An image of the problem with my scrollbar
/* General elements styles. */
body {
margin: 0;
padding: 0;
}
h1,h2 {
text-align: center;
vertical-align: bottom;
/* padding: 3px; */
}
/* Main CSS grid to organise the shape of the webpage. */
.grid {
display: grid;
grid-template-columns: repeat(9,1fr);
grid-template-rows: repeat(9,1fr);
height: 100vh;
width: 100vw;
align-content: center;
justify-content: center;
background-color: black;
}
.grid-item {
border: thin solid black;
border-collapse: collapse;
background-color: white;
}
.grid-item-1 {
grid-column: 1 / -1;
grid-row: 1 / 2;
background-color: green;
}
.grid-item-2 {
grid-column: 1 / -1;
grid-row: 2 / 3;
background-color: red;
}
.grid-item-3 {
grid-column: 1 / 3;
grid-row: 3 / 10;
background-color: goldenrod;
}
.grid-item-5 {
grid-column: 3 / 10;
grid-row: 3 / 10;
}
/* Flexbox for the main menu navigation bar. */
.nav-flexbox {
display: flex;
justify-content: center;
flex-wrap: wrap;
}
.nav-flexbox-item {
flex-basis: 200px;
flex-direction: row;
margin: 0px;
border: thin solid black;
min-height: 50px;
flex-grow: 1;
}
/* Flexbox for the subtopic sidebar. */
.sidebar-flexbox {
display: flex;
flex-direction: column;
justify-content: center;
flex-wrap: nowrap;
height: 100%;
overflow-y: auto;
}
.sidebar-flexbox-item {
flex-basis: 15px;
min-width: 130px;
margin: 0px;
border: 3px solid grey;
border-collapse: collapse;
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Learning Italian Webpage</title>
<base>
<link rel="stylesheet" href="Test.css">
<meta charset="UTF-8">
<meta name="viewport" content="width:device-width, initial-scale:1.0">
<script></script>
<style></style>
</head>
<body>
<div class="grid">
<div class="grid-item grid-item-1">
<h1>Learning Italian with Deep Learning</h1>
</div>
<div class="grid-item grid-item-2 nav-flexbox">
<h2 class="nav-flexbox-item nav-flexbox-item-1">Grammar Notes</h2>
<h2 class="nav-flexbox-item nav-flexbox-item-2">Vocab Lists</h2>
<h2 class="nav-flexbox-item nav-flexbox-item-3">Verb Conjugations</h2>
</div>
<div class="grid-item grid-item-3 sidebar-flexbox">
<h2 class="sidebar-flexbox-item">Subject Pronouns</h2>
<h2 class="sidebar-flexbox-item">Present Tense</h2>
<h2 class="sidebar-flexbox-item">Negative Sentences</h2>
<h2 class="sidebar-flexbox-item">Conjunctions</h2>
<h2 class="sidebar-flexbox-item">Object Pronouns</h2>
<h2 class="sidebar-flexbox-item">Other Pronouns</h2>
<h2 class="sidebar-flexbox-item">Modal Verbs</h2>
<h2 class="sidebar-flexbox-item">Interrogative Sentences</h2>
<h2 class="sidebar-flexbox-item">Present Perfect Tense</h2>
<h2 class="sidebar-flexbox-item">Future Tense</h2>
<h2 class="sidebar-flexbox-item">Adjectives</h2>
<h2 class="sidebar-flexbox-item">Present Progressive Tense(s)</h2>
<h2 class="sidebar-flexbox-item">Possessives</h2>
<h2 class="sidebar-flexbox-item">Adverbs</h2>
<h2 class="sidebar-flexbox-item">Relative Pronouns</h2>
<h2 class="sidebar-flexbox-item">Imperative Tense</h2>
<h2 class="sidebar-flexbox-item">Reflexive Verbs</h2>
<h2 class="sidebar-flexbox-item">Past Historic Tense</h2>
<h2 class="sidebar-flexbox-item">Imperfect Tense</h2>
<h2 class="sidebar-flexbox-item">Pluperfect Tense</h2>
<h2 class="sidebar-flexbox-item">Conditional Tenses</h2>
<h2 class="sidebar-flexbox-item">Present Subjunctive Tense</h2>
<h2 class="sidebar-flexbox-item">Past Subjunctive Tense</h2>
<h2 class="sidebar-flexbox-item">Imperfect Subjunctive Tense</h2>
<h2 class="sidebar-flexbox-item">Pluperfect Subjunctive Tense</h2>
<h2 class="sidebar-flexbox-item">Future Perfect</h2>
<h2 class="sidebar-flexbox-item">Hypothetical Sentences</h2>
<h2 class="sidebar-flexbox-item">Prepositions</h2>
<h2 class="sidebar-flexbox-item">Cardinal Numbers</h2>
<h2 class="sidebar-flexbox-item">Ordinal Numbers</h2>
<h2 class="sidebar-flexbox-item">Numerical Expressions, Telling Time and Dates</h2>
<h2 class="sidebar-flexbox-item">Altered and Compound Nouns</h2>
<h2 class="sidebar-flexbox-item">Articles</h2>
<h2 class="sidebar-flexbox-item">Miscellaneous Topics</h2>
</div>
<div class="grid-item grid-item-5"><p>Grid Item 5</p></div>
</div>
</body>
</html>
So the way to fix it is not using display: flex; and removing height: 100%;.
Try it and see if it works for you.
.sidebar-flexbox {
overflow-y: scroll;
}
You have given height: 100vh
/* Main CSS grid to organise the shape of the webpage. */
.grid
{
display: grid;
grid-template-columns: repeat(9,1fr);
grid-template-rows: repeat(9,1fr);
height: 100vh;
width: 100vw;
align-content: center;
justify-content: center;
background-color: black;
}
remove height : 100vh from here and test it or you can give height: 100%
I am trying to achieve a layout with multiple elements of different height stacked on mobile screens and some elements forming a sidebar for desktop, roughly looking like this:
My first idea was to achieve it via CSS grid, defining one row with two columns and then assigning the grid-area depending on the class (orange vs gray):
Codepen
.layout {
display: grid;
max-width: 860px;
margin: 0 auto;
gap: 20px;
}
#media(min-width: 860px) {
.layout {
grid-template-areas: 'main sidebar';
grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
}
}
.sidebar {
grid-area: sidebar;
}
.content {
grid-area: main;
}
Problem: as multiple sidebar elements now occupy the same grid cell, they overlap instead of just flow on top of each other. I've been trying to wrap my head around alternative solutions for a few days now, but I couldn't find any so far that did not involve reordering the dom with JavaScript. Am I missing the obvious?
EDIT
Flexbox as stated in the answers does not solve this problem (if the position of elements within the list would be known upfront maybe, but this is not the case). Some elements go in the sidebar, some go in the main bar while having a fixed order in the mobile layout.
Use Flexbox, then you can easily do this.
Refer following code,
.layout {
display: flex;
flex-wrap: wrap;
max-width: 860px;
margin: 0 auto;
gap: 20px;
}
set correct order of div (containers) as you need, (the following code is sample one)
<div id="main">
<div style="background-color:coral;" id="myRedDIV"></div>
<div style="background-color:lightblue;" id="myBlueDIV"></div>
<div style="background-color:lightgreen;" id="myGreenDIV"></div>
<div style="background-color:pink;" id="myPinkDIV"></div>
</div>
#main {
width: 100%;
height: 150px;
border: 1px solid #c3c3c3;
display: flex;
flex-wrap: wrap;
}
#main div {
width: 70px;
height: 70px;
}
/* Standard syntax */
div#myRedDIV {order: 1;}
div#myBlueDIV {order: 4;}
div#myGreenDIV {order: 3;}
div#myPinkDIV {order: 2;}
Refer following links for more about Order in Flexbox
Link1 --> About Flexbox Order
Link2 --> About Flexbox Order
Why don't you try with flexbox. you can do it using display:flex, for more about the flex refer below sample.
<!DOCTYPE html>
<html>
<head>
<style>
.flex-container {
display: flex;
flex-wrap: nowrap;
background-color: DodgerBlue;
}
.flex-container > div {
background-color: #f1f1f1;
width: 100px;
margin: 10px;
text-align: center;
line-height: 75px;
font-size: 30px;
}
</style>
</head>
<body>
<h1>Flexible Boxes</h1>
<div class="flex-container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
<p>Try to resize the browser window.</p>
<p>A container with "flex-wrap: nowrap;" will never wrap its items.</p>
<p><strong>Note:</strong> Flexbox is not supported in Internet Explorer 10 or earlier versions.</p>
</body>
</html>
This might not be the answer to your question! (cause I've changed the grid layout into FlexBox)
In this example I'm changing flex-direction via screen breakouts.
More Information on CSS Flex box Direction
Code:
* {
border: 1px solid coral;
padding: 12px;
margin: 12px;
}
.layout {
display: flex;
flex-direction: column;
align-items: center;
}
.layout>* {
display: flex;
flex-direction: row;
}
.sidebar {
background-color: yellow;
}
.content {
background-color: grey;
}
#media(max-width: 860px) {
.layout {
display: flex;
flex-direction: column;
align-items: center;
}
.layout>* {
display: flex;
flex-direction: column;
}
.sidebar {
background-color: yellow;
}
.content {
background-color: grey;
}
.content {
background-color: green;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="layout">
<div>
<div class="content big">
Here's some text
</div>
<div class="sidebar small">
Sidebar Item
</div>
</div>
<div>
<div class="content big">
More Text
</div>
<div class="sidebar small">
another sidebar Item
</div>
</div>
</div>
</body>
</html>
When I run my web-page, it displays it with the header on the left and the footer on the right, even though I don't want it to. I want it to display downwards.
My HTML Code:
<!DOCTYPE html>
<html>
<head>
<title>Alan Turing</title>
<link rel="stylesheet" type="text/css" href="MyStyles.css">
</head>
<body>
<header>
<h5>Alan Turing</h5>
</header>
<nav>
Home
Biography
Quiz
About
</nav>
<article>
<h2>Alan Turing</h2>
<p>Welcome to my Alan Turing website. Click on Biography to read about him, quiz to havea test about him. Click about to see about this web page and other useful websites.</p>
<img alt="Alan turing" src="Assets/alanTuring.jpg">
<p>Above is a picture of Alan Turing, who is famous for cracking the enigma code in World War 2.</p>
<h3>An overview on who he was</h3>
<p>Alan Turing was an English mathematician and pioneer of theoretical computer science and artificial intelligence. During WW2, he was instrumental in breaking the German Enigma code, leading to Allied victory over Nazi Germany.</p>
</article>
</body>
And my CSS code:
header {
padding: 35px;
text-align: center;
background:darkgreen;
color: darkgray;
font-size: 40px;
}
nav {
padding: 20px;
background: green;
color: darkgrey;
font-size: 20px
}
article {
padding: 100px;
text-align: center;
background: lightgreen;
}
#import url('https://fonts.googleapis.com/css?
family=Source+Code+Pro&display=swap');
body {
font-family: 'Source Code Pro', monospace;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
}
I have tried deleting some things, like each section, however it hasn't worked.
Thanks in advance!
You have set body to display: flex. The default direction of a flexbox is row. That's why your page is displaying left to right. To change this, so your flex parent displays its children in a column, add this line to body:
body {
…
flex-direction: column;
}
Here's a little demo to help illustrate changing flex-direction from row (the default) to column.
const container = document.querySelector(".container");
document.querySelector("button").addEventListener("click", () => {
container.classList.toggle("column");
});
.container {
min-height: 100vh;
display: flex;
}
.container.column {
flex-direction: column;
}
.container > div {
flex: 1;
}
.left {
background-color: gray;
}
.right {
background-color: yellow;
}
button {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 1em 1.5em;
}
html, body { margin: 0; }
<div class="container">
<div class="left"></div>
<div class="right"></div>
</div>
<button type="button">Change flex direction</button>
Remove the display: flex and related properties from body