<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Afosto - Medium]]></title>
        <description><![CDATA[The all-in-one e-commerce solution - Medium]]></description>
        <link>https://medium.com/afosto?source=rss----ab916a47e38a---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>Afosto - Medium</title>
            <link>https://medium.com/afosto?source=rss----ab916a47e38a---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 15 May 2026 15:59:11 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/afosto" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[5 Key Lessons I’ve Learned from Building E-Commerce Businesses from Scratch]]></title>
            <link>https://medium.com/afosto/5-key-lessons-ive-learned-from-building-e-commerce-businesses-from-scratch-ae2bb0f3e972?source=rss----ab916a47e38a---4</link>
            <guid isPermaLink="false">https://medium.com/p/ae2bb0f3e972</guid>
            <category><![CDATA[market-research]]></category>
            <category><![CDATA[decision-paralysis]]></category>
            <category><![CDATA[ecommerce-startup]]></category>
            <category><![CDATA[scaleup]]></category>
            <category><![CDATA[cost-effective]]></category>
            <dc:creator><![CDATA[Sander Kah]]></dc:creator>
            <pubDate>Thu, 03 Aug 2023 08:58:43 GMT</pubDate>
            <atom:updated>2023-08-03T08:27:08.499Z</atom:updated>
            <content:encoded><![CDATA[<p>Hello there! I’m Sander, a dutiful pilot with KLM, but that’s just my day job. When I’m not soaring in the clouds, I dive into the exciting world of startups and e-commerce. Over the last decade, I’ve worn multiple hats — a serial entrepreneur, co-owner of a software company (<a href="https://afosto.com">Afosto</a>), and an ardent business-scaling enthusiast.</p><p>With a proven track record in building businesses from scratch, I’ve played a crucial role in helping various startups transform into 7 figure companies. My experience spans across diverse e-commerce ventures I’ve personally launched, which has ingrained me with valuable lessons. I’m also the head of new business at Afosto, where I assist our clients in reaching their business objectives and scaling their operations through smart software solutions.</p><p>But why am I telling you all this? Well, because I want to share the wisdom I’ve gathered from my entrepreneurial journey. It’s been a thrilling ride, filled with successes, failures, and learnings that have shaped my approach toward e-commerce.</p><p>So, whether you’re a budding entrepreneur, an existing e-commerce business owner looking to scale, or someone with a keen interest in the startup world, you’re in the right place. Read on as I unveil the 5 key lessons I’ve learned from building e-commerce businesses from scratch.</p><h3>Lesson #1: Doing Your Homework: Market Research Before Launch</h3><p>Picture this: launching a new e-commerce business without doing your homework is like betting your life savings on a horse race without checking the odds. Not the best strategy, right? And, I can tell you this from first-hand experience!</p><p>Now, my approach is different. Before starting a new venture or expanding my product range, I take on the role of a detective, scouting the online landscape. Are folks looking for my product? How are my competitors pricing? Can we jump in and still turn a profit? Think of market research as your map to treasure island — ignore it at your own risk!</p><h3>Lesson #2: Measured Risks: Testing Before Investing in E-Commerce</h3><p>Jumping head-first into a business without testing the waters isn’t just risky, it’s like flying a plane without a pre-flight check — and I wouldn’t advise either. Once your market research is complete, it’s time to take a small step forward, to test your assumptions.</p><p>Imagine setting up a lean, straightforward e-commerce website as your proving ground. The design is simple, the checkout smooth, and your product page is where the magic happens. It’s where customers decide if they’re buying or browsing. To convince them, answer their burning questions clearly:</p><ul><li>What’s the price?</li><li>Are there any shipping fees?</li><li>When will I get it?</li><li>Is my purchase guaranteed?</li><li>Have others bought and loved this?</li></ul><p>The goal is to validate your product and the market with minimal risk, turning assumptions into data-driven decisions. It’s like taking a test-flight before the big journey!</p><h3>Lesson #3: The Pitfall of Overanalysis: Avoiding Decision Paralysis</h3><p>There’s an unspoken rule in the business skies and the startup scene alike: time equals money. If you find yourself stuck in the research phase or constantly comparing variables without taking action, you’re burning fuel while still on the runway. Remember: real learning happens in-flight, in the heart of the actual market dynamics.</p><p>Overanalysis is a sly beast that often leads to decision paralysis — an overthinking state that hampers progress and freezes action. It’s like waiting for the perfect wind speed before taking off — you could end up grounded indefinitely. In my early days, I found myself caught in this waiting game, hoping for the ‘perfect moment’ or that ‘last bit of data’. But in the high-speed world of e-commerce, such hesitation can mean missed opportunities or even worse, giving competitors a free pass to take the lead.</p><p>These days, I’ve adopted a more action-oriented approach. Sure, I start with the basics and make informed assumptions, but more importantly, I get the wheels off the ground and adapt mid-flight based on real-world feedback. Remember, you don’t have to have everything figured out before you start. Get up in the air, and trust yourself to navigate the journey as it unfolds.</p><h3>Lesson #4: Design on a Dime: Cost-Effective Aesthetics for E-Commerce</h3><p>Launching a webshop often comes with a daydream — of droves of customers pouring in, marveling at the pixel-perfect design of your site, and clicking that ‘buy now’ button without a second thought. However, as someone who’s played this game before, I have to bring you back to reality: that’s usually not how things play out.</p><p>Web design, while undoubtedly important, is not the be-all and end-all. An effective e-commerce site needs to be user-friendly and intuitive, not just pretty. Sure, a well-designed website can nudge your revenue up a notch, but it’s not a magic wand that transforms browsers into buyers. What truly matters to customers are simple things — clear pricing, delivery timelines, and reassurances that others trust you too.</p><p>A crucial element of your site is the product page — the battlefield where most purchase decisions are won or lost. It should be straightforward and informative, showcasing your price, shipping time and costs, warranty information, and customer reviews or other social proofs. This simplicity not only aids your customers in their buying process but also optimizes your resources. After all, design is important, but it’s not worth breaking the bank before you’ve proven your sales capability. Remember, being cost-effective is not about being cheap; it’s about being smart with your investments.</p><h3>Lesson #5: The Numbers Game: Why SEO and Analytics Matter Most</h3><p>The digital world, my friends, is a numbers game. Data is the king that rules this kingdom, and Google is its prime minister. Jokes aside, one cannot overstate the importance of setting up Google Analytics, Google Search Console, and Google Ads from the get-go. Think of it as setting up your own personal oracle — a reliable source of information, guidance, and insights.</p><p>When you first create a Google Ads account, go ahead and pause the initial campaign right away. This nifty trick gives you access to a treasure trove of tools to help select the right keywords for your product and category pages. But remember, don’t dive headfirst into paid advertising before ensuring your technical SEO is on point. You want the heart of your website — its content and technical framework — to be sound and solid. This way, you’ll start ranking for the keywords that are key to your business, making every click on your paid ads count, and importantly, cost less!</p><p>Use Google Analytics to understand your audience — where they’re coming from, what they’re doing on your site, and what makes them tick. Google Search Console, on the other hand, shows you how you’re performing in search results and which keywords are drawing in the free organic traffic. Consider these tools your secret weapons in the e-commerce battle, helping you navigate the landscape, spot opportunities, and seize them before anyone else does!</p><h3>To Infinity and Beyond: A High-Five to You!</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Rka6CQBdCShMmzJywWpx9Q.png" /></figure><p>Well, folks, we’ve had a whirlwind journey through the exciting, sometimes challenging, but always rewarding world of e-commerce. A heartfelt thank you for staying onboard throughout this voyage!</p><p>Remember, as you embark on your e-commerce endeavors, the lessons learned are the stepping stones to success. So, do your homework, dip your toes in the water, sidestep overthinking, be frugal with design, and harness the superpowers of SEO and analytics.</p><p>And as we wrap up, don’t let the conversation end here! I would absolutely love to connect with you further and continue our chat on LinkedIn. Feel like catching up over a virtual coffee and discuss everything from market research to the latest SEO trends? Well, hop on over and <a href="https://www.linkedin.com/in/sander-kah/">connect with me</a>!</p><p>Remember, the e-commerce journey is like a thrilling roller coaster ride — there will be ups, downs, twists, and turns. But hey, that’s where the fun is, right? So keep exploring, keep innovating, and let’s ride this roller coaster together. Until next time!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ae2bb0f3e972" width="1" height="1" alt=""><hr><p><a href="https://medium.com/afosto/5-key-lessons-ive-learned-from-building-e-commerce-businesses-from-scratch-ae2bb0f3e972">5 Key Lessons I’ve Learned from Building E-Commerce Businesses from Scratch</a> was originally published in <a href="https://medium.com/afosto">Afosto</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Lightning fast search widget with Afosto Instant Search]]></title>
            <link>https://medium.com/afosto/lightning-fast-search-widget-with-afosto-instant-search-d9391b01ec02?source=rss----ab916a47e38a---4</link>
            <guid isPermaLink="false">https://medium.com/p/d9391b01ec02</guid>
            <category><![CDATA[widget]]></category>
            <category><![CDATA[search]]></category>
            <category><![CDATA[instant-search]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Gijs Boddeus]]></dc:creator>
            <pubDate>Tue, 05 Apr 2022 13:59:45 GMT</pubDate>
            <atom:updated>2022-04-05T13:59:02.570Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mdslmpSgUHqZRNmu7-5CSw.png" /><figcaption>The Afosto Instant Search widget demo on our site with a movies index</figcaption></figure><p>It’s vital to have fast search functionalities on your website. If your search is slow, this negatively impacts your UX, but Google also penalizes your website for this poor performance. But most solutions out there are overpriced or hard to implement. You might choose to build it on your own, but that will take a long time to get it right, and you still need a good UI for it. That is why we made the Afosto Instant Search Widget, so you don’t have to.</p><h4>How does it work?</h4><p>The widget can connect to an Afosto Instant Search search engine, which includes settings for the indexes and the filters to use. Everything is configurable in the Afosto platform. That way, the developer only needs to implement the code, and you can change how it is displayed.</p><p>You can choose to use a ‘search as you type’ configuration or let the use search by pressing ‘ENTER’. With ‘search as you type’ the user gets near instant feedback of results for the entered query. Try it out in the CodePen in the next section or on our <a href="https://afosto.com/apps/instant-search/widget/">website</a>.</p><h4>How do I implement this on my site?</h4><p>First, you will need to create a search engine with one or more indexes. You can do that by signing up to our platform on <a href="https://afosto.com/register/">afosto.com</a> and follow the guides in our <a href="https://afosto.com/docs/apps/instant-search/">documentation</a>.</p><p>When you have a configured search engine, you can start implementing the code on your site. Depending on your project, you have a few options on how to include the scripts in your code. You can install it via Yarn or NPM, or via script tags from a CDN. For this article, we will keep it simple and use the CDN setup. Include the scripts below into your site code.</p><pre>&lt;!-- Styles --&gt;<br>&lt;link href=&quot;https://cdn.jsdelivr.net/npm/@afosto/instant-search-widget@latest/dist/afosto-instant-search-widget.min.css&quot; /&gt;<br><br>&lt;!-- Scripts --&gt;<br>&lt;script defer src=&quot;https://cdn.jsdelivr.net/npm/@afosto/instant-search-widget@latest/dist/afosto-instant-search-widget.min.js&quot;&gt;&lt;/script&gt;</pre><p>This will include the styles and necessary scripts to initialize and render the widget. To actually initialize it, we can add a script tag with the initialization method AfostoInstantSearchWidget.init(). This method takes your search engine key and fetches the settings for the search engine indexes.</p><pre>&lt;script&gt;<br>  document.addEventListener(&#39;DOMContentLoaded&#39;, function() {<br>   AfostoInstantSearchWidget.init(&#39;movies-demo&#39;);<br>  });<br>&lt;/script&gt;</pre><p>Now the widget is ready to go and is waiting for you to open it. All that is left to do is to add the data attribute data-af-instant-search to a button, input or whatever you choose to use as a trigger.</p><pre>&lt;button data-af-instant-search&gt;Search&lt;/button&gt;</pre><p>That’s all there is to it! You can use the CodePen below as an example and to see the speed of our Instant Search.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fembed%2Fpreview%2FLYeGYqv%3Fdefault-tabs%3Dhtml%252Cresult%26height%3D600%26host%3Dhttps%253A%252F%252Fcodepen.io%26slug-hash%3DLYeGYqv&amp;display_name=CodePen&amp;url=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fpen%2FLYeGYqv&amp;image=https%3A%2F%2Fshots.codepen.io%2Fgijsbotje%2Fpen%2FLYeGYqv-512.jpg%3Fversion%3D1648724343&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/ca186840365e113aada1cc757ab0bbfe/href">https://medium.com/media/ca186840365e113aada1cc757ab0bbfe/href</a></iframe><h4>That&#39;s cool, but I want to customize the design.</h4><p>You are free to customize the styling and layout of the widget by using CSS. For the colors, we use CSS custom properties. So for example changing the primary color, which is by default blue, is done by setting --af-is-primary-500 to whatever color you like. In the example below, we flipped the gray values, so it looks like dark mode, and made the primary color scale red. We also changed the layout a little. Because we’ve used CSS grid for the layout, you are able to reorder the components. The example below has a full height filters sidebar, and the pagination and items per page component are now above the results.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fembed%2Fpreview%2FoNppGqj%3Fdefault-tabs%3Dcss%252Cresult%26height%3D600%26host%3Dhttps%253A%252F%252Fcodepen.io%26slug-hash%3DoNppGqj&amp;display_name=CodePen&amp;url=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fpen%2FoNppGqj%3Feditors%3D0100&amp;image=https%3A%2F%2Fshots.codepen.io%2Fgijsbotje%2Fpen%2FoNppGqj-512.jpg%3Fversion%3D1649082864&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/84d463eb17515f456291254690705b03/href">https://medium.com/media/84d463eb17515f456291254690705b03/href</a></iframe><p>This is just an example of what you can customize. By using the classes or other selectors, you can customize everything you want and create your own theme.</p><h4>I want fast search, but with my own UI</h4><p>Like the speed of our search, but want your own implementation? We got you covered! Internally, our widget uses our <a href="https://github.com/afosto/instant-search-client">Instant Search Client</a> to handle all the requests and functionality. With this client you can build your own solution or connect it to for example <a href="https://github.com/algolia/instantsearch.js">instantsearch.js</a> or <a href="https://github.com/algolia/react-instantsearch">react-instantsearch-dom</a>. With these packages, you can create your own UI that is connected to Afosto Instant Search. Take a look at the <a href="https://afosto.com/apps/instant-search/demo/">demo</a> on our website, or use the CodePen below as an example.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fembed%2Fpreview%2FRwxxXPe%3Fdefault-tabs%3Dcss%252Cresult%26height%3D600%26host%3Dhttps%253A%252F%252Fcodepen.io%26slug-hash%3DRwxxXPe&amp;display_name=CodePen&amp;url=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fpen%2FRwxxXPe%3Feditors%3D1010&amp;image=https%3A%2F%2Fshots.codepen.io%2Fgijsbotje%2Fpen%2FRwxxXPe-512.jpg%3Fversion%3D1649144835&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/62e20e6103c71f6631a1134182744a4d/href">https://medium.com/media/62e20e6103c71f6631a1134182744a4d/href</a></iframe><h4>Let us know what you think</h4><p>We are curious about what you think of our search widget. Feel free to leave a comment or check out our <a href="https://github.com/afosto/instant-search-widget">GitHub</a> for more information or to report an issue.</p><p>Check out our <a href="https://afosto.com/">website</a> to <a href="https://afosto.com/register/">register your Afosto account</a> and take a look at our other apps. You might like <a href="https://afosto.com/apps/quicq/">Quicq</a>, our on the fly image optimization platform.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d9391b01ec02" width="1" height="1" alt=""><hr><p><a href="https://medium.com/afosto/lightning-fast-search-widget-with-afosto-instant-search-d9391b01ec02">Lightning fast search widget with Afosto Instant Search</a> was originally published in <a href="https://medium.com/afosto">Afosto</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Bootstrap v4 explained: Flexing with utilities]]></title>
            <link>https://medium.com/afosto/bootstrap-v4-explained-flexing-with-utilities-4d1d43e196f9?source=rss----ab916a47e38a---4</link>
            <guid isPermaLink="false">https://medium.com/p/4d1d43e196f9</guid>
            <category><![CDATA[frontend]]></category>
            <category><![CDATA[utilities]]></category>
            <category><![CDATA[bootstrap-4]]></category>
            <category><![CDATA[css]]></category>
            <category><![CDATA[flexbox]]></category>
            <dc:creator><![CDATA[Gijs Boddeus]]></dc:creator>
            <pubDate>Wed, 04 Sep 2019 19:11:39 GMT</pubDate>
            <atom:updated>2019-09-04T18:58:46.398Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9z1x3DGfoEaymQJNNo6Nqg.jpeg" /></figure><p>When you browse through the #help channel on the Bootstrap Slack workspace, you will see a few questions being asked over and over again. In this series I will try and answer these questions thoroughly in the hopes you will understand what techniques are used and how to use it properly.</p><p>I’m a big fan of the new flex utilities included in Bootstrap v4. They give you great flexibility , no pun intended, and are perfect for any alignment use case. We’ll have a look at every class that Bootstrap provides and also walk through the styles the classes add. <br>You can read through the documentation on getbootstrap.com.</p><blockquote>If you just want to know how to use it, scroll down till the next three dots.</blockquote><h3>Techniques</h3><p>As you might have guessed: it’s all flexbox for this one. Everything you’ve used floats for, in my opinion, you’re better of with flexbox. If you don’t now what flexbox is you can take a look at the following links. I highly recommend playing the Flexbox Froggy game, it’s the most fun way to learn flexbox.</p><ul><li><a href="https://flexboxfroggy.com/">Flexbox Froggy</a></li><li><a href="https://css-tricks.com/snippets/css/a-guide-to-flexbox/">CSS Tricks: A Complete Guide to Flexbox</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox">Mozilla Developers Network: Basic Concepts of Flexbox</a></li><li><a href="https://medium.com/@js_tut/flexbox-the-animated-tutorial-8075cbe4c1b2">Flexbox the animated tutorial by JavaScript Teacher</a></li></ul><p>If you really want to know everything you can also read the CSS working group spec for flexbox. Kudos if you actually read it start to finish, I sure as hell haven’t.<br><a href="https://www.w3.org/TR/css-flexbox-1/">W3C: CSS Flexible Box Layout Module Level 1</a></p><p>The tiny scss file only contains 51 lines, but packs a lot of power. <a href="https://github.com/twbs/bootstrap/blob/v4-dev/scss/utilities/_flex.scss">Take a look at it on Github</a>. <br>But before we dive into the file, there are a few things you need to be aware of.</p><ul><li>These classes only have effect on an element if it has or is a child of an element that has the display: flex; property. You can also use the d-flex class to add it without writing custom css. This is called the <strong>flex container</strong>.</li><li>display: flex; tells the children of <strong>flex container</strong> how to behave. Only a few properties can control how a single child will behave. A child of a <strong>flex container</strong> is called a <strong>flex item</strong>.</li></ul><p>If it’s not clear yet you’ll need to read every link I mentioned above, even the w3c spec, just to be thorough 😏.</p><p><strong>OK, lets get flexin’!</strong></p><h4>Breakpoints</h4><p>This will use the same setup as the <a href="https://medium.com/afosto/bootstrap-v4-explained-display-utilities-the-new-hiding-and-showing-306ef6aef49e">display utilities</a>, so look over there if you want a complete explanation of every line. Short version: this will loop through every breakpoint and creates a @media (min-width: ##px){...} for each breakpoint. It also creates the $infix variable that we can use in our classes. The infix will correspond to the breakpoint, so sm, md, lg or xl prepended with a — .</p><pre>@each $breakpoint in map-keys($grid-breakpoints) {<br>  @include media-breakpoint-up($breakpoint) {<br>    $infix: breakpoint-infix($breakpoint, $grid-breakpoints);</pre><pre>    ...<br>  }<br>}</pre><h4>Flex-direction</h4><p>To control the direction, also called the main axis, that the flex container will flow it’s flex items we use the flex-direction property. This property only accepts row, column and their reversed options row-reversed and column-reversed. The default value for this property on a flex container is row, so you don’t need to explicitly add the class to get it to work as a row. The css that will control these is as follows.</p><pre>.flex#{$infix}-row            { flex-direction: row !important; }<br>.flex#{$infix}-column         { flex-direction: column !important; }<br>.flex#{$infix}-row-reverse    { flex-direction: row-reverse !important; }<br>.flex#{$infix}-column-reverse { flex-direction: column-reverse !important; }</pre><p>As you can see it’s really simple and solid. To be certain our utility class has effect, we need to append every declaration with !important otherwise we might be looking for why it isn’t working for an hour and add it anyways.</p><h4>Flex-wrap</h4><p>By default a flex container will keep all it’s flex items on one row (or column). We can tell the flex container to wrap it into a second row by adding the flex-wrap property. This can be done in 3 ways: the default nowrap, wrap or its reversed brother wrap-reverse. These result in the classes below.</p><pre>.flex#{$infix}-wrap         { flex-wrap: wrap !important; }<br>.flex#{$infix}-nowrap       { flex-wrap: nowrap !important; }<br>.flex#{$infix}-wrap-reverse { flex-wrap: wrap-reverse !important; }</pre><h4>Flex-fill</h4><p>This isn’t an actual property. It is a nifty way of making a flex item take up as much space as it can, in other words: fill up the remaining space. If you have two flex items next to each other with this class, they will be equal in width as they both take up as much space as they can. To do this we use the shorthand property flex. This is a shorthand to declare flex-grow, flex-shrink and flex-basis, in that order.<br><strong>This is one of the rare properties that can only be used on a flex item.</strong></p><pre>.flex#{$infix}-fill         { flex: 1 1 auto !important; }</pre><p>By setting flex-grow and flex-shrink to 1 we give the flex item the freedom to shrink and grow as much as it can. Setting the flex-basis to auto will tell the flex item that it’s width doesn’t matter. I’m not sure why it’s auto, to my knowledge this value can also be 0, but it still does the same.</p><h4>Flex-grow and flex-shrink</h4><p>We can also control flex-grow and flex-shrink independently by using these properties themselves instead of the shorthand. This gives you the flexibility to let flex items grow and shrink or to constrain them to flex-basis or width properties. Bootstrap only provides a class for the 1 and 0 value of this property. I only encountered a few cases where I wanted to set larger values for these, but these two option are enough in almost all use cases. <br><strong>This is one of the rare properties that can only be used on a flex item.</strong></p><pre>.flex#{$infix}-grow-0       { flex-grow: 0 !important; }<br>.flex#{$infix}-grow-1       { flex-grow: 1 !important; }<br>.flex#{$infix}-shrink-0     { flex-shrink: 0 !important; }<br>.flex#{$infix}-shrink-1     { flex-shrink: 1 !important; }</pre><p>You can think of these classes as booleans for telling the flex item to grow/shrink (1) or not (0).</p><h4>Justify-content</h4><p>To align flex items along the main axis we can use justify-content. It accepts 5 values that give you a lot of flexibility. flex-start and flex-end will align the flex items at the start or end of the main axis. So if the flex-direction is set to row, flex-end will align all flex items to the right. Using center will, as you might guess, center it on the axis. space-between does a bit more special things. It spaces the flex items along the main axis of the flex container with even spaces between each item. space-around will create even spaces around each item. The difference is that the flex items with space-between will be flush with the sides of the flex container. space-around will create space between the edge of a flex item and the edge of the flex-container. The examples in the next paragraph will explain this better.</p><pre>.justify-content#{$infix}-start   { justify-content: flex-start !important; }<br>.justify-content#{$infix}-end     { justify-content: flex-end !important; }<br>.justify-content#{$infix}-center  { justify-content: center !important; }<br>.justify-content#{$infix}-between { justify-content: space-between !important; }<br>.justify-content#{$infix}-around  { justify-content: space-around !important; }</pre><p>As you can see the classes classes are shortened to be easier to use.</p><h4>Align-items</h4><p>We can also align on the cross axis by adding align-items to the flexbox element. The values you can use for this property are: flex-start which is the default, flex-end, center, baseline and stretch. flex end and start work the same</p><p>So if flex-direction is set to row we can align our elements to the bottom of the row in the flexbox element, by setting the value to flex-end. Now the part bottom of the row in the flexbox element is important here. Because when your flexbox items are overflowing your flexbox element, it wraps the items into a new row. Now these element will get aligned relative to the other elements in the row. The next property align-content does it the other way around.</p><pre>.align-items#{$infix}-start   { align-items: flex-start !important;}<br>.align-items#{$infix}-end     { align-items: flex-end !important;}<br>.align-items#{$infix}-center  { align-items: center !important;}<br>.align-items#{$infix}-baseline { align-items: baseline !important;}<br>.align-items#{$infix}-stretch { align-items: stretch !important;}</pre><h4>Align-content</h4><p>Align content will align the rows of the flexbox items grouped together relative to the flexbox element. So image your items are all 20px high in 2 rows, and your flexbox element is 50px high, you’ll get 5px “padding” at the top and bottom of the flexbox element. Stay put till the example for a clearer explanation.</p><pre>.align-content#{$infix}-start   { align-content: flex-start !important; }<br>.align-content#{$infix}-end     { align-content: flex-end !important; }<br>.align-content#{$infix}-center  { align-content: center !important; }<br>.align-content#{$infix}-between { align-content: space-between !important; }<br>.align-content#{$infix}-around  { align-content: space-around !important; }<br>.align-content#{$infix}-stretch { align-content: stretch !important; }</pre><h4>Align-self</h4><p>With align-self you can override how a flex item aligns to the cross axis. So we can override the value set with align-items to the flex element with align-self. The possible values are the same as align-items with the addition of auto, which is the default value.</p><pre>.align-self#{$infix}-auto     { align-self: auto !important; }<br>.align-self#{$infix}-start    { align-self: flex-start !important; }<br>.align-self#{$infix}-end      { align-self: flex-end !important; }<br>.align-self#{$infix}-center   { align-self: center !important; }<br>.align-self#{$infix}-baseline { align-self: baseline !important; }<br>.align-self#{$infix}-stretch  { align-self: stretch !important; }</pre><p>For some reason the auto option, though it is present in the scss file, is not mentioned in Bootstrap’s documentation. But believe me, it’s a thing.</p><h4>Order</h4><p>The order classes isn’t actually a part of the flexbox utilities, but is created in the grid-framework.scss file. The classes are created inside the make-grid-columns mixin. But as they are included in the bootstrap docs as utility classes, this is how they work.</p><pre>.order#{$infix}-first { order: -1; }<br>.order#{$infix}-last { order: $columns + 1; }<br>    <br>@for $i from 0 through $columns { <br>       .order#{$infix}-#{$i} { order: $i; }     <br> }</pre><p>It’s again wrapped in a loop that creates a media query for each breakpoint and passes an infix on as a variable. Bootstrap provides a way to order a flex item as the last or first, but also provides an order class for each column plus a reset option. The for loop above will go from 0 to, by default, 12 and create the order class for each column on every breakpoint. The 0 though is a way to reset the elements ordering. When you use the .order-0 class, the element will be reset to the natural html order. With the other classes you can swap the fifth elements with the second element by using order-5 and order-2.</p><p>So now we’ve got that out of the way… I actually did read most of the W3C article… I now realize you should definitely read through to fully understand flexbox, it’s really well explained.<br>Allright let’s go on with the examples and show you how to use the classes.</p><h3>Using the classes</h3><p>Bootstrap has a few components that are already based on flexbox. That means you can use these classes without the need of adding the .d-flex class. A good example of one of these elements is the navbar. It already is a flex element and has the justify-content property set to space-between. We can now work on some examples with the flexbox utility classes.</p><p>The examples will only use Bootstrap utility classes, just to show their power.</p><h4>flex-direction</h4><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fembed%2Fpreview%2FaRKgKZ%3Fheight%3D600%26slug-hash%3DaRKgKZ%26default-tabs%3Dhtml%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io&amp;url=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fpen%2FaRKgKZ%3Feditors%3D1000&amp;image=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fm.cdpn.io%2Fscreenshot-coming-soon-small.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/5c47e30c203c61df5695ccb942b73cd1/href">https://medium.com/media/5c47e30c203c61df5695ccb942b73cd1/href</a></iframe><h4>flex-wrap</h4><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fembed%2Fpreview%2FReJzJx%3Fheight%3D600%26slug-hash%3DReJzJx%26default-tabs%3Dhtml%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io&amp;url=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fpen%2FReJzJx%3Feditors%3D1000&amp;image=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fm.cdpn.io%2Fscreenshot-coming-soon-small.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/0a73b14b08c54446f5ce4f0276c06f6b/href">https://medium.com/media/0a73b14b08c54446f5ce4f0276c06f6b/href</a></iframe><h4>flex-fill, flex-grow and flex-shrink</h4><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fembed%2Fpreview%2FReJzeQ%3Fheight%3D600%26slug-hash%3DReJzeQ%26default-tabs%3Dhtml%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io&amp;url=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fpen%2FReJzeQ%3Feditors%3D1000&amp;image=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fi.cdpn.io%2F252658.ReJzeQ.small.c1164fe6-d69b-468f-b4ce-2e66050880bc.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/91ff74dc6192e68faf2b0dac9f1920dd/href">https://medium.com/media/91ff74dc6192e68faf2b0dac9f1920dd/href</a></iframe><h4>justify-content</h4><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fembed%2Fpreview%2FXxYLMW%3Fheight%3D600%26slug-hash%3DXxYLMW%26default-tabs%3Dhtml%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io&amp;url=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fpen%2FXxYLMW%3Feditors%3D1000&amp;image=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fi.cdpn.io%2F252658.XxYLMW.small.3769a4d7-a103-4f2a-aa81-bab61892207e.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/d5cf847742f96c16501af3c0db8be2a3/href">https://medium.com/media/d5cf847742f96c16501af3c0db8be2a3/href</a></iframe><h4>align-items</h4><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fembed%2Fpreview%2FwYXLZN%3Fheight%3D600%26slug-hash%3DwYXLZN%26default-tabs%3Dhtml%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io&amp;url=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fpen%2FwYXLZN%3Feditors%3D1000&amp;image=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fi.cdpn.io%2F252658.wYXLZN.small.4b00c0c1-d6dc-4094-9437-1d89fdf89030.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/a5f5bd549177b9933a10d0e0a05d3f67/href">https://medium.com/media/a5f5bd549177b9933a10d0e0a05d3f67/href</a></iframe><h4>align-content</h4><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fembed%2Fpreview%2FBqVXaM%3Fheight%3D600%26slug-hash%3DBqVXaM%26default-tabs%3Dhtml%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io&amp;url=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fpen%2FBqVXaM%3Feditors%3D1000&amp;image=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fi.cdpn.io%2F252658.BqVXaM.small.55936435-eb60-47d2-9e31-70241ca0ea43.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/3ca9a0aa26545b702c8b093feac15194/href">https://medium.com/media/3ca9a0aa26545b702c8b093feac15194/href</a></iframe><h4>align-self</h4><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fembed%2Fpreview%2FwYXVpw%3Fheight%3D600%26slug-hash%3DwYXVpw%26default-tabs%3Dhtml%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io&amp;url=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fpen%2FwYXVpw%3Feditors%3D1000&amp;image=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fm.cdpn.io%2Fscreenshot-coming-soon-small.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/11a85db6bc8afef48166a2b82abbef65/href">https://medium.com/media/11a85db6bc8afef48166a2b82abbef65/href</a></iframe><h4>order</h4><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fembed%2Fpreview%2FMPBgYO%3Fheight%3D600%26slug-hash%3DMPBgYO%26default-tabs%3Dhtml%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io&amp;url=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fpen%2FMPBgYO%3Feditors%3D1000&amp;image=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fm.cdpn.io%2Fscreenshot-coming-soon-small.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/b6fe936d54f13062c1c578af993d4c5f/href">https://medium.com/media/b6fe936d54f13062c1c578af993d4c5f/href</a></iframe><p>Combining these utilities gives you great capability and flexibility (pun intended) to create whatever you want.</p><blockquote>Now, get flexing and prototype your site in minutes.</blockquote><blockquote><em>Thanks for reading, hope you learned something.<br></em><strong><em>Let me know what you want explained next, i’ll be glad to do it.</em></strong></blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4d1d43e196f9" width="1" height="1" alt=""><hr><p><a href="https://medium.com/afosto/bootstrap-v4-explained-flexing-with-utilities-4d1d43e196f9">Bootstrap v4 explained: Flexing with utilities</a> was originally published in <a href="https://medium.com/afosto">Afosto</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Bootstrap v4 explained: Display utilities, the new hiding and showing]]></title>
            <link>https://medium.com/afosto/bootstrap-v4-explained-display-utilities-the-new-hiding-and-showing-306ef6aef49e?source=rss----ab916a47e38a---4</link>
            <guid isPermaLink="false">https://medium.com/p/306ef6aef49e</guid>
            <category><![CDATA[bootstrap]]></category>
            <category><![CDATA[sass]]></category>
            <category><![CDATA[front-end-development]]></category>
            <category><![CDATA[utilities]]></category>
            <dc:creator><![CDATA[Gijs Boddeus]]></dc:creator>
            <pubDate>Thu, 01 Feb 2018 00:08:08 GMT</pubDate>
            <atom:updated>2018-05-02T14:30:31.406Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*B4YQlLbrysOvjIt0xsb0JQ.jpeg" /></figure><p>When you browse through the #help channel on the Bootstrap Slack workspace, you will see a few questions being asked over and over again. In this series I will try and answer these questions thoroughly in the hopes you will understand what techniques are used and how to use it properly.</p><p>This article will show you how to use the new display utilities to hide and show like you did in v3. We’ll also walk through the styles the classes add. <br>You can read through the documentation on <a href="http://getbootstrap.com/docs/4.0/utilities/display/">getbootstrap.com</a>.</p><blockquote><em>If you just want to know how to use it, scroll down till the next three dots.</em></blockquote><h3>Techniques</h3><p>The display utilities are actually really easy to explain, as long as you know how the display property works. If you don’t, you can read up on the below links. Do note that not every value explained on these links are supported.</p><ul><li><a href="https://css-tricks.com/almanac/properties/d/display/">https://css-tricks.com/almanac/properties/d/display/</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/display">https://developer.mozilla.org/en-US/docs/Web/CSS/display</a></li></ul><p>With Sass it is a breeze to create these classes and doesn’t take a lot of lines of code ( <a href="https://github.com/twbs/bootstrap/blob/v4-dev/scss/utilities/_display.scss">38 to be exact</a>, including comments). I’ll dig into the used functions a bit more than the previous article, otherwise it would be to easy 😉. For the developers that are concerned about print, Bootstrap’s got ya covered.</p><h4>Web</h4><p>For the web we start off with creating a loop to create classes per breakpoint.</p><pre>@each $breakpoint in map-keys($grid-breakpoints) {<br>  ...<br>}</pre><p>This loops through every defined breakpoint in the $grid-breakpoints Sass map and passes it through as $breakpoint.</p><p>The next step is actually creating the media query. For this we use a mixin called media-breakpoint-up().</p><pre>@each $breakpoint in map-keys($grid-breakpoints) {<br>  @include media-breakpoint-up($breakpoint) {<br>    $infix: breakpoint-infix($breakpoint, $grid-breakpoints);<br>    <br>    ...<br>  }<br>}</pre><p>This creates the media query using the passed on $breakpoint. to be able to use actually create the corresponding classes an $infix variable is created with the function <a href="https://github.com/twbs/bootstrap/blob/e216c8833c089d1dcf3cc71d5956e318e5487ef7/scss/mixins/_breakpoints.scss#L52">breakpoint-infix()</a> that uses the active $breakpoint and returns the computed value for the infix.</p><pre>@function breakpoint-min($name, $breakpoints: $grid-breakpoints) { <br>  $min: map-get($breakpoints, $name);<br>  @return if($min != 0, $min, null);<br>}</pre><pre>@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {<br>  @return if(breakpoint-min($name, $breakpoints) == null, &quot;&quot;, &quot;-#{$name}&quot;);<br>}</pre><p>These two functions actually do the magic to get the infix, this is used for every utility, grid column or any other element that uses any breakpoint class.<br>breakpoint-min() uses a $name ( the active $breakpoint ) and gets the corresponding pixel value from the $grid-breakpoints. This value is stored as the variable $min. If the value of $min is not 0, it returns that pixel value. If value <strong>is</strong> 0 it returns null.<br>$breakpoint-infix() uses $name ( the active $breakpoint ) and the $grid-breakpoints map to determine what should be used as the infix. If the function breakpoint-min() returns null itself will return an empty string. So for the xs breakpoint we had in v3, you can now leave out the infix to get the same result, ie.: .col-xs-12 can now be used as .col-12. For the other breakpoints that aren’t 0 it will spit out a computed value of the breakpoint name that is prefixed with a dash &quot;-#{$name}&quot;.</p><p>In the next part we actually define the classes. The display properties that are supported are: block, inline, inline-block, table, table-row, table-cell, flex and inline flex.</p><pre>...<br>    .d#{$infix}-none         { display: none !important; }<br>    .d#{$infix}-inline       { display: inline !important; }<br>    .d#{$infix}-inline-block { display: inline-block !important; }<br>    .d#{$infix}-block        { display: block !important; }<br>    .d#{$infix}-table        { display: table !important; }<br>    .d#{$infix}-table-row    { display: table-row !important; }<br>    .d#{$infix}-table-cell   { display: table-cell !important; }<br>    .d#{$infix}-flex         { display: flex !important; }<br>    .d#{$infix}-inline-flex  { display: inline-flex !important; }<br>...</pre><p>As you can see these utilities start with a d, for display, next the infix and then the value used. As these classes should overwrite any used display property on the element it is used on, it has an <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity">!important flag</a>.</p><h4>Print</h4><p>The display properties for print aren’t built with media queries per breakpoint, but only the @media print {...} one. As we now don’t need to infix these classes these are just defined as is. The supported values are the same.</p><pre>@media print {<br>  .d-print-none         { display: none !important; }<br>  .d-print-inline       { display: inline !important; }<br>  .d-print-inline-block { display: inline-block !important; }<br>  .d-print-block        { display: block !important; }<br>  .d-print-table        { display: table !important; }<br>  .d-print-table-row    { display: table-row !important; }<br>  .d-print-table-cell   { display: table-cell !important; }<br>  .d-print-flex         { display: flex !important; }<br>  .d-print-inline-flex  { display: inline-flex !important; }<br>}</pre><h3>Using the classes</h3><p>Here is the difficult part of theses utilities, and the reason for this article. Since v4 the classes .hidden-[breakpoint]-[value] and .visible-[breakpoint]-[value] were dropped. Understanding which display utilities to use to replace which old classes can be a bit confusing. Here we go.</p><h4>Mobile first</h4><p>As the classes are created using the media-breakpoint-up() mixin, we have to think from mobile and upward. So starting with a viewport width of 0, we have d-[value]. This will overwrite the elements value for display on every screen size. If we go one up, so sm, this will overwrite the elements value for display on all the screens sizes above 576px. For example if we use d-sm-none it will be visible on devices than are smaller than 576px, but hidden on devices wider than 576px.</p><p>The main difference is that the class doesn’t overwrite it for that specific breakpoint, but from that breakpoint upward. People that have used the alpha versions of v4 might be looking for .hidden-md-down, these have been dropped and it only works upward.<br>Simply said: The classes set a starting point and are used going upward.<br>If you combine the classes together those starting points are overwritten again going upward.</p><p>Got that? Hope so…</p><h4>What replaces…?</h4><p>The documentation has a table describing what classes to use in what case. To most people this is clear enough, some just wan’t a simple cheatsheet. Actually, who doesn’t want that. So here you go:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e3e8528987a80c4156e3fe31264cbb2b/href">https://medium.com/media/e3e8528987a80c4156e3fe31264cbb2b/href</a></iframe><p>Replace [value] with one of the supported values and you’re good to go. Most commonly block.</p><p>You can be even more thorough and add the class for each breakpoint, but these will do the same trick. If you can’t seem to figure it out until this point I would advice doing that. If we add it to a div it would look something like this.</p><pre>&lt;div class=&quot;d-block d-sm-block d-md-block d-lg-block d-xl-block&quot;&gt;<br>&lt;/div&gt;</pre><p>Using this method you have full control over how it’s being displayed on each breakpoint. If you have your desired display settings you can then try and simplify the classes. If the next on is the same, you can get rid of it. For example if you end up with:</p><pre>d-flex d-sm-flex d-md-flex d-lg-none d-xl-flex</pre><p>You can drop the sm and md class as it will inherit it from the starting point d-flex, the setting changes to none on the lg breakpoint and changes back to flex on xl. You will end up with:</p><pre>d-flex d-lg-none d-xl-flex</pre><p>using these steps you will end up with your desired class list to show and hide your elements.</p><p>Open this codepen in a new tab and scale your window to see the magic.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fembed%2Fpreview%2FddoaKr%3Fheight%3D600%26slug-hash%3DddoaKr%26default-tabs%3Dhtml%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io%26embed-version%3D2&amp;url=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fpen%2FddoaKr%3Feditors%3D1000&amp;image=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fi.cdpn.io%2F252658.ddoaKr.small.01f5b316-7793-4bba-9a10-286d5a39d175.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/eed45a005c8bf215265eb7242ee1052e/href">https://medium.com/media/eed45a005c8bf215265eb7242ee1052e/href</a></iframe><blockquote>Try them out and you’ll start to love them. I know I do.</blockquote><blockquote><em>Thanks for reading, hope you learned something.<br></em><strong><em>Let me know what you want explained next, i’ll be glad to do it.</em></strong></blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=306ef6aef49e" width="1" height="1" alt=""><hr><p><a href="https://medium.com/afosto/bootstrap-v4-explained-display-utilities-the-new-hiding-and-showing-306ef6aef49e">Bootstrap v4 explained: Display utilities, the new hiding and showing</a> was originally published in <a href="https://medium.com/afosto">Afosto</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to customize Bootstrap v4 using node packages]]></title>
            <link>https://medium.com/afosto/how-to-setup-a-bootstrap-project-like-bootstrap-does-it-3825a726b09a?source=rss----ab916a47e38a---4</link>
            <guid isPermaLink="false">https://medium.com/p/3825a726b09a</guid>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[frontend]]></category>
            <category><![CDATA[scss]]></category>
            <category><![CDATA[yarn]]></category>
            <category><![CDATA[bootstrap]]></category>
            <dc:creator><![CDATA[Gijs Boddeus]]></dc:creator>
            <pubDate>Wed, 24 Jan 2018 17:54:44 GMT</pubDate>
            <atom:updated>2018-09-10T00:46:49.885Z</atom:updated>
            <content:encoded><![CDATA[<p>I recently got asked if i could help develop a WordPress theme for crypto currency websites. They were building it using Bootstrap v4 so i already had a lot of ideas on how to build out every page. As I joined the bitbucket repo I was stunned to see that they had no tooling setup. All styles were written in vanilla css… hadn’t done that in a while. Scss has been my go to for the last 3 years, so I decided to change how we worked.</p><h3>What do I need</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BxO2O0kzcxz90xOBI_18RQ.jpeg" /><figcaption>All these tools (<a href="https://www.youtube.com/watch?v=r_cP5B8apKo">Unbox Therapy</a>)</figcaption></figure><p>For this project I needed to ensure code quality, ease of development by writing unprefixed css and making use of everything Sassy function, mixin and variable that Bootstrap includes. Compiling javascript was not a primary concern for now so that’s for another time.<br>Looking at the Bootstrap repository I decided on using these tools.</p><ul><li><a href="https://github.com/sass/node-sass"><strong>node-sass</strong></a> to compile scss/Sass to css</li><li><a href="https://github.com/postcss/autoprefixer"><strong>autoprefixer</strong></a> to add prefixes where needed</li><li><a href="https://github.com/postcss/postcss"><strong>postcss</strong></a> to actually use autoprefixer</li><li><a href="https://github.com/stylelint/stylelint"><strong>stylelint</strong></a> to check the code for mistakes</li><li><a href="https://github.com/jakubpawlowicz/clean-css-cli"><strong>clean-css</strong></a> to create minified versions</li></ul><h3>Exploring the possibilities</h3><p>I started out looking at the <a href="https://github.com/twbs/bootstrap">Bootstrap Github repo</a> and figure out how they build the distribution and doc files. After that I came across a video where someone used gulp to watch scss files and build on every change. I tried both ways and here is what I found out.</p><h4>NPM / Yarn</h4><p>The Bootstrap project uses npm scripts and packages to compile everything and setup a local server via jekyll. For this project I was only interested in compiling my scss to css. I also prefer Yarn over NPM but that is just personal preference, they work the same. It was pretty easy to setup (though npm-run-all didn’t do it for me) and could support everything i needed.</p><h4>Gulp</h4><p>Gulp is a really fast way of setting up build pipelines. It is completely javascript based, that means the that you can setup a pipeline with just javascript. I thought it was really cool and the video showed it was pretty fast. As I started building my pipeline in couldn’t figure out how to get stylelint integrated into the pipeline, so I chose to use NPM script for this project.<br><em>If you do know how, please tell me.</em></p><blockquote>I use IntelliJ’s WebStorm, a really powerful IDE that I am really liking and is ramping up my development speed. You don’t need an IDE to follow along, you could cope with the command line and notepad, wouldn’t advice it though…</blockquote><h3>Let’s get started</h3><p>So now we decided on which tools to use and how to run them we can get started with the project.<br>If you’ve never used node packages you can follow the setup guides for <a href="https://yarnpkg.com/lang/en/docs/install/">Yarn</a> or <a href="http://blog.npmjs.org/post/85484771375/how-to-install-npm">NPM</a>. You need one of these tools to follow along with this article. You’ll also need a basic understanding of the command line. <a href="https://www.codecademy.com/learn/learn-the-command-line">Codecademy</a> has a pretty good course for it that I also followed.<br>Now that you got all the required tools and knowledge let’s get started.</p><h4>Start a project</h4><p>Open up your command line tool and navigate to the directory you’d like to work in, create a new directory and navigate into that directory. It would look something like:</p><pre>$ cd projects<br>$ mkdir bootstrap-setup<br>$ cd bootstrap-setup</pre><p><em>If you would like to use </em><a href="https://gist.github.com/derhuerst/1b15ff4652a867391f03"><em>git</em></a><em> you can init with </em><em>git init and use all the commands when necessary.</em><br>Now we can set our project up using the init command. Running yarn init or npm init the package manager will start setting up al the required files and will ask you a few questions:</p><pre>name: project-name <br>version: (0.0.0) 0.0.1 <br>description: The Project Description <br>entry point: //a file like index.html or just &#39;.&#39;<br>test command: //leave empty <br>git repository: //the repositories url if you have any<br>keywords: //leave empty (NPM only)<br>author: // your name <br>license: N/A</pre><p>These answers will be used to build package.json. This file is like you project configuration, it includes all key information and what package are used in what environment. The contents of package.json will look something like.</p><pre>{<br>  &quot;name&quot;: &quot;bootstrap-setup&quot;,<br>  &quot;version&quot;: &quot;1.0.0&quot;,<br>  &quot;description&quot;: &quot;tooling setup like bootstrap&quot;,<br>  &quot;main&quot;: &quot;.&quot;,<br>  &quot;author&quot;: &quot;Gijs Boddeus&quot;,<br>  &quot;license&quot;: &quot;MIT&quot;<br>}</pre><p>Now we can start installing packages and running scripts.</p><h4>Installing packages</h4><p>This is the easiest part, it’s just installing all the packages. My project doesn’t need any package to be included in a release build, that means I only need dependencies for my development environment. To add packages as devDependencies you can use what’s called a flag: -D.<br>To install packages with NPM you run:</p><pre>npm install &lt;package name&gt; -D</pre><p>If you use yarn, like me, you run:</p><pre>yarn add &lt;package name&gt; -D</pre><p>I started out by installing/adding node-sass by running yarn add node-sass -D. This will install a butt load of node_modules and since it’s the first package it wil create a package.lock file, ignore it, not important.</p><p>If you don’t want to go through installing every package separately you can run these commands.</p><p><strong>Yarn</strong></p><pre>yarn add node-sass clean-css-cli autoprefixer postcss-cli stylelint stylelint-scss stylelint-order stylelint-config-standard stylelint-config-recommended-scss watch -D &amp;&amp; yarn add bootstrap@4.0.0-beta.3</pre><p><strong>NPM</strong></p><pre>npm install node-sass clean-css-cli autoprefixer postcss-cli stylelint stylelint-scss stylelint-order stylelint-config-standard stylelint-config-recommended-scss watch -D &amp;&amp; npm install bootstrap@4.0.0-beta.3</pre><p>Now that we have all the packages we need, we should configure a few things.</p><h3>Configuring the tools</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nkA3_eF9cuMau-OlAKzGaw.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/yQi4mAFmRew?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Oudom Pravat</a> on <a href="https://unsplash.com/?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>To keep it well organized create a directory like <em>build</em> or <em>configs </em>to keep all config files in.</p><h4>Stylelint</h4><p>To ensure you and/or you co-developers write clean and consistent code we use a linter to filter out mistakes and display them ass errors. Stylelint is the package Bootstrap uses for their own configuration, as is every other package we just installed. In the build directory add a file called .stylelintrc and copy the contents from the equally named file on the <a href="https://github.com/twbs/bootstrap/blob/v4-dev/.stylelintrc">Bootstrap repo</a>.</p><p>All these rules defined what is allowed and what will throw an error. For example, &quot;max-empty-lines&quot;: 2 will throw an error if you have 4 empty lines between two lines of code.</p><h4>Postcss</h4><p>Postcss is required to run autopefixer which will add vendor prefixes when necessary, depending on the configuration you define.</p><p>To specify which browsers you wan’t to support you can add an array to the package.json file specifying version like this:</p><pre>&quot;browserslist&quot;: [    <br>    &quot;last 1 major version&quot;,    <br>    &quot;&gt;= 1%&quot;,    <br>    &quot;Chrome &gt;= 45&quot;,    <br>    &quot;Firefox &gt;= 38&quot;,    <br>    &quot;Edge &gt;= 12&quot;,    <br>    &quot;Explorer &gt;= 10&quot;,    <br>    &quot;iOS &gt;= 9&quot;,    <br>    &quot;Safari &gt;= 9&quot;,    <br>    &quot;Android &gt;= 4.4&quot;,    <br>    &quot;Opera &gt;= 30&quot;  <br>],</pre><p><em>These are the default supported browsers by Bootstrap.</em></p><p>To make it possible to add prefixes when needed you need to create a postcss.config.js file and paste this into it:</p><pre>&#39;use strict&#39; </pre><pre>module.exports = (ctx) =&gt; ({<br>    map: ctx.file.dirname.includes(&#39;examples&#39;) ? false : {<br>        inline: false,<br>        annotation: true,<br>        sourcesContent: true<br>    },<br>    plugins: {<br>        autoprefixer: { cascade: false }<br>    }<br>})</pre><p>Now the tools are configured and we can run some scripts… but first we need some scss files. Easiest way, simply add a directory for the scss files and create a main.scss file. In that file import the bootstrap source files from the node_modules:</p><pre><strong>@import</strong> &quot;../../node_modules/bootstrap/scss/bootstrap&quot;;</pre><p>Now we have something to compile and we can start writing scripts.</p><h3>Defining scripts</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mxwl0_gdFfhnpXeh8RozCA.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/FXFz-sW0uwo?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Markus Spiske</a> on <a href="https://unsplash.com/?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>Inside you package.json you can add a section in which you can define scripts to be run inside the command line. This is very convenient as you can group multiple scripts that you would normally run separately, into one simple command.<br>In my project I defined these scripts:</p><ul><li><strong>css:lint </strong>(to test our scss with the stylelint configuration)</li><li><strong>css:compile </strong>(to compile our scss into css files)</li><li><strong>css:prefix </strong>(to add prefixes via autoprefixer)</li><li><strong>css:minify </strong>(to create minified files)</li><li><strong>css:watch </strong>(to start watching for changes in the scss dir)</li><li><strong>css </strong>(to run css:lint, css:compile, css:prefix and css:minify all together)</li></ul><p>I actually copied most of the rules from Bootstrap’s package.json, but made some changes as i didn’t use the <em>npm-run-all </em>package (also available as <em>yarn-run-all </em>for yarn) to run multiple commands parallel or synchronous.</p><p>Open up your package.json and add an array to place your scripts in. You can scripts like this:</p><pre>&quot;scripts&quot;: {<br>  &quot;[script-name]&quot;: &quot;[command line script to run]&quot;,<br>}</pre><h4>css:lint</h4><p>This command will run stylelint with the configuration we defined earlier. If anything is not according to the rules it will return this in neatly in the command line. The script looks like this.</p><pre>stylelint --config build/.stylelintrc --syntax scss \&quot;scss/**/*.scss\&quot; --cache --cache-location \&quot;build/.stylelintcache/\&quot;</pre><p>Basically: run stylelint, use the rules from our config, the code we will lint is scss, go through every scss file in the scss dir and sub directories and cache the results to our build dir. I added the caching to speed up the watcher we will create in a minute.</p><h4>css:compile</h4><p>Now we have clean code, we need to transform it to usable code. Node-sass is a node.js sass/scss pre-processor that will compile your files into usable css.</p><pre>node-sass --output-style expanded --source-map true --source-map-contents true --precision 6 scss/main.scss style.css</pre><p>Basically: output css in expanded mode, generate source maps for easy debugging, allow 6 decimals, use scss/main.scss and output it as style.css. Easy right :).</p><h4>css:prefix</h4><p>We have usable css! well in the newest browsers, unfortunately we still need vendor prefixes. Autoprefixer to the rescue! We can run it as part of postcss as it actually is an addon for it. So the script:</p><pre>postcss --config build/postcss.config.js --replace \&quot;*.css\&quot; \&quot;!*.min.css\&quot;</pre><p>Basically: run postcss, use our config and use all .css files, but <strong>not </strong>the .min.css files and prefix it if needed based on our browserlist.</p><h4>css:minify</h4><p>We are all set with usable css and prefixes for all the browser we need to support. You could stop there but a good last step is to minify your files to minimize the file size. Here’s how:</p><pre>cleancss --level 1 --source-map --source-map-inline-sources --output style.min.css style.css</pre><p>Basically: run cleancss, level of cleanup to perform clean, create a source map fo the minified file, output style.min.css from style.css.</p><h4>css</h4><p>Sweet, everything is setup and we are able to run all of our scripts in our command line. But we don’t want to run all of these scripts separately everytime. We can combine defined scripts into one, single, easy command.</p><pre>yarn css:lint &amp;&amp; yarn css:compile &amp;&amp; yarn css:prefix &amp;&amp; yarn css:minify</pre><blockquote>To run these with NPM you need to replace yarn with npm run. Otherwise they will not run.</blockquote><p>Basically: run all scripts above in order. If you use npm: replace yarn with npm run. (this is where <em>npm-run-all </em>would come in)</p><h4>css:watch</h4><p>Everything now works and can get executed with a single command, awesome!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MNJ5WYM9oe6OGJVGxSeWgg.jpeg" /><figcaption>Sorry, had to do it. (<a href="https://i.ytimg.com/vi/-Rt05oUmt5E/maxresdefault.jpg">https://i.ytimg.com/vi/-Rt05oUmt5E/maxresdefault.jpg</a>)</figcaption></figure><p>We can setup a watcher to run the css script every time an scss file is changed/saved. If run this script you can save your file, refresh your browser and you will see your changes. So without further ado:</p><pre>watch &#39;yarn css&#39; scss</pre><p>After all this your scripts array should look something like:</p><pre>&quot;scripts&quot;: {<br>  &quot;css:lint&quot;: &quot;stylelint --config build/.stylelintrc --syntax scss \&quot;scss/**/*.scss\&quot; --cache --cache-location \&quot;build/.stylelintcache/\&quot;&quot;,<br>  &quot;css:prefix&quot;: &quot;postcss --config build/postcss.config.js --replace \&quot;*.css\&quot; \&quot;!*.min.css\&quot;&quot;,<br>  &quot;css:compile&quot;: &quot;node-sass --output-style expanded --source-map true --source-map-contents true --precision 6 scss/main.scss style.css&quot;,<br>  &quot;css:minify&quot;: &quot;cleancss --level 1 --source-map --source-map-inline-sources --output style.min.css style.css&quot;,<br>  &quot;css&quot;: &quot;yarn css:lint &amp;&amp; yarn css:compile &amp;&amp; yarn css:prefix &amp;&amp; yarn css:minify&quot;,<br>  &quot;css:watch&quot;: &quot;watch &#39;yarn css&#39; scss&quot;<br>}</pre><h3>Running the scripts</h3><p>Now that everything is working we can go ahead and start customizing bootstrap and creating our theme. Open the main.scss file and replace its content with:</p><pre>//$primary: #fe39ed;<br><br>@import &quot;../node_modules/bootstrap/scss/bootstrap&quot;;</pre><p>Start up the watcher with yarn css:watch and keep an eye on the command line. You should get the following output:</p><pre>yarn run v1.3.2<br>$ watch &#39;yarn css&#39; scss<br>&gt; Watching scss<br>$ yarn css:lint &amp;&amp; yarn css:compile &amp;&amp; yarn css:prefix &amp;&amp; yarn css:minify<br>$ stylelint --config build/.stylelintrc --syntax scss &quot;scss/**/*.scss&quot; --cache --cache-location &quot;build/.stylelintcache/&quot;</pre><pre>scss/main.scss<br> 3:51  ✖  Unexpected missing end-of-source newline   no-missing-end-of-source-newline</pre><p>Seems we have an error according to stylelint. Take a look at line 3 of main.scss. Our rules define we wan’t an empty line as the last line of every file. Go ahead and add an empty line to the file and save it. You should see some action in the command line, it shouldn’t throw any errors and lint + compile + prefix + minify without a problem.</p><p>Now to see it in action: create an index.html file in the root of your project. Open the file in a browser. Now add the following to the content of the file:</p><pre>&lt;!doctype html&gt;<br>&lt;html lang=&quot;en&quot;&gt;<br>    &lt;head&gt;<br>        &lt;meta charset=&quot;UTF-8&quot;&gt;<br>        &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0&quot;&gt;<br>        &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&gt;<br>        &lt;title&gt;Bootstrap build setup&lt;/title&gt;<br><br>        <em>&lt;!--  include our style.min.css  --&gt;<br>        </em>&lt;link rel=&quot;stylesheet&quot; href=&quot;./style.min.css&quot;&gt;<br>    &lt;/head&gt;<br>    &lt;body&gt;<br>        &lt;div class=&quot;container mt-5&quot;&gt;<br>            &lt;div class=&quot;card bg-primary text-light mb-5&quot;&gt;<br>                &lt;div class=&quot;card-body text-center py-5&quot;&gt;<br>                    &lt;h1&gt;<br>                        $primary<br>                    &lt;/h1&gt;<br>                &lt;/div&gt;<br>            &lt;/div&gt;<br>        &lt;/div&gt;<br>    &lt;/body&gt;<br>&lt;/html&gt;</pre><p>Refresh your browser and you should see:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HJA_ApcoxnS8Sk1fc1lm4w.png" /><figcaption>$primary will set the background color to #007bff</figcaption></figure><p>Now go back to main.scss and have a look at the first line. This line will override the default value of the primary color variable that Bootstrap uses. Delete the two slashes, //, at the beginning of the line and save the file. Node does its magic and tada!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gZxAD8SCLDG_IobOQqGKXA.png" /><figcaption>$primary now sets the background <em>#fe39ed</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*bGo37peHzBWFxc5Ga1D52g.gif" /></figure><p><strong>We have now customized bootstrap! You can use </strong><a href="https://github.com/twbs/bootstrap/blob/v4-dev/scss/_variables.scss"><strong>variables.scss</strong></a><strong> from the Bootstrap repo as a reference for all the variabels you can use.</strong></p><p>Make sure you read the <a href="http://getbootstrap.com/docs/4.0/getting-started/theming/">documentation on theming</a> to fully understand how to handle different scenarios and use colors in your custom css.</p><p>A good way to structure main.scss is to put all variables into a separate file, also don’t add actual css rules to this file but add them in their own files, and structure the imports like:</p><pre><strong>@import</strong> &quot;variables&quot;;<br><strong>@import</strong> &quot;../../node_modules/bootstrap/scss/bootstrap&quot;;<br><br><em>//  custom styles</em><br><strong>@import</strong> &quot;layout&quot;;<br><strong>@import</strong> &quot;pages&quot;;<br><strong>@import</strong> ...</pre><blockquote>Have a look at <a href="https://bootstrap.build/">bootstrap.build</a>. It’s a Bootstrap configuration tool made by <a href="https://github.com/olegberman">Oleg Berman</a>, really cool!</blockquote><h3>That’s that</h3><p>Now you’re ready to create, customize and build a bootstrap based website.</p><p>I learned a lot figuring out how to get this up and running, this actually the first i did it without using a framework. I feel like I have a better understanding of how frameworks do it and what is needed to actually deliver distributable files.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*RI27HbXO3e6tz6IXivGxNA.gif" /><figcaption>Speed of running the scripts via the watcher</figcaption></figure><p>Though this works, the watcher is a little slow on picking up changes. Also the speed of compilation isn’t top notch. From what I have seen in Youtube, Gulp should be faster, but I couldn’t get stylelint into the pipline like I wanted to. Also <em>npm-run-all</em> might speed up a thing or two, but i got some overlapping scripts and stuff… I was just being foolish I now realize.</p><p>And yes I know Webstorm has built in sass compilation, but the other collaborators are using their preferred editor so I needed this.</p><p><strong>Wishlist</strong></p><ul><li>faster compiling</li><li>faster watcher</li><li>hot reloading of the styles (changes are instantly pushed to the browser)</li><li>js scripts</li></ul><blockquote>Hope you liked this article/tutorial</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3825a726b09a" width="1" height="1" alt=""><hr><p><a href="https://medium.com/afosto/how-to-setup-a-bootstrap-project-like-bootstrap-does-it-3825a726b09a">How to customize Bootstrap v4 using node packages</a> was originally published in <a href="https://medium.com/afosto">Afosto</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Bootstrap v4 explained: The grid and how to use it]]></title>
            <link>https://medium.com/afosto/bootstrap-v4-explained-the-grid-and-how-to-use-it-82a4de58604e?source=rss----ab916a47e38a---4</link>
            <guid isPermaLink="false">https://medium.com/p/82a4de58604e</guid>
            <category><![CDATA[scss]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[grid]]></category>
            <category><![CDATA[bootstrap]]></category>
            <category><![CDATA[frontend]]></category>
            <dc:creator><![CDATA[Gijs Boddeus]]></dc:creator>
            <pubDate>Wed, 24 Jan 2018 17:52:46 GMT</pubDate>
            <atom:updated>2018-01-27T14:31:02.681Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8D3bOkIAnu2WVmOIFhakXQ.jpeg" /></figure><p>When you browse through the #help channel on the Bootstrap Slack workspace, you will see a few questions being asked over and over again. In this series I will try and answer these questions thoroughly in the hopes you will understand what techniques are used and how to use it properly.</p><p>Today I’ll explain the scss techniques used to create the grid and how to use the classes in your html. You can read through the documentation on <a href="http://getbootstrap.com/docs/4.0/layout/grid/">getbootstrap.com</a></p><blockquote>If you just want to know how to use it, scroll down till the next three dots.</blockquote><h3>Techniques</h3><p>Back in the day people had to create grid structures with tables (actually a hack), then with floating divs (also a hack), now we use flexbox (still a hack) and if you’re really up to date css grid (not a hack!). earlier versions of Bootstrap used the float technique, but it had it’s caveats. Version 4 introduces a grid based on flexbox. If you don’t know how flexbox works, here are some links to learn about it.</p><ul><li><a href="http://flexboxfroggy.com/#nl">http://flexboxfroggy.com</a> (a little game about a frog)</li><li><a href="https://css-tricks.com/snippets/css/a-guide-to-flexbox/">https://css-tricks.com/snippets/css/a-guide-to-flexbox/</a> (in depth explanation)</li></ul><h4>Container</h4><p>The .container is a really simple element. It gets a padding equal to half of the gutter width. It also gets centered by adding margin-left: auto; and margin-right: auto;. The width of the container is generated by the make-container-max-widths() mixin. It creates a media query for every breakpoint and adds max-width: [max-width];. The .container-fluid class is exactly the same but without the max-widths, it takes up the full width of your screen and only has the padding.<br>Here’s the scss mixin that creates it:</p><pre>@mixin make-container() {  <br>  width: 100%;  <br>  padding-right: ($grid-gutter-width / 2);  <br>  padding-left: ($grid-gutter-width / 2);  <br>  margin-right: auto;  <br>  margin-left: auto;<br>}</pre><p>For the widths scss the mixin looks like:</p><pre>@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {<br>  @each $breakpoint, $container-max-width in $max-widths {<br>    @include media-breakpoint-up($breakpoint, $breakpoints) {<br>      max-width: $container-max-width;<br>    }  <br>  }<br>}</pre><p>Don’t be frightened by all the variables. What this mixin does is: create a media query for every value in $grid-breakpoints and add a max-width rule into the media query based on the corresponding value in $container-max-widths.</p><h4>Row</h4><p>Flexbox by default aligns items on a single row and starts it on the left. It also defaults to flex-wrap: nowrap , this means it will align all items side by side, even if they don’t really fit. So, Bootstrap sets this property to wrap to make it possible to break columns intro more rows without adding it to as html markup.<br>The scss used for the .row are just this:</p><pre>@mixin make-row() {<br>  display: flex;<br>  flex-wrap: wrap;  <br>  margin-right: ($grid-gutter-width / -2);  <br>  margin-left: ($grid-gutter-width / -2);<br>}</pre><p>It uses flex(box) as the display setting, tells it to wrap instead of overflow and adds negative margins to compensate for the padding on the container. By default these are -15px (30px / -2).</p><p>Additionally the .no-gutters class can be added to the .row element. This adds styling for the row and the columns that are direct children of it. The styles added are:</p><pre>.no-gutters {<br>  margin-right: 0;<br>  margin-left: 0;</pre><pre>  &gt; .col,<br>  &gt; [class*=&quot;col-&quot;] {<br>    padding-right: 0;<br>    padding-left: 0;<br>  }<br>}</pre><p>This removes the negative margin from the row and positive padding from the columns inside te row.</p><h4>Columns</h4><p>The columns are the hardest to understand in my opinion. Since we’re harnessing the power of flexbox, Bootstrap uses flex: 0 0 [col-width]; to set the width of the columns.</p><p>First thing is the general styling added to every column class.</p><pre>position: relative;<br>width: 100%;<br>min-height: 1px; // Prevent columns from collapsing when empty<br>padding-right: ($gutter / 2);<br>padding-left: ($gutter / 2);</pre><p>Not a lot of new things going on here. What might throw you off is the width: 100%; on the second line. This is just a default to stretch the column. The padding gets added by default too with the same as the container.</p><p>To create a structure we need to be able to define the width of column. Bootstrap uses a twelve column grid. This means we can use any number from 1 trough 12 to define it’s width. For example: to get 2 even width columns next to each other, use the number 6 for both column classes.<br>The actual lines that add the width to each column class are:</p><pre>@mixin make-col($size, $columns: $grid-columns) {<br>  flex: 0 0 percentage($size / $columns);<br>  max-width: percentage($size / $columns);<br>}</pre><p>What the percentage($size / $columns) does is taking a width like 6 and divides it by the number of columns, by default 12, and calculates a percentage with it. So for col-[infix]-6 it will print out 50%. The outcome of the percentage function is used in both lines. As the flex property is a shorthand it also gets a flex-shrink and a flex-grow value of 0 to ensure it keeps the defined width. The max-width is a fix for IE and Firefox.<br>Now this is all we need to make a grid, though it is not responsive yet. For that we need to setup the classes for columns 1 through 12 for each breakpoint. Now this is a pretty big <a href="https://github.com/twbs/bootstrap/blob/17b0472b12915dd413b50a41d6975529b04b0a6e/scss/mixins/_grid-framework.scss#L6">mixin</a> so bear with me here…</p><pre>@each $breakpoint in map-keys($breakpoints) {<br>    $infix: breakpoint-infix($breakpoint, $breakpoints);</pre><p>This first part sets a variable to use as an infix for the column classes, by default: sm, md, lgand xl. Note that xs is not used in any class in v4. This is due to the mobile first approach, so the starting point is xs. I.e.col-6 is the class for a 50% width column for every screen width.</p><pre>@include media-breakpoint-up($breakpoint, $breakpoints) {<br>  .col#{$infix} {<br>    flex-basis: 0;<br>    flex-grow: 1;<br>    max-width: 100%;<br>  }<br>  .col#{$infix}-auto {<br>    flex: 0 0 auto;<br>    width: auto;<br>    max-width: none;<br>  }</pre><pre>  ...</pre><p>Here we are at the start of creating the classes for each breakpoint using the media-breakpoint-up mixin and passing the breakpoints map to it. So for each breakpoint this will create two classes that work a little different from the number classes. The first class will stretch the column for as long as it fits, given it’s content.<br>The second class will overwrite the default styling so it’s not a 100% by default, it will just be as wide as it’s content.</p><pre>  ...</pre><pre>  @for $i from 1 through $columns {<br>    .col#{$infix}-#{$i} {<br>      @include make-col($i, $columns);<br>    }<br>  }</pre><pre>  ...</pre><p>Here we actually create the classes we can make the grid responsive with. It loops through every number starting at 1 and ending with the defined number off columns, by default this is 12. It combines the fixed .col and, when it’s not the smallest breakpoint, the earlier defined $infix with the counter ( $i ) to create the class name. It uses the make-col() mixin I explained earlier to add the lines for flex and max-width.</p><pre>  ...</pre><pre>  .order#{$infix}-first {<br>    order: -1;<br>  }<br>  @for $i from 0 through $columns {<br>    .order#{$infix}-#{$i} {<br>      order: $i;<br>    }<br>  }</pre><pre>  ...</pre><p>Here we create the useful order classes for each breakpoint an each option from 0 to 12, again using the infix for the breakpoint. The first class will set the column to the first position regardless off its position. More on these classes in <a href="http://getbootstrap.com/docs/4.0/layout/grid/#reordering">the docs.</a></p><pre>  ...</pre><pre>  @for $i from 0 through ($columns - 1) {<br>    @if not ($infix == &quot;&quot; and $i == 0) {<br>      .offset#{$infix}-#{$i} {<br>        @include make-col-offset($i, $columns);<br>      }<br>    }<br>  }<br>}</pre><p>And for the last part we create the offset classes. These classes add a margin-left based on the same percentage as the width for the columns. <a href="https://github.com/twbs/bootstrap/blob/17b0472b12915dd413b50a41d6975529b04b0a6e/scss/mixins/_grid.scss#L49">Link to the mixin.</a></p><p><strong>This concludes all the scss magic done for you by the Bootstrap package. Now that we have all these classes, how do we use them in our html?</strong></p><h3>Using the classes in HTML</h3><p>Most of the times this is where people get confused. The main thing is knowing <strong>when</strong> to add <strong>which</strong> class on <strong>what </strong>element. So to keep going in the same format, we’ll start of with the container. <br>You can copy the examples below and us this in a codepen, I have a template setup with v4-beta3 which you can find <a href="https://codepen.io/pen?template=XeEyWG">here</a>.</p><h4>Container</h4><p>The container sounds pretty straight forward, but not to everyone. It has been confused as a row, or used nested in another container. The container should always be the outer most element in your website. So starting with a little code:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fembed%2Fpreview%2FbaKZpG%3Fheight%3D600%26slug-hash%3DbaKZpG%26default-tabs%3Dhtml%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io%26embed-version%3D2&amp;url=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fpen%2FbaKZpG&amp;image=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fm.cdpn.io%2Fscreenshot-coming-soon-small.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/d9bac5263bf456ad7ca24652361026bb/href">https://medium.com/media/d9bac5263bf456ad7ca24652361026bb/href</a></iframe><p>This could be the start of your website. The yellow bar is the container element, it is centered by the margin on the x axis with the auto value and has a fixed width. You can use the container-fluid class if you want to make a full width site.<br>to get the text in the header and footer to align with the text, you can place a div inside the header or footer and the container class. That way everything lines up.</p><p>So to be clear: this is the only thing it should be used for. The outer most element so everything aligns vertically. It can be nested in other elements, but these should not have width, margin or padding settings.</p><h4>Row</h4><p>The row should be a direct child of the container. This is what you should adhere to but you can deviate from this. In the example we have a row in the container with a blue background.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fembed%2Fpreview%2Fwywapy%3Fheight%3D600%26slug-hash%3Dwywapy%26default-tabs%3Dhtml%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io%26embed-version%3D2&amp;url=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fpen%2Fwywapy&amp;image=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fi.cdpn.io%2F252658.wywapy.small.83ad2033-4b0c-4935-bb2d-fc5e75ac3533.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/3657748c3e8159582324136b9c7e819d/href">https://medium.com/media/3657748c3e8159582324136b9c7e819d/href</a></iframe><p>You might notice you don’t see the yellow anymore. Thats due to the negative margin on the row. Remember? The container adds 15px of padding on the left and the right, the row adds a margin of -15px to the left and the right to accommodate the padding on the column.<br>Wrapping the row in another element should be allright, but to be on the safe side only use rows as a direct child of a container or of a column.</p><h4>Column</h4><p>This is where the magic happens. <br>The first rule you really need to stick to is: columns <strong>can </strong>only be children of a row, and I’m serious here. Do not use it in any other way, only if you fully understand how flexbox works and you know all the caveats of using it in any browser. Using theses classes the wrong way can really mess up your layout in some browsers.</p><p>Ok now let’s have some fun.<br>If we take the example above and add the most basic column class we have to it, .col, we will see it line up with the container again.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fembed%2Fpreview%2FBJVbRa%3Fheight%3D600%26slug-hash%3DBJVbRa%26default-tabs%3Dhtml%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io%26embed-version%3D2&amp;url=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fpen%2FBJVbRa&amp;image=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fi.cdpn.io%2F252658.BJVbRa.small.48aa34dd-cc70-43a3-ada8-c474cfaea05d.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/e0c55944aa543ba68032b5d49264d48e/href">https://medium.com/media/e0c55944aa543ba68032b5d49264d48e/href</a></iframe><p>you can see the column is exactly as wide as its parent ( the row ), but has a padding of 15px to align with the container again.</p><p>In the example below you can see a basic even width three column layout. In this example this layout is exactly the same across any screen width. That is due to the use of col-4. This class means “Take up 4 of the 12 columns, on every screen width”.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fembed%2Fpreview%2FqpwMJN%3Fheight%3D600%26slug-hash%3DqpwMJN%26default-tabs%3Dhtml%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io%26embed-version%3D2&amp;url=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fpen%2FqpwMJN&amp;image=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fi.cdpn.io%2F252658.qpwMJN.small.e700fdee-e48f-4d25-bc7d-692f51b947a6.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/9ff6ae0920b4ee6c9d2054089fbd33dc/href">https://medium.com/media/9ff6ae0920b4ee6c9d2054089fbd33dc/href</a></iframe><p>Now lets make it responsive, it’s really easy.<br>All we need to do is modify our column classes. We will need a default and add a breakpoint to align the columns next to each other. As Bootstrap v4 is created with mobile first in mind, the default will be for the smallest screen. To do so the class col-12 will give us a full width column. On bigger sizes we want it to go back to three side-by-side columns, we can do this by using col-md-4. What these two classes will tell the browser is: “On small screens you stack on top of each other and take up all 12 column. On screens like tablets and bigger take up 4 of the 12 and let other columns go beside it.”</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fembed%2Fpreview%2FopOaxe%3Fheight%3D600%26slug-hash%3DopOaxe%26default-tabs%3Dhtml%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io%26embed-version%3D2&amp;url=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fpen%2FopOaxe&amp;image=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fi.cdpn.io%2F252658.opOaxe.small.7f0e1ecc-1d6b-438d-95b7-da3b43ea1aa6.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/1df726ff3f71e5e09d0e33e8cfb6ff67/href">https://medium.com/media/1df726ff3f71e5e09d0e33e8cfb6ff67/href</a></iframe><p>Now we have responsive layout we can use in our project. The next example is somewhat a real world use.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fembed%2Fpreview%2FrpbqwM%3Fheight%3D600%26slug-hash%3DrpbqwM%26default-tabs%3Dhtml%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io%26embed-version%3D2&amp;url=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fpen%2FrpbqwM&amp;image=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fi.cdpn.io%2F252658.rpbqwM.small.a8108156-53eb-48e5-9ba7-f8f66fa2773b.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/244acd41f04e6d14358c9bdbdb30bc3e/href">https://medium.com/media/244acd41f04e6d14358c9bdbdb30bc3e/href</a></iframe><p>Yes that is <a href="//www.placecage.com">Nicolas Cage</a>… he can play anything.<br>Same layout as the example above, but with some content in it.</p><h4>Nesting grids</h4><p>You can also nest grids into each other, wel you can start another row inside a column and use columns in it. Golden rule: NEVER NEST A CONTAINER. <br>The order to nest is and can only be:</p><pre>.container<br>  .row<br>    .col<br>      .row<br>        .col<br>          // etc.</pre><p>or if this clarifies it better: .container &gt; .row &gt; .col &gt; .row &gt; .col &gt; //etc. This is the one thing most people seem to misinterpret about the grid. 2 common misunderstandings: using the container as a row and nesting containers inside columns.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fembed%2Fpreview%2FKZYrBX%3Fheight%3D600%26slug-hash%3DKZYrBX%26default-tabs%3Dhtml%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io%26embed-version%3D2&amp;url=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fpen%2FKZYrBX&amp;image=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fi.cdpn.io%2F252658.KZYrBX.small.9782b294-5a54-4a9f-8c36-d166783e42df.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/2a91837b5ba58d93e617a735d7f994e3/href">https://medium.com/media/2a91837b5ba58d93e617a735d7f994e3/href</a></iframe><p>The yellow block is a row that is nested inside the red column.</p><h4>No gutters</h4><p>optionally, I don’t really use it, you can add the class no-gutters to the row to get rid of the gutter between the columns. It still respects the padding of the column but removes the negative margin of the row and the padding of the columns.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fembed%2Fpreview%2FKZYrry%3Fheight%3D600%26slug-hash%3DKZYrry%26default-tabs%3Dhtml%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io%26embed-version%3D2&amp;url=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fpen%2FKZYrry&amp;image=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fi.cdpn.io%2F252658.KZYrry.small.2b68ba31-694e-4173-ba1c-abddc8d8a48d.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/8967b5fec0f2ea64184091c9a82053fa/href">https://medium.com/media/8967b5fec0f2ea64184091c9a82053fa/href</a></iframe><p>As you can see the red and the blue column now have no gutters and are snuck up to each other. Notice that i only added the class to the outer row, not the nested row. As you can see the yellow row still respects the gutters. The row has a negative margin on the left and the right, thus placing the nested columns right up to the outer column edges.</p><h3>Et voíla</h3><p>Thats the basics of of how to use the grid. Use it wisely and keep this in mind:</p><pre>.container<br>  .row<br>    .col<br>      .row<br>        .col<br>          // etc.</pre><p>Here are some more advanced examples to learn from. They are entirely made up out of bootstrap components, plus some awesome pictures 😉.</p><h4>Product grid</h4><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fembed%2Fpreview%2FmpgzxQ%3Fheight%3D600%26slug-hash%3DmpgzxQ%26default-tabs%3Dhtml%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io%26embed-version%3D2&amp;url=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fpen%2FmpgzxQ&amp;image=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fi.cdpn.io%2F252658.mpgzxQ.small.0e2315c0-5c25-416d-a27e-47be2399e27e.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/09138b0f40c9c838bb7d6234a4e90e3d/href">https://medium.com/media/09138b0f40c9c838bb7d6234a4e90e3d/href</a></iframe><h4>Banner grid</h4><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fembed%2Fpreview%2FxpeyNY%3Fheight%3D600%26slug-hash%3DxpeyNY%26default-tabs%3Dhtml%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io%26embed-version%3D2&amp;url=https%3A%2F%2Fcodepen.io%2Fgijsbotje%2Fpen%2FxpeyNY&amp;image=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fi.cdpn.io%2F252658.xpeyNY.small.600cd3d1-bd87-42ba-b5c2-5ad6e228eca4.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/73e0041facbf7b0c6c1daac5ffd8f037/href">https://medium.com/media/73e0041facbf7b0c6c1daac5ffd8f037/href</a></iframe><blockquote>You can go all kinds of crazy with the grid, use your imagination and explore the possibilities.</blockquote><blockquote>Thanks for reading, hope you learned something.<br>Next up on the list: <strong>Display utilities, the new hiding and showing</strong></blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=82a4de58604e" width="1" height="1" alt=""><hr><p><a href="https://medium.com/afosto/bootstrap-v4-explained-the-grid-and-how-to-use-it-82a4de58604e">Bootstrap v4 explained: The grid and how to use it</a> was originally published in <a href="https://medium.com/afosto">Afosto</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>