Making Rows of Boxes Clickable with Links - html

So I've been trying to make these boxes clickable with links for a while now, but haven't been able to figure it out. I'd like each box to have its own link. Can anyone help me refine my code?
https://jsfiddle.net/Anonymous32794/07suq4pg/8/
<div class="wrapper">
<article class="main">
<img src="image" alt="">
<div class="text">
<b>Stuff</b>
<button>Button</button>
<p>Stuff</p></div>
</article>
<aside class="aside aside-2">
<div class="dropdown">
<button class="dropbtn">Downloads</button>
<div class="dropdown-content">
Link 1
Link 2
Link 3
</div>
</div>
</aside>
<footer class="footer">
<div class="box-container">
<div class="box">Chapter 1</div>
<div class="box">Chapter 2</div>
<div class="box">Chapter 3</div>
<div class="box">Chapter 4</div>
<div class="box">Chapter 5</div>
<div class="box">Chapter 6</div>
<div class="box">Chapter 7</div>
<div class="box">Chapter 8</div>
<div class="box">Chapter 9</div>
</div>
</footer>
</div>

First you get all elements with class box. then you bind every element with a click Event Listener. Then you can handle the click event. In this case i print the innerHTML out.
const boxes = document.querySelectorAll('.box');
boxes.forEach((box) => {
box.addEventListener('click', function(e) {
alert('will redirect to:' + e.target.getAttribute('data-href'));
window.location = e.target.getAttribute('data-href');
});
});
.wrapper {
display: flex;
flex-flow: row wrap;
text-align: center;
}
.wrapper > * {
padding: 0px;
flex: 1 100%;
}
.footer {
}
.main {
text-align: left;
}
.aside-2 {
}
.dropbtn {
background-color: #4CAF50;
color: white;
padding: 6px;
font-size: 16px;
border: none;
cursor: pointer;
top: 8px;
}
.dropdown {
position: relative;
display: inline-block;
float: center;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown-content a:hover {background-color: #f1f1f1}
.dropdown:hover .dropdown-content {
display: block;
}
.dropdown:hover .dropbtn {
background-color: #3e8e41;
}
.box {
border: .1rem solid #cccccc;
background: #5cc80f;
color: white;
width: 25%;
}
.box-container {
align-content: center;
align-items: center;
align-self: stretch;
display: flex;
flex-wrap: wrap;
flex-direction: row;
flex-grow: 1;
font-weight: 600;
justify-content: left;
min-width: 0;
}
.box::after {
clear: both;
content: "";
}
img {
float: left;
width: 120px;
height: 171px;
padding: 10px;
border-radius: 20px;
}
#media all and (min-width: 600px) {
.aside { flex: 1 0 0; }
}
#media all and (min-width: 800px) {
.main { flex: 3 0px; }
.aside-1 { order: 1; }
.main { order: 2; }
.aside-2 { order: 3; }
.footer { order: 4; }
}
<div class="wrapper">
<article class="main">
<img src="image" alt="">
<div class="text">
<b>Stuff</b>
<button>Button</button>
<p>Stuff</p></div>
</article>
<aside class="aside aside-2">
<div class="dropdown">
<button class="dropbtn">Downloads</button>
<div class="dropdown-content">
Link 1
Link 2
Link 3
</div>
</div>
</aside>
<footer class="footer">
<div class="box-container">
<div class="box" data-href="http://www.google.de">Chapter 1</div>
<div class="box" data-href="http://www.bing.de">Chapter 2</div>
<div class="box">Chapter 3</div>
<div class="box">Chapter 4</div>
<div class="box">Chapter 5</div>
<div class="box">Chapter 6</div>
<div class="box">Chapter 7</div>
<div class="box">Chapter 8</div>
<div class="box">Chapter 9</div>
</div>
</footer>
</div>

Related

How to center a timeline with blocks in the middle?

I managed to make a mockup of a timeline with blocks. It has a look that is ok. You can run the snippet to take a look or see this image:
.list {
display: flex;
flex-direction: column;
}
.item {
display: flex;
}
.item:not(:last-child) {
margin-bottom: 10px;
}
.left {
display: flex;
flex-direction: column;
}
.right {
flex: 1;
margin-left: 10px;
}
.border {
width: 1px;
border-radius: 10px;
background: black;
height: 100%;
margin: 2px auto;
}
.bubble,
.big-bubble {
padding: 10px 20px;
border: 1px solid black;
border-radius: 5px;
}
.big-bubble {
padding: 30px 0;
border: 1px solid black;
border-radius: 5px;
}
<div class="list">
<div class="item">
<div class="left">
<div class="bubble"></div>
<div class="border"></div>
</div>
<div class="right">
<div class="big-bubble"></div>
</div>
</div>
<div class="item">
<div class="left">
<div class="bubble"></div>
<div class="border"></div>
</div>
<div class="right">
<div class="big-bubble"></div>
</div>
</div>
<div class="item">
<div class="left">
<div class="bubble"></div>
<div class="border"></div>
</div>
<div class="right">
<div class="big-bubble"></div>
</div>
</div>
</div>
But I'm not satisfied with the result. I would like to align my timeline like this. The idea would be that the info bubble on the right starts in the vertical middle of the bubble on the left.
I don't see how to do it with flex.
Why not just give .right a margin-top that is equal to half the height of .left (11px)?
.list {
display: flex;
flex-direction: column;
}
.item {
display: flex;
}
.item:not(:last-child) {
margin-bottom: 10px;
}
.left {
display: flex;
flex-direction: column;
}
.right {
flex: 1;
margin-left: 10px;
margin-top: 11px;
}
.border {
width: 1px;
border-radius: 10px;
background: black;
height: 100%;
margin: 2px auto;
}
.bubble,
.big-bubble {
padding: 10px 20px;
border: 1px solid black;
border-radius: 5px;
}
.big-bubble {
padding: 30px 0;
border: 1px solid black;
border-radius: 5px;
}
<div class="list">
<div class="item">
<div class="left">
<div class="bubble"></div>
<div class="border"></div>
</div>
<div class="right">
<div class="big-bubble"></div>
</div>
</div>
<div class="item">
<div class="left">
<div class="bubble"></div>
<div class="border"></div>
</div>
<div class="right">
<div class="big-bubble"></div>
</div>
</div>
<div class="item">
<div class="left">
<div class="bubble"></div>
<div class="border"></div>
</div>
<div class="right">
<div class="big-bubble"></div>
</div>
</div>
</div>
Alteratively, if you don't want the increased gap, you can just give .left a margin-top of -11px:
.list {
display: flex;
flex-direction: column;
}
.item {
display: flex;
}
.item:not(:last-child) {
margin-bottom: 10px;
}
.left {
display: flex;
flex-direction: column;
margin-top: -11px;
}
.right {
flex: 1;
margin-left: 10px;
}
.border {
width: 1px;
border-radius: 10px;
background: black;
height: 100%;
margin: 2px auto;
}
.bubble,
.big-bubble {
padding: 10px 20px;
border: 1px solid black;
border-radius: 5px;
}
.big-bubble {
padding: 30px 0;
border: 1px solid black;
border-radius: 5px;
}
<div class="list">
<div class="item">
<div class="left">
<div class="bubble"></div>
<div class="border"></div>
</div>
<div class="right">
<div class="big-bubble"></div>
</div>
</div>
<div class="item">
<div class="left">
<div class="bubble"></div>
<div class="border"></div>
</div>
<div class="right">
<div class="big-bubble"></div>
</div>
</div>
<div class="item">
<div class="left">
<div class="bubble"></div>
<div class="border"></div>
</div>
<div class="right">
<div class="big-bubble"></div>
</div>
</div>
</div>

Chrome attempts to print a simple html document as 31K+ empty pages

I have a simple html document (see - https://5fa3b1d135e99.htmlsave.net). When I try to print (cmd/ctrl+P) this document, chrome evaluate the print size as 31,776 pages:
After some research, when removing the gap property from .block-row, it's fixed, but I have no idea what's the cause, plus - I do need the gap.
Any ideas?
In case the link gets expired, this is the output:
#import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght#400;600;700');
#media print {
* {
-webkit-print-color-adjust: exact;
}
.block-row,
.block-signature {
break-inside: avoid;
}
}
html,
body {
margin: 0;
}
body {
font-size: 10px;
font-family: "Open Sans";
}
.page-header {
display: flex;
align-items: center;
justify-content: center;
border-bottom: 1px solid #eaeaea;
padding-bottom: 8px;
margin: 0 24px 24px;
width: 100%;
}
.page-header > div {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
}
.page-header > div > .a-logo-container,
.page-header > div > .other-logo-container {
flex: 1;
}
.page-header > div > .a-logo-container {
display: flex;
align-items: center;
justify-content: center;
}
.page-header .a-logo {
display: block;
width: 79px;
height: 20px;
}
.page-header .other-logo-container {
display: flex;
align-items: center;
}
.page-header .other-logo {
background: none no-repeat center center / contain;
display: block;
width: 40px;
height: 20px;
}
.page-header .other-logo-container {
gap: 8px;
}
.page-header .other-logo-container h2 {
font-size: 10px;
}
.page-footer {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 8px;
font-size: 8px;
font-weight: 400;
width: 100%;
margin: 0 24px;
color: #999;
}
.block-box {
padding: 16px 24px;
background-color: #f9f9f9;
border-radius: 8px;
margin: 16px 0;
}
.block-box .block-column {
gap: 10px;
}
.block-row {
display: flex;
gap: 32px;
}
.block-row > * {
flex: 1;
}
.block-row > * + * {
margin: 16px;
}
.block-column {
display: flex;
flex-direction: column;
}
.block-text,
.block-start-end-time {
display: flex;
flex-direction: column;
gap: 6px;
}
.block-inline-key-value {
display: flex;
gap: 16px;
}
.block-inline-key-value > strong {
font-weight: 600;
}
.block-inline-title {
display: block;
border-bottom: 2px solid;
line-height: 25px;
font-weight: 600;
}
.block-container .label {
white-space: nowrap;
}
.block-title {
background-color: #f9f9f9;
padding: 6px 12px;
border-radius: 8px;
font-weight: 600;
}
.block-item {
display: block;
align-items: center;
}
.block-radios {
display: flex;
flex-direction: column;
gap: 8px;
}
.block-radios .checkbox {
width: 12px;
height: 12px;
border-radius: 100%;
border: 1px solid #c4c4c4;
box-shadow: 0 0 0 1px #fff inset;
}
.block-radios .checkbox[data-checked="true"] {
background-color: #292929;
}
.block-radios > .block-container {
display: flex;
}
.block-radios > .block-container > * {
width: 100%;
}
.block-checkboxes {
display: flex;
flex-direction: column;
gap: 8px;
}
.block-checkboxes > .block-container {
display: grid;
flex-wrap: wrap;
gap: 10px;
grid-template-columns: 1fr 1fr 1fr 1fr;
}
.block-checkboxes .checkbox {
width: 12px;
height: 12px;
border: 1px solid #c4c4c4;
border-radius: 2px;
}
.block-checkboxes .checkbox[data-checked="true"] {
border-color: #292929;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAHCAYAAADam2dgAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAABISURBVHgBfYzBDQAQEASvBCUoQUk6oRSlqIgSlgvigrPJfCaTJVIGwHcMfYKAsSylY46gLsfSTMGkKxBPEXt3cIRFDURoX74BA3ZgYkt9TZoAAAAASUVORK5CYII=) no-repeat center center #292929;
}
.block-signature {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
gap: 12px;
min-height: 100px;
}
.block-signature .signature-title {
border-top: 2px solid;
width: 100%;
text-align: center;
padding: 8px;
box-sizing: border-box;
max-width: 50vw;
}
.block-signature .signature-container > img {
transform: translateY(50%);
height: 80px;
}
<!DOCTYPE html>
<html>
<body>
<section class="blocks">
<div class="block-row">
<div class="block-radios">
<div class="block-inline-title">Radio</div>
<div class="block-container">
</div>
</div>
</div>
<div class="block-row">
<div class="block-title">Main Header</div>
</div>
<div class="block-row">
<div class="block-radios">
<div class="block-inline-title">Drop Down</div>
<div class="block-container">
</div>
</div>
</div>
<div class="block-row">
<div class="block-text">
<div class="block-inline-title">Short Text</div>
<div class="block-container">
<div class="block-item">lorem ipsum</div>
</div>
</div>
</div>
<div class="block-row">
<div class="block-text">
<div class="block-inline-title">Number</div>
<div class="block-container">
<div class="block-item">100</div>
</div>
</div>
</div>
<div class="block-row">
<div class="block-row">
<div class="block-signature">
<div class="signature-container"><strong>Tracey Kutch</strong>
</div>
<div class="signature-title">Patient Name</div>
</div>
<div class="block-signature">
<div class="signature-container">None</div>
<div class="signature-title">Signature</div>
</div>
<div class="block-signature">
<div class="signature-container"><strong>2020-11-04T00:00:00Z</strong>
</div>
<div class="signature-title">Date</div>
</div>
</div>
</div>
<div class="block-row">
<div class="block-start-end-time">
<div class="block-inline-title">Time</div>
<div class="block-container">
<div class="block-item">Invalid Date</div>
</div>
</div>
</div>
</div>
<div class="block-row">
<div class="block-title">TODO Image #Newbie012</div>
</div>
<div class="block-row">
<div class="block-title">TODO Chart #Newbie012</div>
</div>
<div class="block-row">
<div class="block-row"></div>
</div>
<div class="block-row">
<div class="block-checkboxes">
<div class="block-inline-title">Multiple Select (check)</div>
<div class="block-container">
</div>
</div>
</div>
<div class="block-row">
<div class="block-radios">
<div class="block-inline-title">Yes/No</div>
<div class="block-container">
</div>
</div>
</div>
<div class="block-row">
<div class="block-title">Sub Header</div>
</div>
<div class="block-row">
<div class="block-text">
<div class="block-inline-title">Long Text</div>
<div class="block-container">
<div class="block-item">TypeScript supports JSX transpilation and code analysis. If you are unfamiliar with JSX here is an excerpt from the official website: JSX is an XML-like syntax extension to ECMAScript without any defined semantics. It's NOT intended
to be implemented by engines or browsers. It's NOT a proposal to incorporate JSX into the ECMAScript spec itself. It's intended to be used by various preprocessors (transpilers) to transform these tokens into standard ECMAScript.
The motivation behind JSX is to allow users to write HTML like views in JavaScript so that you can: Have the view Type Checked by the same code that is going to check your JavaScript Have the view be aware of the context it is
going to operate under (i.e. strengthen the controller-view connection in traditional MVC). Reuse JavaScript patterns for HTML maintenance e.g. Array.prototype.map, ?:, switch etc instead of creating new (and probably poorly typed)
alternatives. This decreases the chances of errors and increases the maintainability of your user interfaces. The main consumer of JSX at this point is ReactJS from facebook. This is the usage of JSX that we will discuss here.</div>
</div>
</div>
</div>
<div class="block-row">
<div class="block-row">
<div class="block-signature">
<div class="signature-container"><strong>Eliya Local</strong>
</div>
<div class="signature-title">Employee Name</div>
</div>
<div class="block-signature">
<div class="signature-container">None</div>
<div class="signature-title">Signature</div>
</div>
<div class="block-signature">
<div class="signature-container"><strong>2020-11-04T00:00:00Z</strong>
</div>
<div class="signature-title">Date</div>
</div>
</div>
</div>
<div class="block-row">
<div class="block-row">
<div class="block-signature">
<div class="signature-container"><strong>Signature</strong>
</div>
<div class="signature-title">Patient Name</div>
</div>
<div class="block-signature">
<div class="signature-container">None</div>
<div class="signature-title">Signature</div>
</div>
<div class="block-signature">
<div class="signature-container"><strong>2020-11-04T00:00:00Z</strong>
</div>
<div class="signature-title">Date</div>
</div>
</div>
</div>
<div class="block-row">
<div class="block-text">
<div class="block-inline-title">Date</div>
<div class="block-container">
<div class="block-item">12/Sa/1996</div>
</div>
</div>
</div>
<div class="block-row">
<div class="block-start-end-time">
<div class="block-inline-title">Time</div>
<div class="block-container">
<div class="block-item">Invalid Date</div>
</div>
</div>
</div>
<div class="block-row">
<div class="block-text">
<div class="block-inline-title">Add Free Text</div>
<div class="block-container">
<div class="block-item"></div>
</div>
</div>
</div>
<div class="block-row">
<div class="block-title">TODO Chart #Newbie012</div>
</div>
<div class="block-row">
<div class="block-text">
<div class="block-inline-title">Blood Pressure</div>
<div class="block-container">
<div class="block-item">100 / 90</div>
</div>
</div>
</div>
<div class="block-row">
<div class="block-row"></div>
</div>
<div class="block-row">
<div class="block-row"></div>
</div>
<div class="block-row">
<div class="block-row"></div>
</div>
</section>
</body>
</html>
As pointed out by #kaiido the culprit seems to be the empty .block-row with the gap property.
We encountered the same issue and posted a bug in Chrome see link.
Our solution was to remove the gap property when the container is empty.
In your case
.block-row { display: flex; gap: 32px; }
.block-row:empty { gap: unset; }
I didn't have any empty tags and was still getting this issue. So I just removed gap entirely when in print mode and that worked.
#media print {
* {
gap: 0 !important;
}
}

css flexbox grid masonry style

I've been trying to achieve the following layout using CSS and Flexbox but without any luck. Maybe someone here could help me out and point me the mistakes I've made and even suggest me the best course to do it.
This should be the final result (having all items different heights and widths but I'm starting to think that flexbox is not the best choice to do it):
Live example: https://jsfiddle.net/bogdaniel/Lzugkva3/5/
<div class="container">
<div class="blog-container">
<div class="blog-item" style="height: 286px;">
<div class="blog-post">
<div class="post-body">
<div class="post-title">
<h2>Item One</h2>
<span>height: 286px;</span>
<p>Item Should Be First In The List On The Left Column</p>
</div>
</div>
</div>
</div>
<div class="blog-item" style=";height: 203px;">
<div class="blog-post">
<div class="post-body">
<div class="post-title">
<h2>Item Two</h2>
<span>height: 203px;</span>
<p>Item Should Go To The right next to the height 286px;</p>
</div>
</div>
</div>
</div>
<div class="blog-item" style="height: 255px;">
<div class="blog-post">
<div class="post-body">
<div class="post-title">
<h2>Item Three</h2>
<span>height: 255px;</span>
<p>Item Should Be Second On the First Row In the List</p>
</div>
</div>
</div>
</div>
<div class="blog-item" style="height: 325px;">
<div class="blog-post">
<div class="post-body">
<div class="post-title">
<h2>Item Four</h2>
<span>height: 325px;</span>
<p>Item Should Go To The right Of Item Three On The Second Column</p>
</div>
</div>
</div>
</div>
<div class="blog-item" style="height: 251px;">
<div class="blog-post">
<div class="post-body">
<div class="post-title">
<h2>Item Five</h2>
<span>height: 251px;</span>
<span>width: 523px;</span> Item Should Start From The Left And Span 2 Columns Almost
</div>
</div>
</div>
</div>
<div class="blog-item" style="height: 282px;">
<div class="blog-post">
<div class="post-body">
<div class="post-title">
<h2>Item Six</h2>
<span>height: 282px;</span>
<span>width: 186px;</span>
<p>Item Should Be Portrait And Span On The Right Column</p>
</div>
</div>
</div>
</div>
<div class="blog-item" style=" width: 100%%; height: 204px;">
<div class="blog-post">
<div class="post-body">
<div class="post-title">
<h2>Item Seven</h2>
<span>height 204px;</span>
<span>with: 523px;</span>
</div>
</div>
</div>
</div>
<div class="blog-item" style="width: 186px; height: 174px;">
<div class="blog-post">
<div class="post-body">
<div class="post-title">
<h2>Item Eight</h2>
<span>height: 174px;</span>
<span>width: 186px;</span>
</div>
</div>
</div>
</div>
</div>
</div>
SCSS code:
.blog-container {
display: flex;
flex-flow: column wrap;
/* Your container needs a fixed height, and it
* needs to be taller than your tallest column. */
min-height: 1400px;
height: 100vh;
/* Force new columns */
&:before,
&:after {
content: "";
flex-basis: 100%;
width: 0;
order: 2;
}
/* Optional */
background-color: #f7f7f7;
border-radius: 3px;
margin: 15px auto;
counter-reset: items;
}
.blog-item {
width: 50%;
padding: 14px;
.blog-post {
height: 100%;
/* Optional */
position: relative;
border-radius: 3px;
border: 1px solid #4290e2;
box-shadow: 0 2px 2px rgba(0, 90, 250, 0.05),
0 4px 4px rgba(0, 90, 250, 0.05), 0 8px 8px rgba(0, 90, 250, 0.05),
0 16px 16px rgba(0, 90, 250, 0.05);
color: #000;
padding: 15px;
&:before {
counter-increment: items;
content: counter(items);
}
.post-body {
padding: 15px;
}
}
}
.blog-item:nth-child(2n + 1) {
order: 1;
}
.blog-item:nth-child(2n + 2) {
order: 2;
}
.blog-item:nth-child(2n + 3) {
order: 1;
}
.blog-item:nth-child(2n + 4) {
order: 2;
}
while waiting for a comment, if the layout is to be like the image, then you can use grid and set ahead amount of rows and cells to span for each element.
useful ressource : https://css-tricks.com/snippets/css/complete-guide-grid/ & https://gridbyexample.com/
body {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(6, auto);
}
div:nth-child(1) {
grid-row: span 2;
}
div:nth-child(2) {
grid-column: span 3;
}
div:nth-child(3) {
grid-row: 3
}
div:nth-child(4) {
grid-column: span 3;
grid-row: span 2;
}
div:nth-child(5) {
grid-column: span 3;
}
div:nth-child(6) {
grid-row: span 2
}
div:nth-child(7) {
grid-column: span 3;
grid-row: span 2
}
/* makup */
body {
counter-reset: divs;
background: rgb(236, 244, 175);
}
div:before {
counter-increment: divs;
content: counter(divs);
background: tomato;
width: 1.2em;
height: 1.2em;
border-radius: 50%;
text-align: center;
color: green;
text-shadow: 0 0 3px white;
box-shadow: 0 0 3px;
}
div {
border-radius: 3px;
border: 1px solid darkblue;
background: lightblue;
}
body {
margin: 0;
grid-gap: 2vh;
padding: 2vh;
min-height: 100vh;
box-sizing: border-box;
}
div {
display: flex;
align-items: center;
justify-content: center;
font-size: calc(8px + 1.5vh + 1.5vw)
}
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
here is a codepen to test and play with (resize/add content, ... )

Switch between horizontal and vertical layout using CSS (Flex or CSS Grid)

I have a table which looks by default as follows (up to 20 categories with up to 30 items for each category; each of the items will be represented by a card):
Now I'd like to give the user the option to switch to a Horizontal Layout, which should look as follows.
I have started with a JSFiddle: https://jsfiddle.net/stefanwalther/1uzh836j/15/
.status-container {
}
.row {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.col {
display: flex;
flex-direction: column;
flex: 1;
border-width: 1px;
border-style: solid;
border-color: #ccc;
padding: 3px;
}
.header {
background-color: #ccc;
}
<div>
<div class="row header">
<div class="col">
Category 1
</div>
<div class="col">
Category 2
</div>
<div class="col">
Category 3
</div>
</div>
<div class="row">
<div class="col">
Item 1.1
</div>
<div class="col">
Item 2.1
</div>
<div class="col">
Item 3.1
</div>
</div>
<div class="row">
<div class="col">
Item 1.2
</div>
<div class="col">
Item 2.2
</div>
<div class="col">
Item 3.2
</div>
</div>
</div>
Unfortunately, I am stuck, don't know which approach to chose (CSS-Grid, Flex-Box, ?).
Pure CSS flex solution is here. Supports any number of items per category.
See the snippet below:
* {
box-sizing: border-box;
font: normal 400 100%/1.25 sans-serif;
}
#switch {
display: none
}
label {
display: inline-block;
margin: 1rem;
padding: .25em .5em;
border: solid 1px;
border-radius: 1em;
}
label:after {
content: 'vertical mode';
}
#switch:checked+label:after {
content: 'horizontal mode';
}
.category {
position: relative;
display: flex;
flex-wrap: wrap;
align-items: flex-start;
padding-left: 25%
}
.category > div {
width: 25%;
padding: .5em;
border: solid 2px rgba(0, 0, 0, 0);
border-width: 0 4px 4px 0;
box-shadow: inset 0 0 0 2px #248;
text-align: center;
}
.category .header {
position: absolute;
left: 0;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
background: #27c padding-box;
box-shadow: none;
}
#switch:checked ~ section {
display: flex;
justify-content: stretch;
align-items: flex-start;
width: 100%;
}
#switch:checked ~ section .category {
flex-flow: column nowrap;
width: 25%;
padding: 0;
}
#switch:checked ~ section .category > div {
width: 100%
}
#switch:checked~section .category .header {
position: static;
height: auto;
}
<input type="checkbox" id="switch"><label for="switch">Switch to </label>
<section>
<div class="category">
<div class="header">Category 1</div>
<div>Item 1.1</div>
<div>Item 1.2</div>
<div>Item 1.3</div>
<div>Item 1.4</div>
<div>Item 1.5</div>
<div>Item 1.6</div>
<div>Item 1.7</div>
<div>Item 1.8</div>
</div>
<div class="category">
<div class="header">Category 2</div>
<div>Item 2.1</div>
<div>Item 2.2</div>
<div>Item 2.3</div>
</div>
<div class="category">
<div class="header">Category 3</div>
<div>Item 3.1</div>
<div>Item 3.2</div>
<div>Item 3.3</div>
<div>Item 3.4</div>
<div>Item 3.5</div>
<div>Item 3.6</div>
<div>Item 3.7</div>
<div>Item 3.8</div>
<div>Item 3.9</div>
<div>Item 3.10</div>
<div>Item 3.11</div>
<div>Item 3.12</div>
<div>Item 3.13</div>
<div>Item 3.14</div>
</div>
<div class="category">
<div class="header">Category 4</div>
<div>Item 4.1</div>
<div>Item 4.2</div>
<div>Item 4.3</div>
<div>Item 4.4</div>
</div>
</section>

Alternative to display flex for event tracker

I currently have an event tracker made using html and css. My issue is that I would like to get ride of display: flex; due to browser-compatibility issues. Is there an alternative to achieve the same result? I tried using display:inline-block because without flex all steps were coming in different lines.
HTML:
<div class="container">
<div class="row event">
<div class="col-xs-3 event-step">
<p class="event-stepnum">Step 1</p>
<div class="progress">
<div class="progress-bar"></div>
</div>
</div>
<div class="col-xs-3 event-step complete">
<p class="event-stepnum">Step 2</p>
<div class="progress">
<div class="progress-bar"></div>
</div>
</div>
<div class="col-xs-3 event-step">
<p class="event-stepnum">Step 3</p>
<div class="progress">
<div class="progress-bar"></div>
</div>
</div>
</div>
</div>
CSS:
.event > .event-step {
padding: 0;
position: relative;
}
.event > .event-step .event-stepnum {
color: #595959;
font-size: 16px;
margin-bottom: 5px;
}
.steps .step-on,
.steps .step-done {
background-color: #1b7e28;
color: #1b7e28;
border: 1px solid transparent;
}
.progress {
position: relative;
border-radius: 0px;
height: 5px;
box-shadow: none;
margin: 20px 0;
}
.progress > .progress-bar {
width: 0px;
box-shadow: none;
background: #fbe8aa;
}
.event-step.complete > .progress > .progress-bar {
width: 100%;
}
.row {
display:flex;
}
JSFiddle Demo
Just replace the display:flex by display:inline-block and give your step divs a fixed width:
.event > .event-step {
padding: 0;
position: relative;
width: 200px;
}
.row {
display: inline-block;
}
https://jsfiddle.net/onk2cqhg/