<?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>Forem: Nate Gibbons</title>
    <description>The latest articles on Forem by Nate Gibbons (@marshallformula).</description>
    <link>https://forem.com/marshallformula</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%2F16815%2F31f03729-266e-4bf4-b9f2-32568675e086.png</url>
      <title>Forem: Nate Gibbons</title>
      <link>https://forem.com/marshallformula</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/marshallformula"/>
    <language>en</language>
    <item>
      <title>Harness the Power of the Union Type (part 1)</title>
      <dc:creator>Nate Gibbons</dc:creator>
      <pubDate>Tue, 14 Nov 2017 14:08:31 +0000</pubDate>
      <link>https://forem.com/marshallformula/harness-the-power-of-the-union-type-part-1-3fc</link>
      <guid>https://forem.com/marshallformula/harness-the-power-of-the-union-type-part-1-3fc</guid>
      <description>&lt;p&gt;Originally posted at &lt;a href="https://marshallformula.codes/harness-the-power-of-the-union/" rel="noopener noreferrer"&gt;marshallformula.codes&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;I've been using elm at &lt;a href="https://volumeintegration.com" rel="noopener noreferrer"&gt;work&lt;/a&gt; for about a year and a half at this point. Elm was my first experience in a purely functional language and I'm still deeply smitten.  I'm still only beginning to scratch the surface of what functional programming has to offer. I keep discovering these new gems of insight and making new cognitive connections. One such recent discovery was the inherent power of the &lt;a href="https://guide.elm-lang.org/types/union_types.html" rel="noopener noreferrer"&gt;Union Type&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A point of Clarification
&lt;/h2&gt;

&lt;p&gt;Technicaly speaking - the construct that Elm uses is a &lt;a href="https://en.wikipedia.org/wiki/Tagged_union" rel="noopener noreferrer"&gt;Tagged Union Type&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;a data structure used to hold a value that could take on several different, but fixed, types. Only one of the types can be in use at any one time, and a tag field explicitly indicates which one is in use&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Additionally - other &lt;a href="https://wiki.haskell.org/Algebraic_data_type" rel="noopener noreferrer"&gt;languages&lt;/a&gt; call it an &lt;a href="https://en.wikipedia.org/wiki/Algebraic_data_type" rel="noopener noreferrer"&gt;Algebraic Data Type&lt;/a&gt; (or ADT).&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use it
&lt;/h2&gt;

&lt;p&gt;Before we get to some concrete examples - I'd like to clear up some misconceptions that I started with when first learning about Union Types in elm.  Here's what a Union Type looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Shape&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Cirle&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Rectangle&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Triangle&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Based on the definition above and this example - you might be assuming (as I was) that this is basically just an enum.  This is not a bad place to start. You can definitely use a Union Type in the same manner as an enum, but you would be missing the real power that it provides.&lt;/p&gt;

&lt;p&gt;It may help first to discuss some of the terminology when talking about Union Types. In our example above, the type is a &lt;code&gt;Shape&lt;/code&gt; and each of the specified values of &lt;code&gt;Shape&lt;/code&gt; are the &lt;strong&gt;type constructors&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Shape&lt;/span&gt;     &lt;span class="c1"&gt;-- Type definition&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Circle&lt;/span&gt;   &lt;span class="c1"&gt;-- Circle Shape constructor&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Rectangle&lt;/span&gt;   &lt;span class="c1"&gt;-- Rectangle Shape constructor&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Triangle&lt;/span&gt; &lt;span class="c1"&gt;-- Triangle Shape constructor&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Coming from an Object-Oriented background - this delineation of terms is what really made things start to click for me. The constructors are used to create a &lt;code&gt;Shape&lt;/code&gt; value - just like a class (which can have multiple constructors) would use constructors to instantiate a class object. Now that's just about where the similarities end so don't take that concept too far, but perhaps that association might trigger some further understanding as it did for me.&lt;/p&gt;

&lt;p&gt;So lets start using our new &lt;code&gt;Shape&lt;/code&gt; type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;makeCircle&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Shape&lt;/span&gt;
&lt;span class="n"&gt;makeCircle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Circle&lt;/span&gt;

&lt;span class="n"&gt;makeRectangle&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Shape&lt;/span&gt;
&lt;span class="n"&gt;makeRectangle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Rectangle&lt;/span&gt;

&lt;span class="c1"&gt;-- you get it&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok.  Admittedly that's pretty underwhelming. But it does demonstrate how to use the &lt;code&gt;Shape&lt;/code&gt;'s constructors to create new &lt;code&gt;Shape&lt;/code&gt; types.  Let's make it a little more interesting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tag Payload
&lt;/h3&gt;

&lt;p&gt;So far - our &lt;code&gt;Shape&lt;/code&gt; is not much more than an enum. If you actually continued reading the &lt;a href="https://en.wikipedia.org/wiki/Tagged_union" rel="noopener noreferrer"&gt;wikipedia entry referenced above&lt;/a&gt; you might have seen this snippet:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An enumerated type can be seen as a degenerate case: a tagged union of unit types. It corresponds to a set of nullary constructors and may be implemented as a simple tag variable, since it holds no additional data besides the value of the tag.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Did that last sentence imply that unlike an enum type - the tag of a union type can hold data?  Why yes it did.  Nice catch.  &lt;/p&gt;

&lt;p&gt;This is where the real power of the union type comes in to play.  A union type's constructors can specify additonal data (think arguments to a constructor function in OO) that are required to construct that version of the union type. Now we can make our &lt;code&gt;Shape&lt;/code&gt; a little more useful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Shape&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Circle&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Rectangle&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Triangle&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neat! Now the &lt;code&gt;Circle&lt;/code&gt; can store it's radius, the &lt;code&gt;Rectangle&lt;/code&gt; can store it's height and width, and the &lt;code&gt;Triangle&lt;/code&gt; can store the length of it's sides (we'll keep things simple for now and only allow equilateral triangles).&lt;/p&gt;

&lt;p&gt;Now - you might be arguing that it's not completely obvious that the &lt;code&gt;Rectangle&lt;/code&gt;'s two constructor arguments are meant to be the width and height - since all we see is that it takes two &lt;code&gt;Int&lt;/code&gt; values. Here's a tip... &lt;code&gt;alias&lt;/code&gt; is your friend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Radius&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Side&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;

&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Shape&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Circle&lt;/span&gt; &lt;span class="kt"&gt;Radius&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Rectangle&lt;/span&gt; &lt;span class="kt"&gt;Height&lt;/span&gt; &lt;span class="kt"&gt;Width&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Triangle&lt;/span&gt; &lt;span class="kt"&gt;Side&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That might be a little overkill for our simple example - but it illustrates how constructor definitions can be very explicit. I use the this technique anytime that my constructor arguments might be ambigious or confusing. I've found it incredibly valuable.&lt;/p&gt;

&lt;p&gt;We'd better fix our creator functions to reflect our new type constructors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;makeCircle&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Radius&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Shape&lt;/span&gt;
&lt;span class="n"&gt;makeCircle&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Circle&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt;

&lt;span class="n"&gt;makeRectangle&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Height&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Width&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Shape&lt;/span&gt;
&lt;span class="n"&gt;makeRectangle&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Rectangle&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;

&lt;span class="n"&gt;makeTriangle&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Side&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Shape&lt;/span&gt;
&lt;span class="n"&gt;makeTriangle&lt;/span&gt; &lt;span class="n"&gt;side&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Triangle&lt;/span&gt; &lt;span class="n"&gt;side&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Ok - on to the really good stuff. Now that we have different type constructors - we need a way to retrieve data we're storing in the type. In order to do that we need to use &lt;a href="https://gist.github.com/yang-wei/4f563fbf81ff843e8b1e" rel="noopener noreferrer"&gt;pattern matching&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So lets create function that will find the perimiter of a given shape:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;pi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="c1"&gt;-- rounding for simplicity&lt;/span&gt;

&lt;span class="n"&gt;findPerimeter&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Shape&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;findPerimeter&lt;/span&gt; &lt;span class="n"&gt;shape&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kr"&gt;case&lt;/span&gt; &lt;span class="n"&gt;shape&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt; 
        &lt;span class="kt"&gt;Circle&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; 
            &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;pi&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt;

        &lt;span class="kt"&gt;Rectangle&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="kt"&gt;Triangle&lt;/span&gt; &lt;span class="n"&gt;side&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;side&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;-- again equilateral triangle for simplicity&lt;/span&gt;


&lt;span class="c1"&gt;-- let's try it out&lt;/span&gt;

&lt;span class="n"&gt;findPerimeter&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;makeCircle&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;        &lt;span class="c1"&gt;-- 30&lt;/span&gt;

&lt;span class="n"&gt;findPerimiter&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;makeRectangle&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;-- 24&lt;/span&gt;

&lt;span class="n"&gt;findPerimeter&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;makeTriangle&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="c1"&gt;-- 18&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty sweet right? But what happens when we get a new requirement to support a new shape... say a &lt;code&gt;Hexagon&lt;/code&gt;.  Well, let's just add a new constructor then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Shape&lt;/span&gt;
    &lt;span class="c1"&gt;-- other types already defined here&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Hexagon&lt;/span&gt; &lt;span class="kt"&gt;Side&lt;/span&gt; &lt;span class="c1"&gt;-- equal sides for simplicity&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Easy Peasy. Now, perhaps you thought we had already exposed all of the awesomeness that union types had to offer? Good news... &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmarshallformula.codes%2Fcontent%2Fimages%2F2017%2F11%2Fron.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmarshallformula.codes%2Fcontent%2Fimages%2F2017%2F11%2Fron.gif" alt="ron"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yep!  More awesome headed your way.  You see we've just added a new type constructor, however we forgot to account for it in the &lt;code&gt;findPerimeter&lt;/code&gt; function.  You see - unlike in other languages, or by using an enum - our friendly elm compiler simply won't let this stand.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-- MISSING PATTERNS ---------------------------------------------

This `case` does not have branches for all possibilities.

|&amp;gt;    case shape of
|&amp;gt;        Circle radius -&amp;gt;
|&amp;gt;            2 * pi * radius
|&amp;gt;
|&amp;gt;        Rectangle height width -&amp;gt;
|&amp;gt;            (height * 2) + (width * 2)
|&amp;gt;
|&amp;gt;        Triangle side -&amp;gt;
|&amp;gt;            (side * 3)

You need to account for the following values:

    Hexagon _

Add a branch to cover this pattern!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What an incredibly helpful and informative compiler! It just saved us from our own folly. Whenever you use a union type, the Elm compiler checks to make sure you've covered all of the possibilities leading to fewer &lt;a href="https://en.wiktionary.org/wiki/footgun" rel="noopener noreferrer"&gt;footguns&lt;/a&gt;, and therefore - fewer bugs.&lt;/p&gt;




&lt;p&gt;In part 2, I'll be extracting even more magic from the union type. I'll be exposing some of the unique benefits of using union types when paired with concepts like recursion, encapsulation, and polymorphism.&lt;/p&gt;

&lt;p&gt;All of the code discussed here is available in &lt;a href="https://ellie-app.com/sF8YfTW2ca1/0" rel="noopener noreferrer"&gt;this ellie&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>elm</category>
      <category>functional</category>
    </item>
    <item>
      <title>How to animate an auto-height element</title>
      <dc:creator>Nate Gibbons</dc:creator>
      <pubDate>Tue, 31 Oct 2017 14:10:53 +0000</pubDate>
      <link>https://forem.com/marshallformula/how-to-animate-an-auto-height-element-1j3</link>
      <guid>https://forem.com/marshallformula/how-to-animate-an-auto-height-element-1j3</guid>
      <description>&lt;p&gt;Originally posted at &lt;a href="https://volumeintegration.com/animate-auto-height-element/"&gt;https://volumeintegration.com/animate-auto-height-element&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Animating an auto-height element seems like it should be fairly straightforward, however it seems &lt;a href="https://www.google.com/search?q=animation+auto+height+element" rel="noopener"&gt;I'm not the only one who has struggled with this particular issue&lt;/a&gt;.Â  The problem is usually some variant of the following:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;I have some element I would like to allow to vertically expand and collapse.&lt;/li&gt;
    &lt;li&gt;The element has dynamic content - so therefore the height of the expanded element is unknown/dynamic.&lt;/li&gt;
    &lt;li&gt;I need to set the height of the element toÂ &lt;code&gt;auto&lt;/code&gt; to allow the element to change height based on its contents.&lt;/li&gt;
    &lt;li&gt;CSS doesn't allow transitioning to &lt;code&gt;auto&lt;/code&gt; height so - it just jumps to the height when expanding/collapsing.Â  No animation â˜¹ï¸&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;This is what I want to do.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X837iD4W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://volumeintegration.com/wp-content/uploads/expandy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X837iD4W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://volumeintegration.com/wp-content/uploads/expandy.gif" alt="Showing auto-height expander"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Some Workarounds&lt;/h2&gt;

&lt;p&gt;You may find several potential solutions to this problem if you spend a bit of time poking around the internet.&lt;/p&gt;

&lt;p&gt;For example - there is the &lt;strong&gt;max-height&lt;/strong&gt; workaround.Â  In this solution you would basically transition the &lt;code&gt;max-height&lt;/code&gt; attribute instead of the &lt;code&gt;height&lt;/code&gt;.Â The trick is to set the final max-height to something way larger than you think the element will ever grow.Â  This will effectively animate to the height of the element's contents.Â  This might feel a little hanky to you - and for good reason. For starters - you have to guess what might be the largest the contents of the will ever get. But the content is dynamic - so that could easily get out of hand. Furthermore, the transition will animate to the full &lt;code&gt;max-height&lt;/code&gt; specified. The visible height will stop at the height of the content - but the transition thinks it needs to grow all the way to the &lt;code&gt;max-height&lt;/code&gt;. So for example - if you set a transition time of &lt;code&gt;300ms&lt;/code&gt; - it will take that long to animate to the full &lt;code&gt;max-height&lt;/code&gt; even though the visual height stops well before then.&lt;/p&gt;

&lt;p&gt;Other workarounds involve hiding the visual elements instead of changing the actual height or using javascript to manually animate/hide elements etc., but these are even more complicated than the &lt;code&gt;max-height&lt;/code&gt; solution and introduce a slew of new problems to deal with (the very least of which is wreaking havoc on the element's accessibility).&lt;/p&gt;

&lt;h2&gt;&lt;/h2&gt;

&lt;h2&gt;My &lt;span&gt;Hack&lt;/span&gt; Solution&lt;/h2&gt;

&lt;p&gt;If you're the kind of person that peeks at the end of the bookÂ &lt;em&gt;(shame on you)&lt;/em&gt; then you can check out &lt;a href="https://codepen.io/marshallformula/pen/qPvWBL" rel="noopener"&gt;my working solution on codepen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It still uses CSS to animate the &lt;code&gt;height&lt;/code&gt; property through the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/transition" rel="noopener"&gt;transition property&lt;/a&gt;.Â  However it also uses a bit of JavaScript to store some state for the element.&lt;/p&gt;

&lt;p&gt;This solution will not work for all situations - but it suited my needs well, but there are some restrictions:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;You must know the initial default height of the element.Â  This means if you don't know what content will be in your div on initial load - this might not work so well.Â  But if your element has an initial set of known contents this should work like a champ.&lt;/li&gt;
    &lt;li&gt;Content can only be added or removed from the element while it is in the expanded state.Â  If content is added/removed from the div while collapsedÂ  - then you're out of luck again.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Assuming your needs fulfill these requirements - this should work nicely.&lt;/p&gt;

&lt;p&gt;The solution essentially works like this:&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;Store the initial height of the element in a variable somewhere. We'll call it &lt;code&gt;expandHeight&lt;/code&gt; for now.&lt;/li&gt;
    &lt;li&gt;When the element expands - you can easily transition the height from 0 to the &lt;code&gt;expandHeight&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;After the transition is complete (use a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout" rel="noopener"&gt;setTimeout&lt;/a&gt; based on whatever you set the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/transition-duration" rel="noopener"&gt;transition-duration&lt;/a&gt;Â property to) then set the element's height property to &lt;code&gt;auto&lt;/code&gt;
&lt;/li&gt;
    &lt;li&gt;Add/remove content to the element as desired&lt;/li&gt;
    &lt;li&gt;When collapsing -
&lt;ol&gt;
    &lt;li&gt;First store the element's current height back into the &lt;code&gt;expandHeight&lt;/code&gt; variable.&lt;/li&gt;
    &lt;li&gt;Next set the element's height back to a fixed value (what you just stored in expandHeight). This is because the element cannot transition &lt;em&gt;from&lt;/em&gt; an &lt;code&gt;auto&lt;/code&gt; height either. It can only transition to/from a fixed height.&lt;/li&gt;
    &lt;li&gt;Now you can transition back to a height of 0.&lt;/li&gt;
&lt;/ol&gt;




&lt;/li&gt;

    &lt;li&gt;When you need to expand again - just start at step 2 above and repeat as necessary!&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;That's about all there is to it and it has worked well for me. One caveat is that you may need to stick step 5.3 in another &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout"&gt;setTimeout&lt;/a&gt; with a very small delay to allow the DOM time to register that the height attribute has changed from an auto height to a fixed height.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codepen.io/marshallformula/pen/qPvWBL"&gt;Here's my fully functioning example on codepen.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The astute observer might notice that it would not take too much imagination to create a &lt;a href="https://reactjs.org/docs/higher-order-components.html" rel="noopener"&gt;high order ReactJS component&lt;/a&gt; out of this solution that stores its own state internally so you can re-use it anywhere with ease.&lt;/p&gt;

&lt;p&gt;Let me know what you think.Â  More importantly - let me know if you've got something even better!Â  Cheers!&lt;/p&gt;

&lt;h6&gt;&lt;em&gt;Feature Photo by &lt;a href="https://unsplash.com/@christiankaindl"&gt;Christian Kaindl&lt;/a&gt;&lt;/em&gt;&lt;/h6&gt;

</description>
      <category>css</category>
      <category>javascript</category>
      <category>html</category>
    </item>
    <item>
      <title>Hi, I'm Nate Gibbons</title>
      <dc:creator>Nate Gibbons</dc:creator>
      <pubDate>Mon, 17 Apr 2017 15:01:22 +0000</pubDate>
      <link>https://forem.com/marshallformula/hi-im-nate-gibbons</link>
      <guid>https://forem.com/marshallformula/hi-im-nate-gibbons</guid>
      <description>&lt;p&gt;I have been coding for 10 years.&lt;/p&gt;

&lt;p&gt;You can find me on GitHub as &lt;a href="https://github.com/marshallformula" rel="noopener noreferrer"&gt;marshallformula&lt;/a&gt;&lt;br&gt;
You can find me on Twitter as &lt;a href="https://twitter.com/marshallformula" rel="noopener noreferrer"&gt;marshallformula&lt;/a&gt;&lt;br&gt;
You can find me on Mastodon as &lt;a href="https://toot.cafe/@marshallformula" rel="noopener noreferrer"&gt;marshallformula@toot.cafe&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I live in SLC.&lt;/p&gt;

&lt;p&gt;I work for Volume Integration&lt;/p&gt;

&lt;p&gt;I mostly program in these languages: Elm, Java, JavaScript.&lt;/p&gt;

&lt;p&gt;I am currently learning more about Functional Programming.&lt;/p&gt;

&lt;p&gt;Nice to meet you.&lt;/p&gt;

</description>
      <category>introduction</category>
    </item>
  </channel>
</rss>
