title: How does flex-shrink factor in padding and border-box?
body: <p>Let's say we have a flex container with a width of 400px.</p>
  
  <p>Inside this container are three flex items:</p>
  
  <pre><code>:nth-child(1) { flex: 0 2 300px; }   /* flex-grow, flex-shrink, flex-basis */
  :nth-child(2) { flex: 0 1 200px; }
  :nth-child(3) { flex: 0 2 100px; }
  </code></pre>
  
  <p>So the total width of flex items is 600px and the free space in the container is -200px.</p>
  
  <p>With help from <a href="https://stackoverflow.com/q/34735515/3597276">this question</a>, <a href="http://chriswrightdesign.com/experiments/flexbox-adventures/" rel="noreferrer">this article</a>, and the <a href="http://www.w3.org/TR/css-flexbox-1/#resolve-flexible-lengths" rel="noreferrer">flexbox spec</a>, I've learned the basic formula for distributing negative free space among flex items:</p>
  
  <p><strong>Step 1</strong></p>
  
  <p>Multiply each shrink value by its basis and add them all together:</p>
  
  <pre><code>:nth-child(1)  2 * 300 = 600
  :nth-child(2)  1 * 200 = 200
  :nth-child(3)  2 * 100 = 200
  </code></pre>
  
  <p>TOTAL = 1000</p>
  
  <p><strong>Step 2</strong></p>
  
  <p>Divide each item above by the total to determine the <em>shrink factor</em>:</p>
  
  <pre><code>:nth-child(1)  600 / 1000 = .6
  :nth-child(2)  200 / 1000 = .2
  :nth-child(3)  200 / 1000 = .2
  </code></pre>
  
  <p><strong>Step 3</strong></p>
  
  <p>Multiply the shrink factor by the negative free space to determine the space removed from each item:</p>
  
  <pre><code>:nth-child(1)  .6 * -200px = -120px
  :nth-child(2)  .2 * -200px =  -40px
  :nth-child(3)  .2 * -200px =  -40px
  </code></pre>
  
  <p>So, the computed size of each flex item should be:</p>
  
  <pre><code>:nth-child(1)  300px - 120px = 180px
  :nth-child(2)  200px -  40px = 160px
  :nth-child(3)  100px -  40px =  60px
  </code></pre>
  
  <p>Tested in Chrome, Firefox and IE11, the numbers check out. The calculation works perfectly.</p>
  
  <p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
  <div class="snippet-code snippet-currently-hidden">
  <pre class="snippet-code-css lang-css prettyprint-override"><code>.flex {
    display: flex;
    width: 400px;
    height: 50px;
    margin: 0;
    padding: 0;
    list-style: none;
    text-align: center;
  }
  
  .flex li:nth-child(1) {
    flex: 0 2 300px;
    background: orange;
  }
  
  .flex li:nth-child(2) {
    flex: 0 1 200px;
    background: chartreuse;
  }
  
  .flex li:nth-child(3) {
    flex: 0 2 100px;
    background: aqua;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;ul class="flex1 flex"&gt;
    &lt;li&gt;180px&lt;/li&gt;
    &lt;li&gt;160px&lt;/li&gt;
    &lt;li&gt;60px&lt;/li&gt;
  &lt;/ul&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p><a href="https://jsfiddle.net/om8pzewa/3/" rel="noreferrer">jsFiddle demo</a></p>
  
  <hr>
  
  <h3>The Problem</h3>
  
  <p>When padding is introduced, however, the shrink results are different. When padding is applied along with <code>box-sizing: border-box</code>, this results in yet another set of numbers.</p>
  
  <p><a href="https://i.stack.imgur.com/1vlcE.png" rel="noreferrer"><img src="https://i.stack.imgur.com/1vlcE.png" alt="enter image description here"></a></p>
  
  <p>What's the <code>flex-shrink</code> calculation when <code>padding</code> and <code>box-sizing</code> are involved?</p>
  
  <p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
  <div class="snippet-code snippet-currently-hidden">
  <pre class="snippet-code-css lang-css prettyprint-override"><code>.flex {
    display: flex;
    width: 400px;
    height: 50px;
    margin: 0;
    padding: 0;
    list-style: none;
    text-align: center;
    border-bottom: 1px solid #ccc;
  }
  
  .flex li:nth-child(1) {
    flex: 0 2 300px;
    background: orange;
  }
  
  .flex li:nth-child(2) {
    flex: 0 1 200px;
    background: chartreuse;
  }
  
  .flex li:nth-child(3) {
    flex: 0 2 100px;
    background: aqua;
  }
  
  .flex2 li {
    padding: 0 10px;
  }
  
  .flex3 li {
    padding: 0 10px;
    box-sizing: border-box;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;ul class="flex1 flex"&gt;
    &lt;li&gt;180px&lt;/li&gt;
    &lt;li&gt;160px&lt;/li&gt;
    &lt;li&gt;60px&lt;/li&gt;
  &lt;/ul&gt;
  
  &lt;ul class="flex2 flex"&gt;
    &lt;li&gt;144px&lt;/li&gt;
    &lt;li&gt;148px&lt;/li&gt;
    &lt;li&gt;48px&lt;/li&gt;
  &lt;/ul&gt;
  
  &lt;ul class="flex3 flex"&gt;
    &lt;li&gt;175.5px&lt;/li&gt;
    &lt;li&gt;160px&lt;/li&gt;
    &lt;li&gt;64.4px&lt;/li&gt;
  &lt;/ul&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p><a href="https://jsfiddle.net/om8pzewa/5/" rel="noreferrer">jsFiddle demo</a></p>