From dcfb172704f3afb68a30425029ec834be2883274 Mon Sep 17 00:00:00 2001 From: bt Date: Sat, 8 Jun 2024 13:22:19 -0400 Subject: More content porting, on-going markdown changes for lowdown support --- build/flexbox-bar-graphs/index.html | 413 +++++++++++++++++++----------------- 1 file changed, 216 insertions(+), 197 deletions(-) (limited to 'build/flexbox-bar-graphs') diff --git a/build/flexbox-bar-graphs/index.html b/build/flexbox-bar-graphs/index.html index a73e791..c705c0d 100644 --- a/build/flexbox-bar-graphs/index.html +++ b/build/flexbox-bar-graphs/index.html @@ -1,85 +1,96 @@ - + Pure CSS Bar Graphs with Graceful Mobile Fallbacks - - + + +
-

Pure CSS Bar Graphs with Graceful Mobile Fallbacks

+

Pure CSS Bar Graphs with Graceful Mobile Fallbacks

+

2020-12-08

-

I recently published a new open source project, Flexbox Bar Graphs, and wanted to share a simple breakdown of how it was built. It isn't anything mind-blowing, but I like the idea of placing bar graphs in a web page with zero Javascript.

+ +

I recently published a new open source project, Flexbox Bar Graphs, and wanted to share a simple breakdown of how it was built. It isn’t anything mind-blowing, but I like the idea of placing bar graphs in a web page with zero Javascript.

+

So in the end, this is what our bar graphs will look like on desktop:

-

- Flexbox Bar Graph -
The flexbox bar graph in desktop view (direct link to image)
-

+

And this is how it will look on smaller devices:

-

- Flexbox Bar Graph Table -
The flexbox bar graph on mobile devices (direct link to image)
-

-

Let's get into the details!

-

The HTML

-

The main "secret" of this project is that our graphs are constructed out of HTML tables. Now before you freak out - this is perfectly fine and works in our favor quite well.

+ +

Let’s get into the details!

+ +

The HTML

+ +

The main “secret” of this project is that our graphs are constructed out of HTML tables. Now before you freak out - this is perfectly fine and works in our favor quite well.

+
    -
  1. If the user has JS disabled --> they will still see our graphs
  2. -
  3. If the user has CSS disabled --> they will see a standard data table set
  4. +
  5. If the user has JS disabled –> they will still see our graphs
  6. +
  7. If the user has CSS disabled –> they will see a standard data table set
+

All bases are covered!

-
<!-- Using a basic table with our custom data-id -->
-<table data-id="flexbox-bar-graph">
-    <caption>Web Performance Results</caption>
-    <thead>
-        <tr>
-            <th>Test Performed</th>
-            <th>Before</th>
-            <th>After</th>
-            <th>Difference</th>
-        </tr>
-    </thead>
-    <tbody>
-        <tr>
-            <th>Initial Load Time</th>
-            <td>
-                <!--
+
+
<!-- Using a basic table with our custom data-id -->
+<table data-id="flexbox-bar-graph">
+    <caption>Web Performance Results</caption>
+    <thead>
+        <tr>
+            <th>Test Performed</th>
+            <th>Before</th>
+            <th>After</th>
+            <th>Difference</th>
+        </tr>
+    </thead>
+    <tbody>
+        <tr>
+            <th>Initial Load Time</th>
+            <td>
+                <!--
                     WTF are these CSS variables?
                     See the CSS section below
-                -->
-                <span style="--data-set:4.7/5;"></span>
-                <p>4.7</p>
-            </td>
-            <td>
-                <span style="--data-set:2.7/5;"></span>
-                <p>2.7</p>
-            </td>
-            <td>
-                <span style="--data-set:2/5;"></span>
-                <p>2</p>
-            </td>
-        </tr>
-    </tbody>
-</table>
+                -->
+                <span style="--data-set:4.7/5;"></span>
+                <p>4.7</p>
+            </td>
+            <td>
+                <span style="--data-set:2.7/5;"></span>
+                <p>2.7</p>
+            </td>
+            <td>
+                <span style="--data-set:2/5;"></span>
+                <p>2</p>
+            </td>
+        </tr>
+    </tbody>
+</table>
 
+

Nothing crazy is happening here - just your standard HTML table structure. The one main thing to notice is the --data-set CSS variable placed inline on each data point. This will be important for our CSS to configure the individual bar graphs properly.

-

The CSS

-

This might look overwhelming if I just dumped the whole CSS file in one big code block, so instead I'm going to break them down into two parts:

+ +

The CSS

+ +

This might look overwhelming if I just dumped the whole CSS file in one big code block, so instead I’m going to break them down into two parts:

+
  1. Baseline styling (mobile)
  2. Desktop styling
-

Baseline

+ +

Baseline

+

Here we target just our table elements with the data-id of flexbox-bar-graph. This allows us to avoid worrying about adding classes or IDs and also avoids conflicts with other non-graph styled tables in our projects.

+

The base :root element holds all of our bar graph colors. Change these as you see fit!

-
/* Bar Graph color variables */
+
+
/* Bar Graph color variables */
 :root {
     --bar-color-1: #357EC7;
     --bar-color-2: #E42217;
@@ -87,207 +98,215 @@
     --bar-color-4: #7D0541;
     --bar-color-5: #FFD801;
 }
-
-
[data-id="flexbox-bar-graph"] {
+
+[data-id="flexbox-bar-graph"] {
     border-collapse: collapse;
     margin: 4rem 0 6rem;
     width: 100%;
 }
-[data-id="flexbox-bar-graph"] caption {
+[data-id="flexbox-bar-graph"] caption {
     text-align: left;
 }
-[data-id="flexbox-bar-graph"] thead th {
+[data-id="flexbox-bar-graph"] thead th {
     text-align: right;
 }
-[data-id="flexbox-bar-graph"] thead th:nth-child(1),
-[data-id="flexbox-bar-graph"] tbody th {
+[data-id="flexbox-bar-graph"] thead th:nth-child(1),
+[data-id="flexbox-bar-graph"] tbody th {
     text-align: left;
 }
-[data-id="flexbox-bar-graph"] tbody th {
+[data-id="flexbox-bar-graph"] tbody th {
     font-weight: normal;
     font-style: italic;
 }
-[data-id="flexbox-bar-graph"] tbody td {
+[data-id="flexbox-bar-graph"] tbody td {
     text-align: right;
 }
-[data-id="flexbox-bar-graph"] tbody td p {
+[data-id="flexbox-bar-graph"] tbody td p {
     margin: 0;
 }
 
-

Desktop

-

Now we set your "visual" bar graphs to show at a set width (in this example it is 1000px and above). That way the "default" styling can target the mobile device screen sizes.

+ +

Desktop

+ +

Now we set your “visual” bar graphs to show at a set width (in this example it is 1000px and above). That way the “default” styling can target the mobile device screen sizes.

+
    -
  • The thead tr th:nth-child(x):before elements create the square "legends" beside each individual data point heading
  • -
  • The tbody tr td:nth-of-type(x) span elements are the bars themselves
  • -
-
@media(min-width: 1000px) {
-    [data-id="flexbox-bar-graph"] {
+
  • The thead tr th:nth-child(x):before elements create the square “legends” beside each individual data point heading

  • +
  • The tbody tr td:nth-of-type(x) span elements are the bars themselves

    + +

    @media(min-width: 1000px) { + [data-id="flexbox-bar-graph”] { background: transparent; display: block; min-height: 400px; padding: 0; position: relative; width: 100%; - } + }

    - [data-id="flexbox-bar-graph"] caption { - display: block; - font-size: 2rem; - text-align: center; - width: 100%; - } +
    [data-id="flexbox-bar-graph"] caption {
    +    display: block;
    +    font-size: 2rem;
    +    text-align: center;
    +    width: 100%;
    +}
     
    -    [data-id="flexbox-bar-graph"] thead {
    -        display: block;
    -        margin: 2rem 0 3rem;
    -        width: 100%;
    -    }
    -    [data-id="flexbox-bar-graph"] thead tr {
    -        border-bottom: 1px solid lightgrey;
    -        display: flex;
    -        justify-content: center;
    -        padding-bottom: 1rem;
    -    }
    -
    -    [data-id="flexbox-bar-graph"] thead tr th {
    -        display: inline-block;
    -        margin: 0;
    -        padding: 0;
    -        position: relative;
    -        text-align: right;
    -    }
    -    [data-id="flexbox-bar-graph"] thead tr th:before {
    -        content:'';
    -        display: inline-block;
    -        height: 10px;
    -        margin: 0 0.5rem 0 2rem;
    -        position: relative;
    -        width: 10px;
    -    }
    -    [data-id="flexbox-bar-graph"] thead tr th:nth-child(1),
    -    [data-id="flexbox-bar-graph"] thead tr th:nth-child(1):before {
    -        display: none;
    -    }
    -    [data-id="flexbox-bar-graph"] thead tr th:nth-child(2):before {
    -        background: var(--bar-color-1);
    -    }
    -    [data-id="flexbox-bar-graph"] thead tr th:nth-child(3):before {
    -        background: var(--bar-color-2);
    -    }
    -    [data-id="flexbox-bar-graph"] thead tr th:nth-child(4):before {
    -        background: var(--bar-color-3);
    -    }
    -    [data-id="flexbox-bar-graph"] thead tr th:nth-child(5):before {
    -        background: var(--bar-color-4);
    -    }
    -    [data-id="flexbox-bar-graph"] thead tr th:nth-child(6):before {
    -        background: var(--bar-color-5);
    -    }
    -
    -    [data-id="flexbox-bar-graph"] tbody {
    -        display: flex;
    -        justify-content: space-between;
    -        min-height: 300px;
    -        width: 100%;
    -    }
    -
    -    [data-id="flexbox-bar-graph"] tbody tr {
    -        display: flex;
    -        flex-direction: column-reverse;
    -        flex-wrap: wrap;
    -        justify-content: flex-end;
    -        padding: 0 50px;
    -        position: relative;
    -        width: 100%;
    -    }
    -    [data-id="flexbox-bar-graph"] tbody tr th {
    -        font-size: 90%;
    -        position: absolute;
    -        text-align: center;
    -        top: 100%;
    -        width: calc(100% - 100px);
    -    }
    -    [data-id="flexbox-bar-graph"] tbody tr td {
    -        align-items: center;
    -        display: flex;
    -        flex-direction: column;
    -        height: 95%;
    -        justify-content: flex-end;
    -    }
    -
    -    [data-id="flexbox-bar-graph"] tbody tr td span {
    -        display: block;
    -        height: calc(var(--data-set) * 100%);
    -        width: 20px;
    -    }
    -    [data-id="flexbox-bar-graph"] tbody tr td:nth-of-type(1) span {
    -        background: var(--bar-color-1);
    -    }
    -    [data-id="flexbox-bar-graph"] tbody tr td:nth-of-type(2) span {
    -        background: var(--bar-color-2);
    -    }
    -    [data-id="flexbox-bar-graph"] tbody tr td:nth-of-type(3) span {
    -        background: var(--bar-color-3);
    -    }
    -    [data-id="flexbox-bar-graph"] tbody tr td:nth-of-type(4) span {
    -        background: var(--bar-color-4);
    -    }
    -    [data-id="flexbox-bar-graph"] tbody tr td:nth-of-type(5) span {
    -        background: var(--bar-color-5);
    -    }
    -
    -    [data-id="flexbox-bar-graph"] tbody tr td p {
    -        font-size: 90%;
    -        margin: 0;
    -        text-align: center;
    -    }
    +[data-id="flexbox-bar-graph"] thead {
    +    display: block;
    +    margin: 2rem 0 3rem;
    +    width: 100%;
    +}
    +[data-id="flexbox-bar-graph"] thead tr {
    +    border-bottom: 1px solid lightgrey;
    +    display: flex;
    +    justify-content: center;
    +    padding-bottom: 1rem;
    +}
    +
    +[data-id="flexbox-bar-graph"] thead tr th {
    +    display: inline-block;
    +    margin: 0;
    +    padding: 0;
    +    position: relative;
    +    text-align: right;
    +}
    +[data-id="flexbox-bar-graph"] thead tr th:before {
    +    content:'';
    +    display: inline-block;
    +    height: 10px;
    +    margin: 0 0.5rem 0 2rem;
    +    position: relative;
    +    width: 10px;
    +}
    +[data-id="flexbox-bar-graph"] thead tr th:nth-child(1),
    +[data-id="flexbox-bar-graph"] thead tr th:nth-child(1):before {
    +    display: none;
    +}
    +[data-id="flexbox-bar-graph"] thead tr th:nth-child(2):before {
    +    background: var(--bar-color-1);
    +}
    +[data-id="flexbox-bar-graph"] thead tr th:nth-child(3):before {
    +    background: var(--bar-color-2);
    +}
    +[data-id="flexbox-bar-graph"] thead tr th:nth-child(4):before {
    +    background: var(--bar-color-3);
    +}
    +[data-id="flexbox-bar-graph"] thead tr th:nth-child(5):before {
    +    background: var(--bar-color-4);
    +}
    +[data-id="flexbox-bar-graph"] thead tr th:nth-child(6):before {
    +    background: var(--bar-color-5);
    +}
    +
    +[data-id="flexbox-bar-graph"] tbody {
    +    display: flex;
    +    justify-content: space-between;
    +    min-height: 300px;
    +    width: 100%;
    +}
    +
    +[data-id="flexbox-bar-graph"] tbody tr {
    +    display: flex;
    +    flex-direction: column-reverse;
    +    flex-wrap: wrap;
    +    justify-content: flex-end;
    +    padding: 0 50px;
    +    position: relative;
    +    width: 100%;
    +}
    +[data-id="flexbox-bar-graph"] tbody tr th {
    +    font-size: 90%;
    +    position: absolute;
    +    text-align: center;
    +    top: 100%;
    +    width: calc(100% - 100px);
    +}
    +[data-id="flexbox-bar-graph"] tbody tr td {
    +    align-items: center;
    +    display: flex;
    +    flex-direction: column;
    +    height: 95%;
    +    justify-content: flex-end;
    +}
    +
    +[data-id="flexbox-bar-graph"] tbody tr td span {
    +    display: block;
    +    height: calc(var(--data-set) * 100%);
    +    width: 20px;
    +}
    +[data-id="flexbox-bar-graph"] tbody tr td:nth-of-type(1) span {
    +    background: var(--bar-color-1);
    +}
    +[data-id="flexbox-bar-graph"] tbody tr td:nth-of-type(2) span {
    +    background: var(--bar-color-2);
    +}
    +[data-id="flexbox-bar-graph"] tbody tr td:nth-of-type(3) span {
    +    background: var(--bar-color-3);
    +}
    +[data-id="flexbox-bar-graph"] tbody tr td:nth-of-type(4) span {
    +    background: var(--bar-color-4);
    +}
    +[data-id="flexbox-bar-graph"] tbody tr td:nth-of-type(5) span {
    +    background: var(--bar-color-5);
    +}
    +
    +[data-id="flexbox-bar-graph"] tbody tr td p {
    +    font-size: 90%;
    +    margin: 0;
    +    text-align: center;
     }
     
    -

    Bonus Styling

    -

    In the Flexbox Bar Graph repo, I've also included the ability to display these bar graphs horizontally, like so:

    -

    - Flexbox Bar Graph Horizontal -
    The flexbox bar graph in the horizontal layout (direct link to image)
    -

    + +

    }

  • + + +

    Bonus Styling

    + +

    In the Flexbox Bar Graph repo, I’ve also included the ability to display these bar graphs horizontally, like so:

    +

    The change in CSS is actually quite simple to pull this off - you just need to include the data-layout attribute on the table itself.

    -
    [data-layout="horizontal"] tbody {
    +
    +
    [data-layout="horizontal"] tbody {
         min-height: auto;
     }
     
    -[data-layout="horizontal"] tbody tr {
    +[data-layout="horizontal"] tbody tr {
         flex-direction: column;
         padding: 0 40px;
     }
    -[data-layout="horizontal"] tbody tr th {
    +[data-layout="horizontal"] tbody tr th {
         width: calc(100% - 80px);
     }
     
    -[data-layout="horizontal"] tbody tr th {
    +[data-layout="horizontal"] tbody tr th {
         text-align: left;
         top: calc(100% + 20px);
     }
     
    -[data-layout="horizontal"] tbody tr td {
    +[data-layout="horizontal"] tbody tr td {
         flex-direction: row;
         height: auto;
         justify-content: start;
         margin: 10px 0;
     }
     
    -[data-layout="horizontal"] tbody tr td span {
    +[data-layout="horizontal"] tbody tr td span {
         height: 20px;
         width: calc(var(--data-set) * 100%);
     }
     
    -[data-layout="horizontal"] tbody tr td p {
    +[data-layout="horizontal"] tbody tr td p {
         margin-left: 10px;
     }
     
    -

    That's All Folks!

    + +

    That’s All Folks!

    +

    That just about sums things up. Feel free to check out the Github repo itself, open any issues you find or fork it for your own!

    +