<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Scott Bergler</title>
    <description>The latest articles on DEV Community by Scott Bergler (@skillitzimberg).</description>
    <link>https://dev.to/skillitzimberg</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F152325%2F49a55ffe-c589-4724-9f6a-65bf544f19a6.png</url>
      <title>DEV Community: Scott Bergler</title>
      <link>https://dev.to/skillitzimberg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/skillitzimberg"/>
    <language>en</language>
    <item>
      <title>Using Environmental Variables In Firebase Hosting</title>
      <dc:creator>Scott Bergler</dc:creator>
      <pubDate>Tue, 19 Jan 2021 19:26:54 +0000</pubDate>
      <link>https://dev.to/skillitzimberg/using-environmental-variables-in-firebase-hosting-njh</link>
      <guid>https://dev.to/skillitzimberg/using-environmental-variables-in-firebase-hosting-njh</guid>
      <description>&lt;p&gt;Photo Credit: &lt;a href="https://unsplash.com/@mightyhummingbird"&gt;Mariko Margetson&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This article is not really a tutorial or even the answer to a question. In a way it is a question itself. &lt;/p&gt;

&lt;p&gt;Here I explain the problem I was having and how I solved it up to this point, but I'm almost 100% certain that I'm missing some details and understanding.&lt;/p&gt;

&lt;p&gt;My hope is that the article might start some arguments, dialogues and conversations and maybe I'll get more context and information about better ways of solving the problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Assumption:
&lt;/h3&gt;

&lt;p&gt;I'm assuming you are generally familiar with Firebase, Firebase Emulators, and Firebase Functions. If not, let me know and I'll see if I can help. I need to write an article about that whole journey anyway.&lt;/p&gt;

&lt;h3&gt;
  
  
  Context:
&lt;/h3&gt;

&lt;p&gt;An app I'm working on had some API keys hard-coded in it. I wanted to hide this information, but the application needs some of these keys on start up.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem:
&lt;/h3&gt;

&lt;p&gt;This Flutter app is deployed with Firebase Hosting. The Hosting environment does not have environmental variables. So how do I set and get the environmental variables the app needs without hard-coding and committing keys and secrets?&lt;/p&gt;

&lt;p&gt;I followed (as far as I understood it) the advice given by &lt;a href="https://stackoverflow.com/users/209103/frank-van-puffelen"&gt;Frank van Puffelen&lt;/a&gt; on &lt;a href="https://stackoverflow.com/questions/57119794/flutter-firebase-config-variables"&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I know that there are subtlties in his advice that I'm not getting, especially around his comment "If you want them to remain secret, it's not just about not having them in the code, it's about not using them from the client at all." I still don't understand that statement.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution:
&lt;/h3&gt;

&lt;p&gt;In my &lt;code&gt;functions&lt;/code&gt; directory I created a &lt;code&gt;.runtimeconfig.json&lt;/code&gt; file (and added it to my &lt;code&gt;.gitignore&lt;/code&gt;) with the various keys I needed. This is the local development way of setting environmental variables for Firebase Functions.&lt;/p&gt;

&lt;p&gt;Then I wrote an &lt;code&gt;HTTPS&lt;/code&gt; cloud function called &lt;code&gt;getEnv&lt;/code&gt;. This function returns the Functions &lt;code&gt;functions.config()&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;Now I am able to get the keys and secrets I need to start the app by fetching the config object from the &lt;code&gt;getEnv&lt;/code&gt; function as the app is starting up.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final code:
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;functions/.runtimeconfig.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "algolia": {
    "appid": "ID",
    "apikey": "KEY"
  },
  "webmerge": {
    "key": "KEY",
    "secret": "SECRET",
    "stashkey": "STASH_KEY"
  },
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In &lt;code&gt;functions/index.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';

. . .

const cors = require('cors')({origin: true});
const envObj = functions.config();

. . .

admin.initializeApp();

export const getEnv = functions.https.onRequest((req, resp) =&amp;gt; {
  cors(req, resp, () =&amp;gt; resp.status(200).send(JSON.stringify(envObj)));
});

. . .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NOTE: I used the &lt;code&gt;cors&lt;/code&gt; package to get around CORS errors when working locally. I would get these errors when &lt;code&gt;localhost:5000&lt;/code&gt; (Emulator hosting) called &lt;code&gt;localhost:5001&lt;/code&gt; (Emulator functions).&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;web_flutter/main.dart&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Future&amp;lt;Map&amp;lt;String, dynamic&amp;gt;&amp;gt; fetchEnv(String functionsURL) async {
  var response = await http.get('${functionsURL}/getEnv');
  return json.decode(response.body);
}

Future&amp;lt;void&amp;gt; main() async {
  try {
    var functionsURL = 'FUNCTIONS_URL';
    var app = fb.initializeApp(firebase app details);
    if (window.location.hostname == 'localhost') {
      app.firestore().settings(Settings(
            host: 'localhost:8080',
            ssl: false,
          ));
      functionsURL = 'http://localhost:5001';
    }

    var env = await fetchEnv(functionsURL);

    var searchClient = Algolia.init(
        applicationId: env['algolia']['appid'],
        apiKey: env['algolia']['apikey']);

    runApp(MyApp(
        repository: Repository(app.firestore(), searchClient),
        authentication: Authentication(app.auth())));
  } on fb.FirebaseJsNotLoadedException catch (e) {
    print(e);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once I confirmed that this was working locally, I was able to use &lt;code&gt;firebase functions:config:set&lt;/code&gt; to set this data in the live Functions environment and deploy my updated hosting and functions with &lt;code&gt;firebase deploy&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Your Thoughts?
&lt;/h3&gt;

&lt;p&gt;I'd love to hear your thoughts and experience with environmental variables in general and specific to Firebase. Is there a better way to do this?&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>firebase</category>
      <category>hosting</category>
      <category>functions</category>
    </item>
    <item>
      <title>Micro Project: Responsive Menu</title>
      <dc:creator>Scott Bergler</dc:creator>
      <pubDate>Fri, 12 Jun 2020 16:47:34 +0000</pubDate>
      <link>https://dev.to/skillitzimberg/micro-project-responsive-menu-bj4</link>
      <guid>https://dev.to/skillitzimberg/micro-project-responsive-menu-bj4</guid>
      <description>&lt;p&gt;I watched &lt;a href="https://www.youtube.com/watch?v=DZg6UfS5zYg"&gt;Brad Traversy's&lt;/a&gt; and &lt;a href="https://www.youtube.com/watch?v=sjrp1FEHnyA&amp;amp;t=45s"&gt;FollowAndrew's&lt;/a&gt; tutorials about this and deconstructed them to make sense to me. This article is the result.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Objective
&lt;/h1&gt;

&lt;p&gt;A menu that displays as a hamburger menu when the viewport is small and as an inline list when the viewport is larger.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Plan
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Start the HTML.&lt;/li&gt;
&lt;li&gt;Toggle the menu between open and closed.&lt;/li&gt;
&lt;li&gt;Create the hamburger.&lt;/li&gt;
&lt;li&gt;Hide the toggler.&lt;/li&gt;
&lt;li&gt;Change the hamburger into an 'X' when the menu is open.&lt;/li&gt;
&lt;li&gt;Make the menu display for larger viewports.&lt;/li&gt;
&lt;li&gt;Make the transitions between open and closed smoother.&lt;/li&gt;
&lt;li&gt;Make some initial typography choices.&lt;/li&gt;
&lt;li&gt;Add more general layout.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  The HTML
&lt;/h1&gt;

&lt;p&gt;This is the beginning of our &lt;code&gt;index.html&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;

&amp;lt;head&amp;gt;
  &amp;lt;meta charset="UTF-8"&amp;gt;
  &amp;lt;meta
    name="viewport"
    content="width=device-width, initial-scale=1.0"
  &amp;gt;
  &amp;lt;title&amp;gt;A Responsive Menu&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;

&amp;lt;body&amp;gt;

&amp;lt;/body&amp;gt;

&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I'm making the assumption that our navigation menu will be a part of our page's header, so let's add the header and nav tags:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;. . .
&amp;lt;body&amp;gt;
  &amp;lt;header&amp;gt;
    &amp;lt;nav&amp;gt;

    &amp;lt;/nav&amp;gt;
  &amp;lt;/header&amp;gt;
&amp;lt;/body&amp;gt;
. . .
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To be able to toggle our menu between opened and closed we need some kind of boolean state. A checkbox input will give us this. We'll give it the id of &lt;code&gt;toggler&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;. . .
&amp;lt;body&amp;gt;
  &amp;lt;header&amp;gt;
    &amp;lt;nav&amp;gt;
      &amp;lt;input
        type="checkbox"
        id="toggler"
      &amp;gt;
    &amp;lt;/nav&amp;gt;

  &amp;lt;/header&amp;gt;
&amp;lt;/body&amp;gt;
. . .
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now we can add our menu options.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;. . .
  &amp;lt;header&amp;gt;
    &amp;lt;nav&amp;gt;
      &amp;lt;input
        type="checkbox"
        id="toggler"
      &amp;gt;

      &amp;lt;ul&amp;gt;
        &amp;lt;li&amp;gt;&amp;lt;a href="#projects"&amp;gt;projects&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
        &amp;lt;li&amp;gt;&amp;lt;a href="#about"&amp;gt;about&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
        &amp;lt;li&amp;gt;&amp;lt;a href="#contact"&amp;gt;contact&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
      &amp;lt;/ul&amp;gt;
    &amp;lt;/nav&amp;gt;

  &amp;lt;/header&amp;gt;
. . .
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Back to the plan&lt;/p&gt;

&lt;h1&gt;
  
  
  Toggling The Menu
&lt;/h1&gt;

&lt;p&gt;Let's start working on the toggle functionality. Create a &lt;code&gt;css&lt;/code&gt; directory and a &lt;code&gt;menu.css&lt;/code&gt; file and add a link to the css file in the &lt;code&gt;index.html&lt;/code&gt; &lt;code&gt;head&lt;/code&gt;. Here's the relevant parts of the updated &lt;code&gt;index.html&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;

&amp;lt;head&amp;gt;
  &amp;lt;meta charset="UTF-8"&amp;gt;
  &amp;lt;meta
    name="viewport"
    content="width=device-width, initial-scale=1.0"
  &amp;gt;
/* This is the link to the css file. */
  &amp;lt;link
    rel="stylesheet"
    href="css/menu.css"
  &amp;gt;

  &amp;lt;title&amp;gt;Responsive Navigation&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;

&amp;lt;body&amp;gt;
. . .
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The menu options are what we will be hiding or showing depending on the state of the checkbox. When the checkbox is not checked we want the menu closed. To do this we'll give the unordered list (&lt;code&gt;ul&lt;/code&gt;) a &lt;code&gt;max-height&lt;/code&gt; of 0 to collapse it and hide its contents with &lt;code&gt;overflow: hidden&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* 1. Toggle the menu */
ul {
  max-height: 0;
  overflow: hidden;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next we want to open the menu when the checkbox is checked. We can check the state of the checkbox and if it's checked we can expand the height of the &lt;code&gt;ul&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* 1. Toggle the menu */
ul {
  max-height: 0;
  overflow: hidden;
}

#toggler:checked ~ ul {
  max-height: 240px;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The tilde (&lt;code&gt;~&lt;/code&gt;) is a subsequent-sibling combinator. So &lt;code&gt;#toggler:checked ~ ul&lt;/code&gt; says, "when &lt;code&gt;#toggler&lt;/code&gt; is checked select the next &lt;code&gt;ul&lt;/code&gt; tag that is a sibling of &lt;code&gt;#toggler&lt;/code&gt; and set its &lt;code&gt;max-height&lt;/code&gt; to 240px."&lt;/p&gt;

&lt;p&gt;If you open the &lt;code&gt;index.html&lt;/code&gt; file in your browser you should see a lonely checkbox:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dMx4Myfa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9h2bajqevte3bu8jizjt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dMx4Myfa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9h2bajqevte3bu8jizjt.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if you click on the checkbox you should see your menu:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--23r9kRuI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tg0gjuufy3l87j1e1iur.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--23r9kRuI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tg0gjuufy3l87j1e1iur.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Back to the plan&lt;/p&gt;
&lt;h1&gt;
  
  
  Create the hamburger
&lt;/h1&gt;

&lt;p&gt;Right now we have a bare checkbox input. We're going to replace it with a hamburger.&lt;/p&gt;

&lt;p&gt;Since we want to get rid of the checkbox we'll need an element to take its place. A cool thing about HTML inputs is that when paired with a &lt;code&gt;label&lt;/code&gt; tag, a click on the &lt;code&gt;label&lt;/code&gt; does the same thing as clicking on the input.&lt;/p&gt;

&lt;p&gt;Let's add a &lt;code&gt;label&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;body&amp;gt;
  &amp;lt;header&amp;gt;
    &amp;lt;nav&amp;gt;
      &amp;lt;input
        type="checkbox"
        id="toggler"
      &amp;gt;
      &amp;lt;-- Here's the label. --&amp;gt;
      &amp;lt;label for="toggler"&amp;gt;
        Toggle me.
      &amp;lt;/label&amp;gt;

      &amp;lt;ul&amp;gt;
        &amp;lt;li&amp;gt;&amp;lt;a href="#projects"&amp;gt;projects&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
        &amp;lt;li&amp;gt;&amp;lt;a href="#about"&amp;gt;about&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
        &amp;lt;li&amp;gt;&amp;lt;a href="#contact"&amp;gt;contact&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
      &amp;lt;/ul&amp;gt;
    &amp;lt;/nav&amp;gt;
  &amp;lt;/header&amp;gt;
&amp;lt;/body&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Clicking on "Toggle me" will open and close the menu. Our hamburger will go here instead.&lt;/p&gt;

&lt;p&gt;The classic hamburger is three horizontal lines. We will style a single &lt;code&gt;span&lt;/code&gt; tag so that it will create these three lines.&lt;/p&gt;

&lt;p&gt;First we add the &lt;code&gt;span&lt;/code&gt; tag with an id of "hamburger":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;body&amp;gt;
  &amp;lt;header&amp;gt;
    &amp;lt;nav&amp;gt;
      &amp;lt;input
        type="checkbox"
        id="toggler"
      &amp;gt;
      &amp;lt;label for="toggler"&amp;gt;
        &amp;lt;-- The new span tag. --&amp;gt;
        &amp;lt;span id="hamburger"&amp;gt;&amp;lt;/span&amp;gt;
      &amp;lt;/label&amp;gt;

      &amp;lt;ul&amp;gt;
. . .
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In our css file we'll give this span a width, height, and background color so we can see it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#hamburger {
  display: block;
  height: 2px;
  width: 25px;
  background-color: black;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Notice that &lt;code&gt;span&lt;/code&gt; is an inline element. In order to give it width and height we set it to &lt;code&gt;display: block&lt;/code&gt;. We could have used a &lt;code&gt;div&lt;/code&gt; here instead and saved a line of css. For completely subjective reasons I prefer the &lt;code&gt;span&lt;/code&gt; here. And none of the other semantic HTML tags made much sense to me  in this context. I'd love to hear your thoughts on other choices.&lt;/p&gt;

&lt;p&gt;Now we have the burger in our hamburger. Next for the buns.&lt;/p&gt;

&lt;p&gt;Our buns are going to have the same basic starting point as the burger. We can add the &lt;code&gt;::before&lt;/code&gt; and &lt;code&gt;::after&lt;/code&gt; pseudo-elements to the &lt;code&gt;span&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#hamburger,
#hamburger::before,
#hamburger::after {
  display: block;
  height: 2px;
  width: 25px;
  background-color: black;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;These pseudo-elements will render something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      &amp;lt;label for="toggler"&amp;gt;
        &amp;lt;-- The new span tag. --&amp;gt;
        &amp;lt;span id="hamburger"&amp;gt;
          ::before
          ::after
        &amp;lt;/span&amp;gt;
      &amp;lt;/label&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;At first, all three of these &lt;code&gt;span&lt;/code&gt;s will display right on top of each other, so you won't see them. We're going to move the &lt;code&gt;::before&lt;/code&gt; and &lt;code&gt;::after&lt;/code&gt; &lt;code&gt;span&lt;/code&gt;'s above and below the original &lt;code&gt;span&lt;/code&gt;, respectively.&lt;/p&gt;

&lt;p&gt;In order to move the pseudo-elements, which are children of the original &lt;code&gt;span&lt;/code&gt;, we need to give the original a position of relative. Below the rest of the css rule sets add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#hamburger {
  position: relative;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We also need to give the pseudo-elements a position of absolute which let's us move them in relation to their parent, the original &lt;code&gt;span&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#hamburger::before,
#hamburger::after {
  position: absolute;
  content: '';
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note that we added the property &lt;code&gt;content&lt;/code&gt; with a value of an empty string. Without this the pseudo-elements won't be rendered because they wouldn't have anything to display. Without content, they won't acknowledge other styles applied to them.&lt;/p&gt;

&lt;p&gt;Now we can move the &lt;code&gt;::before&lt;/code&gt; up and the &lt;code&gt;::after&lt;/code&gt; down by adding these rule sets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#hamburger::before {
  top: -5px;
}

#hamburger::after {
  top: 5px;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Back to the plan&lt;/p&gt;

&lt;h1&gt;
  
  
  Hide the toggler
&lt;/h1&gt;

&lt;p&gt;We don't need to see the checkbox anymore to be able to toggle the menu, so let's hide it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#toggler {
  display: none;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Back to the plan&lt;/p&gt;

&lt;h1&gt;
  
  
  X Marks The Spot
&lt;/h1&gt;

&lt;p&gt;We're going to transform our hamburger into an 'X' by rotating the &lt;code&gt;::before&lt;/code&gt; and &lt;code&gt;::after&lt;/code&gt; buns and disappearing the burger by adding these rule sets to our css:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#toggler:checked ~ label #hamburger {
  background: transparent;
}

#toggler:checked ~ label #hamburger::before {
  transform: rotate(-45deg);
  top: 0;
}

#toggler:checked ~ label #hamburger::after {
  transform: rotate(45deg);
  top: 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;By setting the &lt;code&gt;top&lt;/code&gt; property on &lt;code&gt;::before&lt;/code&gt; and &lt;code&gt;::after&lt;/code&gt; to 0, we bring them both back down on top of the burger. Now when they are rotated their centers are matched up giving us an 'X'.&lt;/p&gt;

&lt;p&gt;Back to the plan&lt;/p&gt;

&lt;h1&gt;
  
  
  A Menu For Larger Viewports
&lt;/h1&gt;

&lt;p&gt;The view we've created so far is meant for smaller devices. If the user has more real estate we'll show them a menu better suited to their screen. We'll use a media query for this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@media (min-width: 42em) {

}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;min-width&lt;/code&gt; of &lt;code&gt;42em&lt;/code&gt; is totally subjective. If the user hasn't changed the base font size of their browser &lt;code&gt;1em&lt;/code&gt; is about 16px. This comes out to 672px.&lt;/p&gt;

&lt;p&gt;The first thing we want to do is hide the hamburger.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@media (min-width: 42em) {
  /* Hide the hamburger */
  label {
    display: none;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The next thing I want to do is stop limiting the height of the menu. This way it will always be visible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@media (min-width: 42em) {
  /* Hide the hamburger */
  label {
    display: none;
  }

  ul {
    max-height: none;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now I want the items to lay out in line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@media (min-width: 42em) {
  /* Hide the hamburger */
  label {
    display: none;
  }

  ul {
    max-height: none;
  }

  li {
    float: left;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We'll come back to this in the layout section.&lt;/p&gt;

&lt;p&gt;Back to the plan&lt;/p&gt;

&lt;h1&gt;
  
  
  Easing Transitions
&lt;/h1&gt;

&lt;p&gt;I'm working on developing my eye for design and the niceties of UI/UX. In putting this project together I learned about transitions. This is still pretty subtle for me and very brand new.&lt;/p&gt;

&lt;p&gt;When the menu is opened, it just appears, pops into existence, and is equally abrupt when leaving. We can smooth this out. In our &lt;code&gt;menu.css&lt;/code&gt; file let's revisit our rule set for the &lt;code&gt;ul&lt;/code&gt; tag and use the &lt;code&gt;transition&lt;/code&gt; property.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ul {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.2s ease;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;transition&lt;/code&gt; property attaches itself to some other property declared on an element and moderates the transition between the two states. Here we're saying that when the &lt;code&gt;ul&lt;/code&gt; (the menu) is revealed or hidden that we want this to take two tenths of a second. Play around with this value. What feels best to you?&lt;br&gt;
Chris Coyler has &lt;a href="https://css-tricks.com/ease-out-in-ease-in-out/"&gt;some thoughts&lt;/a&gt; about this that I'm still grappling with.&lt;/p&gt;

&lt;p&gt;We can also smooth out the transition between the hamburger and X states of our menu icon. Again, revisiting our &lt;code&gt;menu.css&lt;/code&gt; and the &lt;code&gt;::before&lt;/code&gt;/&lt;code&gt;::after&lt;/code&gt; state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
#hamburger::before,
#hamburger::after {
  position: absolute;
  content: '';
  transition: all 0.2s ease;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;all&lt;/code&gt; here means any of the properties on these elements that are manageable by &lt;code&gt;transition&lt;/code&gt;. In particular we're attaching this to the &lt;code&gt;top&lt;/code&gt; and &lt;code&gt;transform&lt;/code&gt; properties we defined earlier.&lt;/p&gt;

&lt;p&gt;Again, play with these. Where else might you want transitions? Are there better ways of implementing them? Please let me know what you find!&lt;/p&gt;

&lt;p&gt;Back to the plan&lt;/p&gt;

&lt;h1&gt;
  
  
  Typography
&lt;/h1&gt;

&lt;p&gt;We're not going super deep here, but we'll want our fonts to be styled so that when we start working on the layout we can react to something closer to our end goal.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;css&lt;/code&gt; directory create a &lt;code&gt;main.css&lt;/code&gt; file. Add a link to it in &lt;code&gt;index.html&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;

&amp;lt;head&amp;gt;
  &amp;lt;meta charset="UTF-8"&amp;gt;
  &amp;lt;meta
    name="viewport"
    content="width=device-width, initial-scale=1.0"
  &amp;gt;
  &amp;lt;-- Linking to our more general styles --&amp;gt;
  &amp;lt;link
    rel="stylesheet"
    href="css/main.css"
  &amp;gt;
  &amp;lt;link
    rel="stylesheet"
    href="css/menu.css"
  &amp;gt;
  &amp;lt;title&amp;gt;Responsive Navigation&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
. . . 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In &lt;code&gt;main.css&lt;/code&gt; we'll add a base font for the whole page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;body {
  font-family: Arial, Helvetica, sans-serif;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let's replace the default anchor tag styling.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a {
  color: black;
  text-decoration: none;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Back to the plan&lt;/p&gt;

&lt;h1&gt;
  
  
  Layout
&lt;/h1&gt;

&lt;p&gt;For better or for worse, I like to do styling and layout last. I prefer to get the mechanics working first. I've seen people far more skilled than I jump back and forth between styling/layout and mechanics or even start with styling/layout. So there's probably no right or wrong here. Do what gets it done and is most interesting for you.&lt;/p&gt;

&lt;p&gt;To get to a basic starting point for all tags I removed margin and padding globally in &lt;code&gt;main.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* {
  margin: 0;
  padding: 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This seems to mess things up for us. The hamburger almost left the screen.&lt;/p&gt;

&lt;p&gt;Our &lt;code&gt;nav&lt;/code&gt; contains our hamburger and our menu, but is not something we are actually seeing. So let's leave it alone and work with the tags we are seeing. We can bump the hamburger down by giving the &lt;code&gt;label&lt;/code&gt; some margin. &lt;code&gt;label&lt;/code&gt;s are inline elements so we set the &lt;code&gt;display&lt;/code&gt; property to &lt;code&gt;block&lt;/code&gt; to apply margins.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;label {
  display: block;
  margin: 2em;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I'm using &lt;code&gt;em&lt;/code&gt;s because I'm thinking that tying layout to the font size might help give the page some kind of cohesion. I could be very wrong about this, but it's working for me right now.&lt;/p&gt;

&lt;p&gt;I want the hamburger and all of the navigation to be on the right side of the header so in &lt;code&gt;menu.css&lt;/code&gt; I added:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nav {
  float: right;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I'm noticing that it can be difficult to click on the hamburger/X. You have to click very precisely. If you put a border on the label you'll see why. Changing the &lt;code&gt;label&lt;/code&gt;'s &lt;code&gt;margin&lt;/code&gt; to &lt;code&gt;1em&lt;/code&gt; and adding a &lt;code&gt;padding&lt;/code&gt; of &lt;code&gt;1em&lt;/code&gt; fixes this.&lt;/p&gt;

&lt;p&gt;The next thing I notice is that the menu items are scrunched together. Also in &lt;code&gt;menu.css&lt;/code&gt; I give them some room with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;li {
  padding: 1em;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That all seems to be in a pretty good spot now. This is a deep rabbit hole and it all comes down to your particular use case. Now what about bigger screens? Let's revisit our media query.&lt;/p&gt;

&lt;p&gt;We've got a good start, but if you play with the screen width you'll see that the items appear slightly above the hamburger. I want them to replace the hamburger, to kind of slide out to left of it. The items still have &lt;code&gt;1em&lt;/code&gt; of padding from the small screen layout. I'm removing that so that I can get a better sense of where things should be in the new layout.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@media (min-width: 42em) {
  /* Hide the hamburger */
  label {
    display: none;
  }

  ul {
    max-height: none;
  }

  li {
    float: left;
    padding: 0;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I'll use &lt;code&gt;margin&lt;/code&gt; to move the &lt;code&gt;ul&lt;/code&gt; down &lt;code&gt;1.5em&lt;/code&gt; so that the items' mid-line lines up with the mid-line of the hamburger, and move the right side over &lt;code&gt;2em&lt;/code&gt; to match up with the hamburger.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ul {
    max-height: none;
    margin: 1.5em 2em 0 0;
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Almost there! I want to give the items their space back and add a bit of demarcation between them with a right-side border:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  li {
    float: left;
    padding: 0 1.5em;
    border-right: 1px solid black;
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And that's it. There's a lot of variations and fixes to be done, but it really depends on where and how you're using the menu. So this is a good jumping off place.&lt;/p&gt;

&lt;p&gt;Writing this was an amazing exercise and I learned so much! I hope it's been useful for you, too. Please let me know if you have any questions, suggestions, or corrections.&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>A Fast &amp; Dirty TypeScript Project: </title>
      <dc:creator>Scott Bergler</dc:creator>
      <pubDate>Wed, 04 Dec 2019 13:44:07 +0000</pubDate>
      <link>https://dev.to/skillitzimberg/a-fast-dirty-typescript-project-3lbl</link>
      <guid>https://dev.to/skillitzimberg/a-fast-dirty-typescript-project-3lbl</guid>
      <description>&lt;h1&gt;
  
  
  A Fast &amp;amp; Dirty TypeScript Project
&lt;/h1&gt;

&lt;p&gt;Between work and my own personal development projects I’m usually switching back and forth between many languages, frameworks, tools, and code bases. Sometimes I forget how to do what seems like should be the simplest, most basic things. I decided to write this short article because I was frustrated with myself and the situation I found myself in. I thought writing this down might help me remember that I know how to do this and maybe help other beginners who have similar needs/problems.&lt;/p&gt;

&lt;p&gt;At work we ran into a problem and need to pivot to incorporate a challenging (for me at least) new API. I don’t want to go through all the hoops to set that up in the context of the app. I just want to play with the API in a setting that I have complete control over (not &lt;a href="https://glitch.com/"&gt;Glitch&lt;/a&gt;, &lt;a href="https://stackblitz.com/"&gt;Stackblitz&lt;/a&gt;, &lt;a href="https://codepen.io/"&gt;Codepen&lt;/a&gt;, et al — I’m sure they are perfectly viable, but for some reason they never work for me and I’d rather know all the cogs I have in place and why they’re there, plus it’s good for me to keep practicing building from the ground up).&lt;/p&gt;

&lt;p&gt;I just need a small console app to check out the new API. Our project uses TypeScript for Firebase cloud functions and Axios for working with third party APIs.&lt;/p&gt;

&lt;p&gt;Here are the steps I took:&lt;br&gt;
1) Create a new project directory in my development directory. In my case ‘axios_tests’. &lt;code&gt;mkdir axios_tests&lt;/code&gt;&lt;br&gt;
2) &lt;code&gt;cd axios_tests&lt;/code&gt;&lt;br&gt;
3) &lt;code&gt;npm init&lt;/code&gt; to create the package.json file&lt;br&gt;
4) &lt;code&gt;npm install typescript&lt;/code&gt; to add TypeScript to the package.json dependencies. Technically this should have been &lt;code&gt;npm install typescript --save-dev&lt;/code&gt; to save it to the dev-dependencies but this ‘project’ is never going to be in production — fast &amp;amp; dirty.&lt;br&gt;
5) &lt;code&gt;npm install axios&lt;/code&gt; and do the same for Axios&lt;br&gt;
6) &lt;code&gt;tsc --init&lt;/code&gt; to create a standard tsconfig.json file&lt;br&gt;
7) Because I’m going to be using Promises and &lt;code&gt;console.log()&lt;/code&gt; I found out that I needed to add the &lt;code&gt;es2015&lt;/code&gt; &amp;amp; &lt;code&gt;dom&lt;/code&gt; to the &lt;code&gt;tsconfig.json&lt;/code&gt; compilerOptions. Other than that addition these are the default settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "lib": [
            "es2015",
            "dom"
    ],
    "strict": true,
    "esModuleInterop": true,
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;8) create an &lt;code&gt;index.ts&lt;/code&gt; file&lt;br&gt;
9) To make sure Axios is working I used this in &lt;code&gt;index.ts&lt;/code&gt; (Thank you, &lt;a href="https://flaviocopes.com/"&gt;Flavio Copes&lt;/a&gt;!)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as axios from "axios";
(async () =&amp;gt; {
  console.log(await axios.default({
    url: 'https://dog.ceo/api/breeds/list/all'
  }))
})();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;10) &lt;code&gt;tsc index.ts&lt;/code&gt; to compile the TypeScript to JavaScript&lt;br&gt;
11) &lt;code&gt;node index.js&lt;/code&gt; to run the JavaScript file&lt;/p&gt;

&lt;p&gt;And I got back a big list of dogs in the console . . .&lt;/p&gt;

&lt;p&gt;Now I’m set up to start building out just the code I need to work with the new API without first having to figure out how to wire everything up in the larger project which will include writing/refactoring and deploying cloud functions, possibly adding a new Firebase collection, and likely some UI changes.&lt;/p&gt;

&lt;p&gt;I hope this helps someone other than me. Please let me know if you have questions, better ideas for doing this sort of thing, or see problems.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>axios</category>
    </item>
  </channel>
</rss>
