<?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: Katie Langerman</title>
    <description>The latest articles on DEV Community by Katie Langerman (@langermank).</description>
    <link>https://dev.to/langermank</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%2F486343%2F91c4a243-bc03-4f53-8067-30ae200d2a93.jpeg</url>
      <title>DEV Community: Katie Langerman</title>
      <link>https://dev.to/langermank</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/langermank"/>
    <language>en</language>
    <item>
      <title>Figma controller components &amp; prepping for variants</title>
      <dc:creator>Katie Langerman</dc:creator>
      <pubDate>Tue, 29 Dec 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/langermank/figma-controller-components-prepping-for-variants-2lc9</link>
      <guid>https://dev.to/langermank/figma-controller-components-prepping-for-variants-2lc9</guid>
      <description>&lt;p&gt;I've seen figma variants done with and without component nesting, and at this point made a button both ways. Having gone through the process a few times &lt;em&gt;sigh&lt;/em&gt; I feel pretty confident in using controller components to build out variants. My key takeaway: &lt;strong&gt;variants are like props and should be used to toggle states&lt;/strong&gt;. You don't want to be building core UI within the variant setup, you just want to hook it all up. Either way its a tedious process– but the end result is pretty rad.&lt;/p&gt;

&lt;p&gt;Along with using controller components, it's important to do some prep work before you start building out each variant. I'll go through how I plan for variants before touching my figma file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Controller component
&lt;/h2&gt;

&lt;p&gt;Build a base level component to act as a "controller" for each variant. This is where you could control &lt;strong&gt;border radius, margins/padding, size, autolayout, and ordering/layout.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's great if you have a rough idea for reach property before you start, but as you build out variants you can easily make new controllers. I started with my default button height and sizing, then later added specific controllers for icon buttons so I could utilize autolayout. Once I was happy with my default set, I made copies of each controller and added &lt;code&gt;small&lt;/code&gt; and &lt;code&gt;large&lt;/code&gt; sizes. Now if I want to make my large buttons GIANT, I only have to change it in 6 places (vs 34)&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/b9bd4ad164c5ecf9e0c724438ddaca6c/eea4a/figma-controller-component.jpg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F-eU63fJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://langermank.com/static/b9bd4ad164c5ecf9e0c724438ddaca6c/b4294/figma-controller-component.jpg" alt="controller component" title="controller component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Planning for variants
&lt;/h2&gt;

&lt;p&gt;Step away from your figma file for a minute. Maybe do a little research by looking at &lt;a href="https://designsystemsrepo.com/design-systems/"&gt;other design systems&lt;/a&gt;. &lt;strong&gt;Make a list of every variant you think you might need&lt;/strong&gt;. I'm usually a build only what you need when you need it person, but in this case its much easier to have a little plan before you start. The same goes for actually architecting a component with code– the clearer picture you have of the different props, the better.&lt;/p&gt;

&lt;p&gt;Here's my list for Button&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;state [default, hover, disabled]&lt;/li&gt;
&lt;li&gt;size [small, default, large]&lt;/li&gt;
&lt;li&gt;variant [primary, secondary]&lt;/li&gt;
&lt;li&gt;outlineBtn [true/false]&lt;/li&gt;
&lt;li&gt;loading [true/false]&lt;/li&gt;
&lt;li&gt;iconLeft [true/false]&lt;/li&gt;
&lt;li&gt;iconRight [true/false]&lt;/li&gt;
&lt;li&gt;iconOnly [true/false]&lt;/li&gt;
&lt;li&gt;fullWidth [true/false]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use whatever naming convention feels good. I'm using camelCase to make it easier to transfer this to JS.&lt;/p&gt;

&lt;p&gt;Take that list and define every property for the first Button variant. Figma is looking for a specific format. It should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;state=default, size=default, variant=primary, outlineBtn=false, loading=false, iconLeft=false, iconRight=false, iconOnly=false, fullWidth=false

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Alright, back to your figma file
&lt;/h2&gt;

&lt;p&gt;Make a new frame and copy your button_controller into it. Do not detach instance. It should look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/4dbcd5a396662c3805581171c7dfaf32/eea4a/first-component.jpg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iQbQDdD9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://langermank.com/static/4dbcd5a396662c3805581171c7dfaf32/b4294/first-component.jpg" alt="create a new component frame" title="create a new component frame"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make that new frame Button a component. This is what we will base our variants off of. Style this first component while still using the controller. The only changes I really made to Button are colors and some autolayout to allow for fullWidth. Click the plus sign under Variants to enable, but instead of manually adding props (it takes forever) just copy paste the list above into the name of the first button in the layers panel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eG6RJBI8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5slt1nrri3p5w00pfon1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eG6RJBI8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5slt1nrri3p5w00pfon1.gif" alt="adding prop names to component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can do the same thing here but it will take 5x longer (Add New Property)&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/3a6e2ee879a82351712a2de05ff971cd/eea4a/add-new-prop.jpg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9FXqpQWh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://langermank.com/static/3a6e2ee879a82351712a2de05ff971cd/b4294/add-new-prop.jpg" alt="add new props via sidebar" title="add new props via sidebar"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Now when you make a new variant, you can simply make whatever design adjustments you want and change any of the props you already created! You can continue changing props via text in the variant name or through the variants panel. Having a prop-plan ahead of time will allow you to more easily build each variant and hopefully prevent any major oversights that generally mean you have to start over.&lt;/p&gt;

&lt;p&gt;Feel free to check out my &lt;a href="https://www.figma.com/file/WOrTkNOlTlHPpqt4b0n9cc/Button-Components-with-Controllers-Full-Variants?node-id=0%3A1"&gt;figma file&lt;/a&gt; for Button as a reference or to use in your own system!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Converting Fluid Typography LESS mixin to CSS clamp()</title>
      <dc:creator>Katie Langerman</dc:creator>
      <pubDate>Sat, 16 May 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/langermank/converting-fluid-typography-less-mixin-to-css-clamp-g5g</link>
      <guid>https://dev.to/langermank/converting-fluid-typography-less-mixin-to-css-clamp-g5g</guid>
      <description>&lt;p&gt;I've been waiting for &lt;code&gt;clamp()&lt;/code&gt; browser support for awhile. Finally we're at a point where it feels safe to implement with a fallback for production sites. I spent a day converting an existing fluid type scale to utilize &lt;code&gt;clamp()&lt;/code&gt; and documented the process along the way! My goal with this conversion was to keep the compiled sizing as close to the original LESS mixin as possible. A few benefits I already see for using &lt;code&gt;clamp()&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The syntax is &lt;em&gt;immensely&lt;/em&gt; easier to read and write&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;clamp()&lt;/code&gt; definition could live in a CSS custom property, allowing for themes to utilize one type scale file without losing control over individual heading sizes&lt;/li&gt;
&lt;li&gt;You no longer need to rely on a complicated LESS mixin&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Skip ahead to my codepen for the results&lt;/p&gt;

&lt;h2&gt;
  
  
  out with the old
&lt;/h2&gt;

&lt;p&gt;Below is the original LESS mixin I've been using for years. I've seen this several times on codepen and in various articles, so I'm not sure who to credit. I use rems and assume a base font size of 16px.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    .fluid-typography-rem(@min-screen: 320px, @max-screen: 1600px, @base-font: 16px, @min-font, @max-font, @fallbackFontSize) {
        // min font size
        font-size: @min-font;

        @media screen and (min-width: unit((@min-screen / @base-font), ~'rem')) {
            font-size: ~'@{fallbackFontSize}';
            font-size: calc(
                @min-font ~' + ' unit(@max-font - @min-font) ~' * ((100vw - '
                    unit((@min-screen / @base-font), ~'rem') ~') /' unit(
                        (@max-screen / @base-font) - (@min-screen / @base-font)
                    ) ~')'
            );
        }

        @media screen and (min-width: unit((@max-screen / @base-font), ~'rem')) {
            // max font size
            font-size: @max-font;
        }
    }

    /* the output looks like this for h1 */
    /* minimum size of 25.6px */
    h1 {
        font-size: 1.6rem;
    }

    /* starting at 320px screen width */
    @media screen and (min-width: 20rem) {
        h1 {
            font-size: 1.75rem; // fallback of 28px
            font-size: calc(1.6rem + 0.4 * ((100vw - 20rem) / 70));
        }
    }

    /* anything beyond 1440px */
    @media screen and (min-width: 90rem) {
        h1 {
            font-size: 2rem; // max of 32px
        }
    }

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



&lt;p&gt;I've always felt that this logic is really hard to follow. Essentially we are setting a min font size, a max font size, and asking the browser to scale up and down fluidly between the two &lt;strong&gt;based on the viewport width in the calc function&lt;/strong&gt;... which is also calculated based on the screen size range and base font size we have specified. I think &lt;code&gt;clamp()&lt;/code&gt; is doing the same thing, though I haven't been able to get an exact match between the mixin and clamp. I'm okay with that.&lt;/p&gt;

&lt;h2&gt;
  
  
  converting to clamp()
&lt;/h2&gt;

&lt;p&gt;Since I already have a fluid type scale, I can reuse those values within my clamp definitions. I still need to support ie11 and other browsers that have yet to support &lt;code&gt;clamp()&lt;/code&gt; so I'll be using &lt;code&gt;@supports&lt;/code&gt; with a fallback. I found &lt;a href="https://medium.com/@Yuschick/fluid-typography-with-css-clamp-is-my-new-favorite-thing-573d0b8d7bfc"&gt;this article&lt;/a&gt; really helpful in understanding &lt;code&gt;clamp()&lt;/code&gt; and using it with &lt;code&gt;@supports&lt;/code&gt;, but I'm going to elaborate on each part of clamp for my own sake (it took me a bit to fully grasp).&lt;/p&gt;

&lt;h3&gt;
  
  
  clamp() breakdown
&lt;/h3&gt;

&lt;p&gt;Read the spec &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/clamp"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;clamp(min, val, max)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;min&lt;/code&gt; the smallest unit you ever want&lt;/p&gt;

&lt;p&gt;&lt;code&gt;max&lt;/code&gt; the biggest unit you ever want&lt;/p&gt;

&lt;p&gt;&lt;code&gt;val&lt;/code&gt; the ideal unit&lt;/p&gt;

&lt;p&gt;The middle value is referred to as a &lt;code&gt;preferred value&lt;/code&gt;. I found this part a little confusing to figure out. If the computed &lt;code&gt;val&lt;/code&gt; is less than &lt;code&gt;min&lt;/code&gt; : &lt;code&gt;min&lt;/code&gt; value will be used. If the computed &lt;code&gt;val&lt;/code&gt; is greater than &lt;code&gt;max&lt;/code&gt; : &lt;code&gt;max&lt;/code&gt; value will be used.&lt;/p&gt;

&lt;p&gt;By setting the &lt;code&gt;preferred&lt;/code&gt; value in &lt;code&gt;vw&lt;/code&gt; units, we can leverage the "fluid" aspect of relative units. And by using &lt;code&gt;clamp()&lt;/code&gt; we can enforce a min and max font-size to regain control over the fluidity whenever necessary (eg: not allowing the font-size to go below or above a certain point.) Having a good understanding of how &lt;code&gt;vw&lt;/code&gt; works helps here! As a little overview:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;vw&lt;/code&gt; = 1% of the viewport's width&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;3vw&lt;/code&gt; = 30% of the viewport's width&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;vw&lt;/code&gt; and &lt;code&gt;vh&lt;/code&gt; are relative units, not absolute, so they scale with the width or height of the viewport (perfect for fluid typography)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  example
&lt;/h4&gt;

&lt;p&gt;Say this is our clamp definition: &lt;code&gt;font-size: clamp(1.6rem, 4vw, 2rem);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If the viewport window is 768px, &lt;code&gt;font-size: 4vw&lt;/code&gt; computes to 30.7167px&lt;/p&gt;

&lt;p&gt;768 * 0.4 = 307.2 or 30.72px&lt;/p&gt;

&lt;p&gt;If that calculated value of 30.72px was &lt;strong&gt;higher&lt;/strong&gt; than the &lt;code&gt;max&lt;/code&gt; value we defined in the clamp, the font-size would instead take the &lt;code&gt;max&lt;/code&gt; value.&lt;/p&gt;

&lt;p&gt;In plain english, clamp says: "Here's my min font-size, here's my max font-size, and here's my &lt;strong&gt;PREFERRED font-size&lt;/strong&gt;. Please use my preferred font-size whenever possible, but don't let it exceed my max font-size or go below my min font-size."&lt;/p&gt;

&lt;h2&gt;
  
  
  the comparison
&lt;/h2&gt;

&lt;p&gt;From what I can tell, there's a slight difference between the fluid typography mixin logic and &lt;code&gt;clamp()&lt;/code&gt;. You can see the difference in the codepen below where I'm printing out each computed font size side by side. Now that I understand how to utilize the &lt;code&gt;val&lt;/code&gt; part of &lt;code&gt;clamp()&lt;/code&gt; it's quite easy to control the type scale, but trying to match it with logic in a mixin I barely understand was a struggle. Since I have further improvements I'd like to do to this particular type scale, I'm happy with the results being close enough for now!&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/langermank/embed/ZEbqyWJ?height=600&amp;amp;default-tab=css,result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>css</category>
      <category>progressiveenhancement</category>
      <category>typography</category>
      <category>design</category>
    </item>
  </channel>
</rss>
