<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Aaron Choo</title>
    <description>The latest articles on DEV Community by Aaron Choo (@aaroncql).</description>
    <link>https://dev.to/aaroncql</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F413588%2F51b7bb2b-fc73-433e-af54-fb9818fa76d5.png</url>
      <title>DEV Community: Aaron Choo</title>
      <link>https://dev.to/aaroncql</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aaroncql"/>
    <language>en</language>
    <item>
      <title>Relating SOLID principles to CSS and Tailwind</title>
      <dc:creator>Aaron Choo</dc:creator>
      <pubDate>Mon, 19 Oct 2020 13:13:34 +0000</pubDate>
      <link>https://dev.to/aaroncql/relating-solid-principles-to-css-and-tailwind-1j17</link>
      <guid>https://dev.to/aaroncql/relating-solid-principles-to-css-and-tailwind-1j17</guid>
      <description>&lt;p&gt;This is the second (and last) article in the series. If you haven't read the first one yet, which discussed basic ideas of how to apply OOP concepts to CSS, you might want to catch up on it first:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/aaroncql" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F413588%2F51b7bb2b-fc73-433e-af54-fb9818fa76d5.png" alt="aaroncql"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/aaroncql/applying-oop-principles-to-css-cof" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Applying OOP concepts to CSS&lt;/h2&gt;
      &lt;h3&gt;Aaron Choo ・ Oct 16 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#css&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#html&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#oop&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tailwindcss&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;In this article, we start by introducing the &lt;a href="https://en.wikipedia.org/wiki/SOLID" rel="noopener noreferrer"&gt;SOLID principles&lt;/a&gt; into our CSS, and then relate everything back to Tailwind.&lt;/p&gt;

&lt;h2&gt;
  
  
  Single Responsibility Principle in CSS
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Single Responsibility Principle (SRP) states that every module, class or function should have responsibility over a single part of that program's functionality&lt;/strong&gt;, which it should &lt;em&gt;encapsulate&lt;/em&gt;. What it means is that every CSS class (or object as we have defined) we write should only have a single function or use, and it should do it well. Going back to our button example in the first article again, the CSS for &lt;code&gt;.base-btn&lt;/code&gt; was as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.base-btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="no"&gt;cyan&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This class actually violates SRP, because it has two different responsibilities: one to style the border, and another to style the text colour. In OOP fashion, we can say that the &lt;code&gt;.base-btn&lt;/code&gt; class has more than a single reason to change (either to change the style of the border, or of the text colour). To try to remedy this, we can split the class up like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.btn-border&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="no"&gt;cyan&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.white-text&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, one can say still that the &lt;code&gt;.btn-border&lt;/code&gt; class violates SRP, since it actually contains styles for three different aspects of a border, and thus has more than a single responsibility. As such, we can split it up even further like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.solid-border&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;border-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.width-2px-border&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;border-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.cyan-border&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;border-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;cyan&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.white-text&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, each class truly has only a single responsibility and a single reason to change. However, the disadvantage is that what once took us 4 lines of CSS, now takes at least 12 lines (3 for each of the 4 classes), 3x more than what we started with! Note however, that this is a trivial example, and not representative of what is seen in practical settings. Since the classes defined here truly has a single responsibility, another person could also argue that you can use these classes in other parts of the HTML, without duplicating a single line of CSS, and therefore save more lines of CSS &lt;em&gt;in the long run&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Remember that the purpose of SRP is so that the styles defined within a class is highly &lt;a href="https://en.wikipedia.org/wiki/Cohesion_(computer_science)" rel="noopener noreferrer"&gt;cohesive&lt;/a&gt;, thereby increasing the chance of reusing this class somewhere else. What this essentially means is the result of &lt;em&gt;smaller classes&lt;/em&gt;, but &lt;em&gt;many more classes&lt;/em&gt;, which may lead to more CSS than what we started with.&lt;/p&gt;

&lt;p&gt;Always remember, that &lt;strong&gt;there is always the tradeoff between developer experience and code size, and always a certain overhead in adhering to any principle&lt;/strong&gt;. For a small and trivial website, the benefits of adhering to SRP blindly might not be apparent, and may even hamper development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open-Closed Principle in CSS
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Open-Closed Principle (OCP) states that classes should be open for extension, but closed for modification&lt;/strong&gt;. In CSS, it means that if we were to have base classes defined (eg, &lt;code&gt;.white-text&lt;/code&gt;, &lt;code&gt;.blue-border&lt;/code&gt;), we should try to avoid modifying it directly, but instead extend from it. Implicitly, this makes sense because any modification to the base &lt;code&gt;.white-text&lt;/code&gt; class will most certainly affect all the HTML tags which use and depend on this class - something which we want to avoid.&lt;/p&gt;

&lt;p&gt;In the previous article, we have already seen the idea of &lt;em&gt;composition&lt;/em&gt;, which plays nicely together with OCP. Instead of modifying the base classes which already exist, we should instead compose them together to form our eventual style.&lt;/p&gt;

&lt;p&gt;Of course, you could go the other route: use the base classes as defined, but override the undesirable rules using &lt;code&gt;!important&lt;/code&gt;. However, this actually violates another one of the SOLID principles (discussed later, don't worry), not to mention the &lt;a href="https://uxengineer.com/css-specificity-avoid-important-css/#why-avoid-!important" rel="noopener noreferrer"&gt;fragility of using &lt;code&gt;!important&lt;/code&gt; to override your own CSS&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Liskov Substitution Principle in CSS
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Liskov Substitution Principle (LSP) states that objects of a superclass should be replaceable with objects of its subclasses without breaking the application&lt;/strong&gt;. If you do not use a CSS processor like Less, Sass, or Stylus, this section might be less applicable to you. I'll admit, however, that this section isn't applicable to me either, not because I don't use CSS processors, but because I much prefer &lt;a href="https://en.wikipedia.org/wiki/Composition_over_inheritance" rel="noopener noreferrer"&gt;composition over inheritance&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I highly recommend this article, &lt;a href="https://frontstuff.io/should-you-chain-or-extend-css-classes" rel="noopener noreferrer"&gt;&lt;em&gt;Should You Chain or Extend CSS Classes&lt;/em&gt;&lt;/a&gt;, which talks in great length about the advantages of composition over inheritance. Of course, this makes me sorely unqualified to talk about this section. Nevertheless, here is an &lt;a href="http://blog.millermedeiros.com/solid-css/" rel="noopener noreferrer"&gt;article you can refer to regarding LSP in CSS&lt;/a&gt; if you aren't yet convinced about only using composition.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interface Segregation Principle in CSS
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Interface Segregation Principle (ISP) states that no client should be forced to depend on methods it does not use&lt;/strong&gt;. In terms of CSS, it can be easily rephrased to say that every block of CSS rule you write should not override any rules being composed.&lt;/p&gt;

&lt;p&gt;Similar to previous examples, let's start with the base &lt;code&gt;.base-btn&lt;/code&gt; class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.base-btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="no"&gt;cyan&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, remember in the OCP discussion, we raised the possibility of overriding the base styles? Let's try that to style a button using &lt;code&gt;base-btn&lt;/code&gt;, but with green text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"base-btn green-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Press Me!&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
&lt;span class="nc"&gt;.base-btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="no"&gt;cyan&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.green-text&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;green&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This clearly violates ISP, because the button depends on &lt;code&gt;.base-btn&lt;/code&gt;, which has a defined rule for the text colour, but which the button &lt;em&gt;actually doesn't want&lt;/em&gt;. By adhering to SRP and defining multiple (but very specific) base classes with a single responsibility only, this violation could have been easily avoided.&lt;/p&gt;

&lt;p&gt;Again, it's a tradeoff between defining more specific base classes (high cohesion and loose coupling) versus defining one big general one (&lt;em&gt;maybe&lt;/em&gt; more code reuse). If you do find yourself constantly overriding base styles like the above example though, it is a clear indication that your &lt;a href="https://en.wikipedia.org/wiki/Interface_bloat" rel="noopener noreferrer"&gt;base classes are too fat&lt;/a&gt;, and that it's time to separate it out into more specific base classes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dependency Inversion Principle in CSS
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Dependency Inversion Principle (ISP) states that high-level modules should not depend on low-level modules, and both should depend on abstractions&lt;/strong&gt;. In the general sense, the point of adhering to ISP is to reduce coupling between modules and promote module independence.&lt;/p&gt;

&lt;p&gt;In HTML and CSS for example, it shouldn't matter to the parent &lt;code&gt;div&lt;/code&gt; container (higher-level module) how the components within it (lower-level modules) are styled, as long as it doesn't break the layout, and vice versa. With this context, the excessive use of descendent and child selectors is a sign of the violation of DIP, since the descendent element is clearly dependent on its ancestor.&lt;/p&gt;

&lt;p&gt;As such, instead of writing nested rules like &lt;code&gt;.container .panel &amp;gt; .card&lt;/code&gt; for a nested card, writing a specific class like &lt;code&gt;.first-inner-panel-card&lt;/code&gt; is preferable, because this class has a higher chance of further reuse in other parts of the HTML which doesn't have the same structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Linking it all back to Tailwind
&lt;/h2&gt;

&lt;p&gt;If you are still reading (thanks!), the conclusion for this series is obvious: linking all of what we have discussed to Tailwind. Like mentioned at the start, this paradigm is not new; one can simply look towards existing frameworks and methodologies like &lt;a href="http://oocss.org/" rel="noopener noreferrer"&gt;OOCSS&lt;/a&gt;, &lt;a href="http://getbem.com/introduction/" rel="noopener noreferrer"&gt;BEM&lt;/a&gt;, and &lt;a href="https://github.com/nemophrost/atomic-css" rel="noopener noreferrer"&gt;Atomic CSS&lt;/a&gt; for example. And looking at the reactions toward these frameworks, it is thus not surprising to find the same criticisms surrounding Tailwind.&lt;/p&gt;

&lt;p&gt;The truth is, adhering to any framework (or to the principles discussed here) is a legitimate overhead, and one which demands developers to bear the upfront cost of. With a small project, the benefits are not immediately obvious, and may sometimes even be detrimental.&lt;/p&gt;

&lt;p&gt;If you are looking into using (or have used) Tailwind, I certainly hope you are able to spot the clear parallels between OOP concepts, SOLID principles, and Tailwind. Tailwind describes itself as a &lt;strong&gt;utility-first&lt;/strong&gt; CSS framework, which really just means that every utility class in Tailwind is designed to respect SRP, where each and every class is as independent and as loosely coupled as possible. If you look back at the last example given in the SRP section, where each class defined only has a single CSS rule and responsibility, we have essentially done up a small version of Tailwind (albeit with different class names).&lt;/p&gt;

&lt;p&gt;In other words, &lt;strong&gt;Tailwind is actually just a framework which adheres strongly to the SOLID principles&lt;/strong&gt;. Why bother coming up with your own CSS classes, trying your best to adhere to all the concepts and principles discussed here, when there is already a solid tool out there? This is &lt;strong&gt;not&lt;/strong&gt; to say that once you use Tailwind, you're on your way to cleaner CSS however; there are still plenty of ways to &lt;a href="https://tailwindcss.com/docs/extracting-components#keeping-things-composable" rel="noopener noreferrer"&gt;mess it up&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  So why the controversy?
&lt;/h2&gt;

&lt;p&gt;As a Computer Science student, Tailwind clicked almost immediately for me, but it wasn't until recently that I found the link between Tailwind and OOP/SOLID. I've found that using Tailwind made my CSS much more maintainable, and for someone who didn't really like writing CSS, Tailwind actually made it &lt;em&gt;enjoyable&lt;/em&gt;. So why is it that some people just really dislike it?&lt;/p&gt;

&lt;p&gt;If I had to guess, I would say that the people most likely to write CSS are designers (or bootcamps graduates), and not necessarily programmers who are classically trained in Computer Science. Nothing against these people, but it is arguably difficult to understand OOP (we were all there once!) while adhering to the principles stated here. One reason, already discussed greatly by others, is that for someone writing CSS "their way" for all their lives, it takes a lot for them to break their habit and adopt a totally new framework. However, I would argue that if the framework is good enough (which in my opinion, Tailwind is), then there is no reason why someone would not want to change.&lt;/p&gt;

&lt;p&gt;My theory is that those who dislike Tailwind are in one of these two groups:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Those who cannot yet relate Tailwind to the OOP concepts and SOLID principles discussed in this article, and thus doesn't understand the benefits of Tailwind&lt;/li&gt;
&lt;li&gt;Those who can relate, but simply dislike the OOP way of doing things&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you are in the second group, then it explains why Tailwind is so controversial: because &lt;a href="https://www.google.com/search?q=is+oop+bad" rel="noopener noreferrer"&gt;OOP itself is controversial&lt;/a&gt;. If you are in the first group, even though I didn't even touch on how to use Tailwind, hopefully this series has given you a deeper understanding of &lt;em&gt;how&lt;/em&gt; and &lt;em&gt;why&lt;/em&gt; Tailwind works in principle. So go ahead, try it out!&lt;/p&gt;

&lt;h2&gt;
  
  
  Further reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blog.millermedeiros.com/solid-css/" rel="noopener noreferrer"&gt;SOLID CSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://vanseodesign.com/web-design/solid-oo-principles-2/" rel="noopener noreferrer"&gt;SOLID Object Oriented Principles And CSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://frontstuff.io/should-you-chain-or-extend-css-classes" rel="noopener noreferrer"&gt;Should You Chain or Extend CSS Classes?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://frontstuff.io/in-defense-of-utility-first-css" rel="noopener noreferrer"&gt;In Defense of Utility-First CSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://uxengineer.com/css-specificity-avoid-important-css/" rel="noopener noreferrer"&gt;CSS &lt;code&gt;!important&lt;/code&gt;: Don’t Use It. Do This Instead&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tailwindcss.com/docs/utility-first" rel="noopener noreferrer"&gt;Tailwind: Utility-First&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.decaf.de/2015/06/24/why-bem-in-a-nutshell/" rel="noopener noreferrer"&gt;'Why BEM?' in a nutshell&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>css</category>
      <category>html</category>
      <category>oop</category>
      <category>tailwindcss</category>
    </item>
    <item>
      <title>Applying OOP concepts to CSS</title>
      <dc:creator>Aaron Choo</dc:creator>
      <pubDate>Fri, 16 Oct 2020 04:30:17 +0000</pubDate>
      <link>https://dev.to/aaroncql/applying-oop-principles-to-css-cof</link>
      <guid>https://dev.to/aaroncql/applying-oop-principles-to-css-cof</guid>
      <description>&lt;h2&gt;
  
  
  Series introduction
&lt;/h2&gt;

&lt;p&gt;Recently, &lt;a href="https://tailwindcss.com/"&gt;Tailwind&lt;/a&gt; has seen a &lt;a href="https://npm-stat.com/charts.html?package=tailwindcss"&gt;large explosion in growth&lt;/a&gt;: going from 390,000 npm downloads in Oct 2019, up to 1.8 million downloads just last month. This unprecedented popularity comes with it the &lt;a href="https://www.quora.com/Why-is-Java-so-polarizing-Everyone-seems-to-either-love-it-or-hate-it"&gt;&lt;em&gt;Java phenomenon&lt;/em&gt;&lt;/a&gt;: deeply polarising views within the community where there are &lt;a href="https://dev.to/swyx/why-tailwind-css-2o8f"&gt;those who love it&lt;/a&gt;, and &lt;a href="https://johanronsse.be/2020/07/08/why-youll-probably-regret-using-tailwind/"&gt;those who simply hate it&lt;/a&gt; (not to forget &lt;a href="https://areknawo.com/my-mixed-feelings-about-tailwind-css/"&gt;those that can't decide&lt;/a&gt; as well).&lt;/p&gt;

&lt;p&gt;However, this series is &lt;strong&gt;not&lt;/strong&gt; going to be about whether you should or should not be using Tailwind. Rather, this first article will attempt to be an introduction to some &lt;a href="https://www.geeksforgeeks.org/object-oriented-programming-oops-concept-in-java/"&gt;OOP concepts&lt;/a&gt;, and how they can be applied to writing cleaner CSS. The next article will then dive deeper into the &lt;a href="https://en.wikipedia.org/wiki/SOLID"&gt;SOLID principles&lt;/a&gt;, and how Tailwind relates to all of these. Then, perhaps we can even rationalise why there is such a &lt;a href="https://dev.to/nickytonline/what-are-your-thoughts-on-tailwind-css-573m"&gt;large divide in the community&lt;/a&gt; regarding the use of Tailwind.&lt;/p&gt;

&lt;h2&gt;
  
  
  Object-oriented programming in CSS
&lt;/h2&gt;

&lt;p&gt;Let's start applying object-oriented programming (OOP) principles to CSS. Firstly, a disclaimer: the idea of object-oriented CSS is not new, and has been around for quite some time. However, there is a lack of articles clearly linking OOP &lt;em&gt;concepts&lt;/em&gt; to CSS. If the explanation given here confuses you, you may want to take a peak at the extensive &lt;a href="https://github.com/stubbornella/oocss/wiki"&gt;OOCSS wiki&lt;/a&gt;. Note, however, that some definitions used here may differ.&lt;/p&gt;

&lt;p&gt;Also, there are quite a few concepts related to OOP - and only a couple which can best be applied to CSS. As such, this article will only touch on the following concepts: &lt;strong&gt;encapsulation&lt;/strong&gt;, &lt;strong&gt;abstraction&lt;/strong&gt;, and &lt;strong&gt;composition&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Objects in CSS
&lt;/h3&gt;

&lt;p&gt;Firstly, let's define what an "object" is in CSS. In OOP languages like Java, it makes sense to have objects like &lt;code&gt;Car&lt;/code&gt; or &lt;code&gt;Elephant&lt;/code&gt; which clearly have well defined states and behaviours. What then, represents an object in CSS? For simplicity's sake, let's define an "object" in CSS to be synonymous with &lt;a href="https://www.w3schools.com/cssref/css_selectors.asp"&gt;selectors&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For example, here is a class selector and an id selector, both with defined styles within them, and which we can refer to as two different objects, &lt;code&gt;.object-1&lt;/code&gt; and &lt;code&gt;#object-2&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.object-1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* styles here */&lt;/span&gt;
  &lt;span class="c"&gt;/* ... */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#object-2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* styles here */&lt;/span&gt;
  &lt;span class="c"&gt;/* ... */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that &lt;strong&gt;this definition is not official&lt;/strong&gt;, and is nothing more than syntactic sugar made to drive the concept closer to OOP. With that, let's start!&lt;/p&gt;

&lt;h3&gt;
  
  
  Encapsulation in CSS
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Encapsulation is the process of grouping logically related data and operations together in an entity&lt;/strong&gt;. Basically, things which make sense to be together, ought to be together. Every block of style you write in a CSS selector (or "object" as we have defined) can essentially be taught of as a single encapsulation. Note that there are good ways to encapsulate code and bad ways to encapsulate code.&lt;/p&gt;

&lt;p&gt;As an example, let's try building a simple HTML button. This button should have a 2-pixel border that is cyan in colour, white text, and a teal background (yes, gruesome design, I know). In the CSS of the following snippet, we have a &lt;code&gt;#teal-button&lt;/code&gt; object, which is an encapsulation of the styles needed to style the button:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- HTML --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"teal-button"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Press Me!&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- CSS --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
&lt;span class="nf"&gt;#teal-button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="no"&gt;cyan&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;teal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, what happens if we want to have a similar button, except with a red background this time? Well, if we do not want to refactor our previous code, here's an easy way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"teal-button"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Press Me!&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"red-button"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Press Me!&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
&lt;span class="nf"&gt;#teal-button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="no"&gt;cyan&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;teal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#red-button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="no"&gt;cyan&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that we have redundantly duplicated portions of the CSS. Is there a need to have the same styles for &lt;code&gt;border&lt;/code&gt; and &lt;code&gt;color&lt;/code&gt; in two separate places? This is a classic example of the violation of the aptly named &lt;a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;&lt;em&gt;Don't Repeat Yourself&lt;/em&gt; (DRY) principle&lt;/a&gt;. In OOP, we would have said that the &lt;code&gt;#teal-button&lt;/code&gt; object and the &lt;code&gt;#red-button&lt;/code&gt; object have similar states which could be better &lt;strong&gt;aggregated or encapsulated into a common, shared object&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"teal-button"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"base-btn teal-bg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Press Me!&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"red-button"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"base-btn red-bg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Press Me!&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;/* contains styles common to both buttons */&lt;/span&gt;
&lt;span class="nc"&gt;.base-btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="no"&gt;cyan&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.teal-bg&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;teal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.red-bg&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As your app grows and as you add more buttons of different background colours, using the first approach means that your CSS will grow extremely fast. Refactoring will also be an absolute nightmare. For example, in the second approach, a single line of CSS has to be modified to make all buttons change their borders to green. How many lines of CSS do you need to modify in the first approach for the same effect?&lt;/p&gt;

&lt;p&gt;It is easy to reason to yourself how the second approach promotes code reusability, while reducing unnecessary code duplication. Writing less CSS comes with it two clear advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Smaller bundle size for your built website&lt;/li&gt;
&lt;li&gt;Much better developer experience (no more waddling over pages of id selectors, or changing multiple pages of CSS just to have a consistent design)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Abstractions in CSS
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Abstraction is the process of hiding the internal working of a process from its end user&lt;/strong&gt;. Do not confuse this with encapsulation, which is the act of grouping things together in an entity. Abstractions &lt;em&gt;rely&lt;/em&gt; on encapsulations: we group things together in an entity via encapsulation, and then expose that entity as an abstraction for the end user to use. This way, there is no need for the user to know &lt;em&gt;how&lt;/em&gt; the entity is implemented, only &lt;em&gt;what&lt;/em&gt; it does.&lt;/p&gt;

&lt;p&gt;In CSS, &lt;em&gt;the end user is actually yourself and your fellow developers&lt;/em&gt;. Using the same example above, we have actually practised sound abstractions by defining the &lt;code&gt;teal-bg&lt;/code&gt; and &lt;code&gt;red-bg&lt;/code&gt; classes. There is no need to look at the actual implementation of the CSS classes to know that the &lt;code&gt;teal-bg&lt;/code&gt; class is obviously applying the teal colour to the background.&lt;/p&gt;

&lt;p&gt;Similar to encapsulation, there are good and bad ways to abstract things. In the previous example, the &lt;code&gt;base-btn&lt;/code&gt; class does not immediately give us a visual understanding of how the button is implemented. Does this mean that the &lt;code&gt;base-btn&lt;/code&gt; class is bad? Well... It depends, and we shall leave this to the next article. What we do know is that the act of &lt;strong&gt;using semantic names for classes&lt;/strong&gt; is one of the ways abstractions can be effectively used in CSS.&lt;/p&gt;

&lt;p&gt;Ok, you might be asking, &lt;em&gt;but what is the point&lt;/em&gt;? Let's have another example, where we want to make a button, and a paragraph, both with blue texts. If you have been paying attention to the previous section, we now know that we should avoid repeating the same code via encapsulation. As such, we can come up with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- HTML --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"blue-text-button"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Press Me!&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"blue-text-button"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Here is some text...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- CSS --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
&lt;span class="nc"&gt;.blue-text-button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yes, this fits the design specifications perfectly fine, and we have also managed to not repeat ourselves. But the issue with this is that the HTML/CSS has lost their semantic meaning. Without looking at how the CSS is implemented, do you know what exactly the &lt;code&gt;blue-text-button&lt;/code&gt; class does? Should the &lt;code&gt;button&lt;/code&gt; word be part of &lt;code&gt;blue-text-button&lt;/code&gt; if it does not even style a single part of the button? More importantly, why does the &lt;code&gt;p&lt;/code&gt; tag, which clearly isn't a button, depend on the CSS class whose name has &lt;code&gt;button&lt;/code&gt; in it?&lt;/p&gt;

&lt;p&gt;In order to let your fellow developer (or yourself in the future) understand immediately what you are trying to achieve, a better approach will be to rename the &lt;code&gt;blue-text-button&lt;/code&gt; class to &lt;code&gt;blue-text&lt;/code&gt;. Now, with sound abstractions, it is immediately obvious what this snippet is trying to achieve, &lt;strong&gt;without even looking at the implementation of the CSS&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"blue-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Press Me!&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"blue-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Here is some text...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, one could argue that the above CSS implementation is trivial, and does not detract one from immediately understanding what &lt;code&gt;blue-text-button&lt;/code&gt; does by looking at the CSS implementation. What about this case where your website has a custom colour palette:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"custom-colour-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Press Me!&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"custom-colour-2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Here is some text...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
&lt;span class="nc"&gt;.custom-colour-text-1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#51c6e0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.custom-colour-text-2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#5be051&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even looking at the CSS implementation wouldn't save you (unless of course, you memorised the hex colours...). Assuming the colours are part of your company/brand, and which probably will not change for quite some time, a better approach would be to name the classes like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.brand-blue-text&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#51c6e0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.brand-green-text&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#5be051&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you can safely use the class &lt;code&gt;brand-blue-text&lt;/code&gt; or &lt;code&gt;brand-green-text&lt;/code&gt; anywhere in your HTML, where you and your fellow developers will immediately know that &lt;em&gt;what&lt;/em&gt; you are trying to achieve.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compositions in CSS
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Composition is the act of modelling a &lt;em&gt;has-a&lt;/em&gt; relationship between objects&lt;/strong&gt;. For example, &lt;em&gt;a car has an engine&lt;/em&gt;, and &lt;em&gt;a human being has a heart&lt;/em&gt;. Again, if you are sharp enough, the use of composition have already been demonstrated in very our first example. Instead of putting all the styles into &lt;code&gt;#teal-button&lt;/code&gt;, we have instead defined two different classes, &lt;code&gt;.base-btn&lt;/code&gt; and &lt;code&gt;.teal-bg&lt;/code&gt;, from which we then &lt;em&gt;compose&lt;/em&gt; together to make the original style of &lt;code&gt;#teal-button&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The whole idea of composition is to reuse existing code, reduce unnecessary code duplication, and to design cleaner CSS (basically the whole point of this series if you haven't got the memo yet). Let's reuse our first example again, except with one more green coloured button this time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"teal-button"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"base-btn teal-bg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Press Me!&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"red-button"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"base-btn red-bg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Press Me!&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"green-button"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"base-btn green-bg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Press Me!&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
&lt;span class="nc"&gt;.base-btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="no"&gt;cyan&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.teal-bg&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;teal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.red-bg&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.green-bg&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;green&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, say for instance we want to add a 8px padding around the teal and red buttons only (ie. the green button should stay as is), what would be the best way to do this?&lt;/p&gt;

&lt;p&gt;As our first try, we could define this padding within &lt;code&gt;.teal-bg&lt;/code&gt; and &lt;code&gt;red-bg&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.teal-bg&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;teal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.red-bg&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, this violates what we've learnt in &lt;em&gt;abstractions&lt;/em&gt;: it's utterly confusing for the class &lt;code&gt;teal-bg&lt;/code&gt; to also apply padding when the name of the class clearly has no mention of padding in it. To remedy this, we could rename the classes, which would then require us to refactor all the instances in which the original &lt;code&gt;teal-bg&lt;/code&gt;/&lt;code&gt;red-bg&lt;/code&gt; has been referenced - not ideal.&lt;/p&gt;

&lt;p&gt;For our second try, we can instead put the padding style in &lt;code&gt;base-btn&lt;/code&gt;, which would require an &lt;code&gt;!important&lt;/code&gt; in &lt;code&gt;.green-bg&lt;/code&gt; to override the padding (remember that the green button also takes &lt;code&gt;.base-btn&lt;/code&gt; as a class):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.base-btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="no"&gt;cyan&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.teal-bg&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;teal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.red-bg&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.green-bg&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;green&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, however, we've made our CSS really fragile and dangerous. For a component with a defined padding, applying &lt;code&gt;green-bg&lt;/code&gt; to it will lead to that component losing its defined padding - not ideal.&lt;/p&gt;

&lt;p&gt;The better approach is to define a class just for the padding, which we can then &lt;em&gt;compose&lt;/em&gt; with the teal and red buttons like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"teal-button"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"base-btn teal-bg padding-8px"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Press Me!&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"red-button"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"base-btn red-bg padding-8px"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Press Me!&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"green-button"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"base-btn green-bg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Press Me!&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
&lt;span class="nc"&gt;.base-btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="no"&gt;cyan&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.teal-bg&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;teal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.red-bg&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.green-bg&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;green&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.padding-8px&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, this looks much better! We have encapsulated the common padding style into a single class, and abstracted it such that the class name &lt;code&gt;padding-8px&lt;/code&gt; makes sense. By not modifying the other existing classes, we have further reduced the risk of breaking anything which relies on them. Notice also, that by reading the HTML only (without reading the CSS), we can still visualise roughly how the end product looks like.&lt;/p&gt;

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

&lt;p&gt;That's it, now you're on you way to writing cleaner CSS! We have only just scratched the surface here regarding OOP and object-oriented CSS. In the next article, we shall dive more deeply into exactly why some of the negative examples shown here are &lt;em&gt;bad&lt;/em&gt;, and actually start looking at Tailwind and the SOLID principles.&lt;/p&gt;

</description>
      <category>css</category>
      <category>html</category>
      <category>oop</category>
      <category>tailwindcss</category>
    </item>
    <item>
      <title>Display LaTeX Math in GitHub Markdown Previews</title>
      <dc:creator>Aaron Choo</dc:creator>
      <pubDate>Sun, 16 Aug 2020 13:43:28 +0000</pubDate>
      <link>https://dev.to/aaroncql/display-latex-math-in-github-markdown-previews-2988</link>
      <guid>https://dev.to/aaroncql/display-latex-math-in-github-markdown-previews-2988</guid>
      <description>&lt;p&gt;&lt;strong&gt;TLDR&lt;/strong&gt;: install the &lt;a href="https://chrome.google.com/webstore/detail/github-math-display/cgolaobglebjonjiblcjagnpmdmlgmda"&gt;Chrome extension&lt;/a&gt;, or check out the MIT licensed repo: &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/AaronCQL"&gt;
        AaronCQL
      &lt;/a&gt; / &lt;a href="https://github.com/AaronCQL/katex-github-chrome-extension"&gt;
        katex-github-chrome-extension
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A chrome extension to display LaTeX flavoured math in GitHub Markdown previews.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


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

&lt;p&gt;As a computer science student, I primarily take my course notes in Markdown, which would eventually be pushed to GitHub. However, it's 2020 and GitHub still &lt;a href="https://github.community/t/feature-request-latex-math-in-markdown/14214"&gt;does not support 

&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;LaTeX\LaTeX&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord textrm"&gt;L&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord textrm mtight sizing reset-size6 size3"&gt;A&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord textrm"&gt;T&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord textrm"&gt;E&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord textrm"&gt;X&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 flavoured math&lt;/a&gt; when previewing Markdown content (GitHub please...).&lt;/p&gt;

&lt;p&gt;There is already an &lt;a href="https://chrome.google.com/webstore/detail/mathjax-plugin-for-github/ioemnmodlmafdkllaclgeombjnmnbima?hl=en"&gt;existing Chrome extension&lt;/a&gt; for this exact use case. However, I was unable to load the package via the Chrome store for some reason, and had to load the raw package from the GitHub source.&lt;/p&gt;

&lt;p&gt;Initially, I was happy with it, but I soon felt that the rendering becomes really sluggish when the Markdown file grows sufficiently large (probably because it uses MathJax internally). Moreover, GitHub recently revamped their website, and it now behaves more like a SPA. This means that some internal navigation in the loaded web page does not refresh the whole page, resulting in the extension failing to render the math.&lt;/p&gt;

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

&lt;p&gt;This new extension serves to solve the above problems. It uses 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;KaTeX\KaTeX&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord textrm"&gt;K&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord textrm mtight sizing reset-size6 size3"&gt;A&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord textrm"&gt;T&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord textrm"&gt;E&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord textrm"&gt;X&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 internally for fast and efficient rendering. It is also able to detect and work with the SPA-like internal navigation, and will even render the math when editing Markdown content (when clicking &lt;code&gt;Preview changes&lt;/code&gt;). For now, it only targets Markdown previews, leaving code blocks and code previews untouched (since this is my exact use case).&lt;/p&gt;

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

&lt;p&gt;This project is relatively new - if you happen to find any bugs, feel free to open an issue. I have already documented some &lt;a href="https://github.com/AaronCQL/katex-github-chrome-extension#known-issues"&gt;known issues&lt;/a&gt; which I do not yet have answers for (if you happen to have a solution, &lt;strong&gt;please open a PR&lt;/strong&gt; 😁).&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>webdev</category>
      <category>github</category>
    </item>
    <item>
      <title>Is Vue 3 Composition API Worth It?</title>
      <dc:creator>Aaron Choo</dc:creator>
      <pubDate>Mon, 22 Jun 2020 14:04:55 +0000</pubDate>
      <link>https://dev.to/aaroncql/is-vue-3-composition-api-worth-it-2chb</link>
      <guid>https://dev.to/aaroncql/is-vue-3-composition-api-worth-it-2chb</guid>
      <description>&lt;p&gt;&lt;strong&gt;The short answer is "yes"&lt;/strong&gt;. But I suspect that you are going to need more than a random stranger telling you a one word answer.&lt;/p&gt;

&lt;p&gt;There has already been numerous posts and articles talking about the advantages that the Composition API has over the Options API. From the &lt;a href="https://composition-api.vuejs.org/#motivation"&gt;official RFC&lt;/a&gt; to this &lt;a href="https://dev.to/danielelkington/vue-s-darkest-day-3fgh"&gt;particular DEV post&lt;/a&gt; which also discussed about the controversy behind the Composition API when it was first introduced back in 2019.&lt;/p&gt;

&lt;p&gt;I am not, however, going to repeat the points about code reusability, or code organisation (both of which have already been discussed in great lengths in the above links). In this article, I am going to focus more on the development experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problems with Options API
&lt;/h2&gt;

&lt;p&gt;As someone who also develops in React, I definitely agree that Vue's Options API is much more intuitive and much easier to grasp for a beginner. I mean, &lt;code&gt;data&lt;/code&gt; for your reactive data, &lt;code&gt;computed&lt;/code&gt; for data that relies on &lt;code&gt;data&lt;/code&gt;, &lt;code&gt;methods&lt;/code&gt; for functions that act on &lt;code&gt;data&lt;/code&gt;: how much easier can it get? This simplicity was one of the main reason why I gave up on learning React (back when I first started!), and decided to try Vue, and the rest is history.&lt;/p&gt;

&lt;p&gt;However, as we all know, the Options API forces us to use the &lt;code&gt;this&lt;/code&gt; keyword, and prepending everything with the &lt;code&gt;this&lt;/code&gt; keyword leads to various caveats and problems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Poor Type Inference
&lt;/h3&gt;

&lt;p&gt;Firstly, the IDE (or at least VSC, in my case, which is my daily driver) is unable to infer the type of the variable declared. Take for example, this simple case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;twiceArr&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; 
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;While writing the &lt;code&gt;twiceArr&lt;/code&gt; computed property, the lack of type inference means that the IDE is unable to bring up suggestions for array methods when you are typing &lt;code&gt;this.arr&lt;/code&gt;. Moreover, say a few weeks from now, and somebody decides to change the data &lt;code&gt;arr&lt;/code&gt; from an array to an object like &lt;code&gt;{}&lt;/code&gt;. This means that &lt;code&gt;this.arr.map()&lt;/code&gt; will throw a runtime error (since objects do not have the &lt;code&gt;map&lt;/code&gt; method). Ideally, the IDE should warn about this illegal statement, &lt;em&gt;except that it cannot&lt;/em&gt;, because it is unable to infer the type of the data &lt;code&gt;arr&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Of course, this may sound more like a minor nuisance than an actual problem. However, when your app grows big (which it will!), and when different developers come into the same project, it will really stymie development speed and add on to the confusion.&lt;/p&gt;

&lt;h3&gt;
  
  
  Really Weird Bugs
&lt;/h3&gt;

&lt;p&gt;This I am sure many Vue developers have experienced before. Knowing the difference between a normal function &lt;code&gt;function() {}&lt;/code&gt; and an arrow function &lt;code&gt;() =&amp;gt; {}&lt;/code&gt; and how Vue binds the &lt;code&gt;this&lt;/code&gt; keyword differently in them is &lt;em&gt;not&lt;/em&gt; something I would exactly call beginner friendly. Stackoverflow for instance has more than a few questions asking for this exact same problem (&lt;a href="https://stackoverflow.com/questions/42971081/use-arrow-function-in-vue-computed-does-not-work"&gt;1&lt;/a&gt;, &lt;a href="https://stackoverflow.com/questions/44915753/es6-arrow-function-this-puzzle-in-vue-js-official-github-example"&gt;2&lt;/a&gt;, &lt;a href="https://stackoverflow.com/questions/58951720/how-can-i-implement-arrow-function-in-vuejs"&gt;3&lt;/a&gt; to name a few).&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="c1"&gt;// arrow function =(&lt;/span&gt;
  &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Timmy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;userCopy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="c1"&gt;// undefined!&lt;/span&gt;
&lt;span class="p"&gt;}),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I remember in my first few months of learning Vue, I made the mistake of writing my &lt;code&gt;data&lt;/code&gt; with an arrow function like the above, and pulling my hair out, because I cannot figure out why &lt;code&gt;userCopy&lt;/code&gt; was returning &lt;code&gt;undefined&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;Yes, to somebody more experienced, these &lt;em&gt;are not weird bugs and are well documented features&lt;/em&gt; when you actually learn about how Vue works under the hood. However, you do not really expect a beginner to learn how the framework works when he is just starting out.&lt;/p&gt;

&lt;h3&gt;
  
  
  Difficult to Collaborate
&lt;/h3&gt;

&lt;p&gt;Which leads me to my last point: collaboration is rather cumbersome. Type inference, type checking, and static code analysis are one of those few things that you only notice when you suddenly have to deal with their absence. If you are not yet a TypeScript convert (or have otherwise not used a statically typed language before), this point might sound foreign to you.&lt;/p&gt;

&lt;p&gt;Even so, I believe that anybody who has worked with a non-trivial project with a significantly large codebase (upwards of 10K LOCs) would experience the pain of working with one. Do you often find yourself taking much longer than usual trying to understand and trace the SFC code not authored by you (or which you have written a while ago)? Jumping within the &lt;code&gt;data&lt;/code&gt; to the &lt;code&gt;methods&lt;/code&gt; section, to the lifecycle hooks and to the actual template before forgetting what the relevant function defined in &lt;code&gt;methods&lt;/code&gt; did?&lt;/p&gt;

&lt;p&gt;OK, I did mention that I was not going to talk about code organisation. But the point remains: with better type inference and static analysis, it would make collaboration and understanding the code much easier, especially when you have confidence in the types that you are using and/or returning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of Composition API
&lt;/h2&gt;

&lt;p&gt;If you did not know already, &lt;strong&gt;Vue 3 itself was rewritten with TypeScript&lt;/strong&gt;. Watch &lt;a href="https://www.youtube.com/watch?v=WLpLYhnGqPA"&gt;this great talk&lt;/a&gt; by Evan You about the design considerations with Vue 3, and why the team have decided to go with TypeScript.&lt;/p&gt;

&lt;p&gt;The short summary is: Vue 3, together with the Composition API, solves all of the pain points mentioned earlier, and helps make your developement experience much better. For example. in the &lt;code&gt;setup&lt;/code&gt; of the Composition API, the improved type inference means that you get much better IntelliSense within VSC, and have actually useful suggestions which pertain to the &lt;code&gt;string&lt;/code&gt; type:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QPofDZTe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7q5shmokvgh780jnkquk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QPofDZTe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7q5shmokvgh780jnkquk.png" alt="Composition API IDE Screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Look, arrow functions too! The blasphemy!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Note that you &lt;strong&gt;do not have to be using TypeScript&lt;/strong&gt; in your Vue 3 projects to benefit from any of this. And if you do want to try out TypeScript, simply change the script tag to &lt;code&gt;&amp;lt;script lang="ts"&amp;gt;&lt;/code&gt; so that your IDE knows to lint the code as TypeScript. And voila! It is that simple. Unlike Vue 2,  there is no need to learn another &lt;a href="https://vuejs.org/v2/guide/typescript.html#Class-Style-Vue-Components"&gt;Class Based API&lt;/a&gt; just to get &lt;a href="https://composition-api.vuejs.org/#type-issues-with-class-api"&gt;marginally better TypeScript support&lt;/a&gt;. This native TypeScript support is the one change that I am most excited about in Vue 3.&lt;/p&gt;

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

&lt;p&gt;The question remains: is learning or using the Composition API worth it? Even though the Options API &lt;a href="https://composition-api.vuejs.org/#adoption-strategy"&gt;will not be deprecated in Vue 3&lt;/a&gt; and can be used together within the same codebase?&lt;/p&gt;

&lt;p&gt;Whether to &lt;em&gt;learn&lt;/em&gt; it or not is an easy question to answer: learn it. Learning is after all, inevitable, especially in the field of web development where a new tool comes out once every few months.&lt;/p&gt;

&lt;p&gt;The question of whether to &lt;em&gt;use&lt;/em&gt; it in a production site is a little more complex. Personally, I would, from the moment Vue 3 is production ready, only write new features using the Composition API. Refactoring the "old" Options API code on the other hand, is a decision only you can make. If the feature is continuously being worked on, I would say it makes sense to refactor to the Composition API to take advantage of all the benefits mentioned earlier.&lt;/p&gt;

&lt;p&gt;But why take it from me? As of this article, &lt;a href="https://github.com/vitejs/vite"&gt;Vite&lt;/a&gt; has just released its first beta version, and apps bootstrapped with it comes with Vue 3 and all its glory out of the box (plus, the hot module reloading is amazingly fast). Try it out for yourself and let me know what you think!&lt;/p&gt;

</description>
      <category>vue</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
