<?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[Appwrite - Medium]]></title>
        <description><![CDATA[Appwrite blog - Medium]]></description>
        <link>https://medium.com/appwrite-io?source=rss----aeb817f12ad4---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>Appwrite - Medium</title>
            <link>https://medium.com/appwrite-io?source=rss----aeb817f12ad4---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 10 Apr 2026 18:32:06 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/appwrite-io" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Accessibility in Pink Design]]></title>
            <link>https://medium.com/appwrite-io/accessibility-in-pink-design-172aa8f214f9?source=rss----aeb817f12ad4---4</link>
            <guid isPermaLink="false">https://medium.com/p/172aa8f214f9</guid>
            <category><![CDATA[community]]></category>
            <category><![CDATA[accessibility]]></category>
            <category><![CDATA[open-source]]></category>
            <category><![CDATA[design-systems]]></category>
            <dc:creator><![CDATA[Chen]]></dc:creator>
            <pubDate>Wed, 08 Feb 2023 10:11:03 GMT</pubDate>
            <atom:updated>2023-02-08T10:11:03.081Z</atom:updated>
            <content:encoded><![CDATA[<h4>How Pink Design helped us improve web accessibility in our products</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jx43VjxGm0n9Lus7Dq9Ugg.png" /></figure><p>When creating products, accessibility can be an afterthought. Understandably, we want to ship our products fast and deliver value to our users. We might think that accessibility is needed for edge cases and therefore not prioritize it. It’s good to be reminded that <a href="https://www.who.int/news-room/fact-sheets/detail/disability-and-health#:~:text=An%20estimated%201.3%20billion%20people%20%E2%80%93%20or%2016%25%20of%20the%20global,diseases%20and%20people%20living%20longer.">the World Health Organization (WHO)</a> estimates that 16% of the global population has some form of disability (Dec 2022).<br>Ignoring such a significant part of your user base simply doesn’t create a good user experience.<br>Creating accessible products is everyone’s responsibility. Designers, developers, content authors, and whoever else is involved in creating products should do their part and strive towards achieving a better experience for everyone.</p><p>It’s not always easy to maintain a high level of accessibility, but it’s definitely easier with a design system. The components we created in Pink Design, Appwrite’s fully open source UI library, have an accessibility level of AA. This is the recommended level of accessibility for most products.</p><p>To ensure our products will maintain a high accessibility level, we did the following:</p><p><strong>Use high color contrast</strong></p><p>Color contrast might be the first thing that comes to mind when thinking about accessibility. A lack of contrast between the text and background might mean some people would be unable or have difficulty reading the text. Similarly, bright colors with high luminance are not readable for others. W3C recommends a contrast ratio between text and background of 4.5 to 1 for conformance level AA.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ryM4Fg9tcoCPPT1iAjd1yA.png" /><figcaption>Contrast ratio in Pink Design’s modal component</figcaption></figure><p><strong>Not relying on color</strong></p><p>The term “color blindness” is often used to describe people who have trouble identifying and distinguishing between certain colors, but color blindness, the inability to see any color, is extremely rare. According to <a href="https://www.nhs.uk/conditions/colour-vision-deficiency/">the United Kingdom National Health Service (NHS)</a>, red-green color blindness affects 1 out of 12 men and 1 out of 200 women. People with this color vision deficiency may have difficulty differentiating between reds, oranges, yellows, browns, and greens. They also might find it hard to distinguish between shades of purple and may confuse red with black. <br>Similarly, people with “blue-yellow” color vision deficiency may have difficulty differentiating between blues, greens, and yellows.</p><p>We use four system colors in Pink Design — red, orange, green, and blue. Each of these colors represents a state in the Appwrite console — red indicates an error or danger, orange indicates a warning, green indicates success, and blue indicates information. Knowing the difficulties our users might face while seeing these colors, we don’t rely on color to make critical information understandable.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*y8_t-Hks_O_YgHtk8bvy3A.png" /><figcaption>Pink Design’s inline alerts as seen by normal vision vs. Protanopia (blindness to red)</figcaption></figure><p><strong>Allow keyboard navigation</strong></p><p>People with fine motor control restrictions or disabled hands or arms will be unable to use a mouse. In Pink Design, we provide distinct states for interactive elements. By designing states like focus, hover, and active, we provide the ability to navigate all interactive elements with a keyboard. This is not only an accessible experience but also a better experience for all users who prefer keyboard navigation, including Appwrite’s developer community.</p><p>It is possible to enhance accessibility through development as well. In collaboration with our engineering team, we decided to incorporate the following into Pink Design:</p><p><strong>Define font size in REM</strong></p><p>Browsers have a default font size that users can change via the browser setting. A pixel is an absolute unit for fixed sizes and spaces that ignores browser settings. This means that if we are using pixels and a user (with or without vision impairment) changes the font size in their browser settings, their setting won’t affect our product. That being said, pixels should not cause any problems if the user zooms in, but we make no assumptions about users’ preferences. This is why we decided to define the font size in REM, which is a relative unit.</p><p><strong>Allow users to reduce motion</strong></p><p>There is no doubt that animations are a nice addition to every product, but animations can also distract people. In some cases, animations can cause dizziness, vertigo, or epileptic seizures. Users that are sensitive to motion might choose to reduce motion in their operating system settings. In this case, we should skip the animation for them. In Pink Design, we decided to create a big animation to show the functionality of the library on the landing page. The animation is 10 seconds long and is the first thing you see on the page. It starts immediately when the page is loaded, but if “reduce motion” is enabled in the operating system, the animation skips to the end.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CCtloAxP7b8WY08fIpFGEQ.png" /><figcaption>Reduce motion on macOS</figcaption></figure><p>At Appwrite, accessibility is for sure a team effort. We are all working to maintain and improve the accessible experience in our products, and it’s always in our minds. Using accessible components help us improve our accessibility level, but it’s important to remember, there are many types of disabilities. We have worked on improving the experience for users with vision, mobility, and cognitive disabilities, and we will keep working to improve even further.</p><p>If you haven’t already, browse the 💻 <a href="https://github.com/appwrite/pink">Pink Design GitHub Repository</a> or check out our 🚀 <a href="https://pink.appwrite.io/getting-started">Getting Started Guide</a> to use Pink Design in your projects or when contributing to Appwrite.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=172aa8f214f9" width="1" height="1" alt=""><hr><p><a href="https://medium.com/appwrite-io/accessibility-in-pink-design-172aa8f214f9">Accessibility in Pink Design</a> was originally published in <a href="https://medium.com/appwrite-io">Appwrite</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Supporting CSS Multi Direction Languages in 2023]]></title>
            <link>https://medium.com/appwrite-io/supporting-css-multi-direction-languages-in-2023-ea8f1f20bb91?source=rss----aeb817f12ad4---4</link>
            <guid isPermaLink="false">https://medium.com/p/ea8f1f20bb91</guid>
            <category><![CDATA[front-end-development]]></category>
            <category><![CDATA[css]]></category>
            <category><![CDATA[design-systems]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Elad Shechter]]></dc:creator>
            <pubDate>Mon, 06 Feb 2023 12:16:54 GMT</pubDate>
            <atom:updated>2023-02-06T12:16:54.389Z</atom:updated>
            <content:encoded><![CDATA[<p>Supporting a website with the most common language directions (left-to-right and right-to-left) has historically required a lot of work.</p><p>However, in 2023, after obtaining most of the main features of CSS Logical Properties, supporting multi-direction language websites is now much easier.</p><p>Despite this, CSS Logical Properties still need to be improved and require additional solutions.</p><p>In this post, I want to examine how we solved the missing parts of supporting a multi-direction language website.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*soflr6uJiR4oWK4ANNVFFA.png" /></figure><h3>What are CSS Logical Properties?</h3><p>Currently, most websites work with fixed axes according to physical directions, such as top/right/bottom/left.</p><p>We have our old, familiar CSS Physical Properties from those physical directions, such as margin-right, padding-bottom, border-left, and so on.</p><h4>The Problem with Physical Properties</h4><p>When enabling support for a language that goes right-to-left (direction: rtl), as well as left-to-right (direction: ltr), you need to create a kind of horizontal mirror of the website.</p><p>Creating the mirror requires a different set of CSS files if using Physical Properties.</p><p><strong>Example of How a Multi-Direction Website Can Look Like:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*I7fh4iWteM__HG1JK3Rnxg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wiSjm3W5niCm2JXDYIV_rg.png" /></figure><h4>CSS Logical Directions</h4><p>This problem can be solved with CSS Logical Properties. Instead of the physical directions, we now have two axes:</p><ul><li><strong>Inline axis</strong> — this is the axis of the text.</li><li><strong>Block axis</strong> — this is the axis of the flow of the website.</li></ul><p>Each of those axes has a start and an end direction.</p><p><strong>Inline-axis:</strong><br>To describe the <strong>inline axis</strong>, we have its two directions:</p><ul><li><strong>Inline-start</strong> — describes the start of the line of text; in English, this is the <strong>left</strong>.</li><li><strong>Inline-end</strong> — describes the end of the line of text; in English, this is the <strong>right</strong>.</li></ul><p><strong>Block-axis:</strong><br>To describe the <strong>block axis</strong>, we have its two directions:</p><ul><li><strong>Block-start </strong>— describes the start of the flow of the website; in English and most languages today, this is the <strong>top</strong>.</li><li><strong>Block-end</strong> — describes the end of the flow of the website; in English, and most languages today, this is the <strong>bottom</strong>.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/958/1*2Nu6EOeXINR18eqUHJzLGQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/958/1*4K3cE7E8JQOWUR1WbxZw0Q.png" /><figcaption>From CSS Physical direction to Logical Directions</figcaption></figure><h4>CSS Logical Properties</h4><p>From these logical directions, we obtain updates for most of our physical properties, for example:</p><pre>margin-left =&gt; margin-inline-start<br>padding-top =&gt; padding-block-start<br><br>/* position properties - for example for: position: fixed; */<br><br>top =&gt; inset-block-start<br>bottom =&gt; inset-block-end<br>left =&gt; inset-inline-start<br>right =&gt; inset-inline-end </pre><p>When using the new CSS Logical Properties, the values flip according to the direction property value: ltr (left-to-right [default]) or rtl (right-to-left).</p><p><strong>Example of left-to-right:</strong></p><pre>html {<br>  direction: ltr; /* default value */<br>}<br><br>div {<br>  margin-inline-start: 20px; /* = margin-left: 20px */<br>}</pre><p><strong>Example of right-to-left:</strong></p><pre>html {<br>  direction: rtl;<br>}<br><br>div {<br>  margin-inline-start: 20px; /* = margin-right: 20px */<br>}</pre><h4>What is Top and Bottom?</h4><p>The top and bottom directions represent the <strong>block-axis</strong>, which is the main flow of the website.</p><p>Although it is not commonly used on the web, we can use the writing-mode property to affect the <strong>block-axis</strong>.</p><p><em>Note: </em>Affecting the main flow of the website is made for Far East languages such as Chinese, in which the line of the text can be written from top to bottom.</p><pre>writing-mode: horizontal-tb; /* top to bottom (default value) */<br>writing-mode: vertical-rl;   /* right to left */<br>writing-mode: vertical-lt;   /* left to right */</pre><p>Changing the writing-mode value into vertical-lr or vertical-rl values will change to flow of the website from top-to-bottom to right-to-left or left-to-right. <strong>This means that the top is not the top anymore!</strong> The <strong>scroll is now horizontal</strong> instead of vertical, and the <strong>text goes from top to bottom</strong>.</p><p><a href="https://huijing.github.io/zh-type/"><strong>Demo</strong></a> (by <a href="https://twitter.com/hj_chen">HJ Chen</a>):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*k6hLq6YmENvwyICItdzqow.png" /></figure><p>The writing-mode property is mostly unused; 99.99% of websites only work with direction set to ltr or rtl.</p><p>This also means that using the main axis/block axis properties, such as margin-block-start, does not typically affect us. However, I still prefer to use CSS Logical Properties throughout a website to be consistent.</p><h3>Are CSS Logical Properties Good Enough?</h3><p>CSS Logical Properties will do most of the job, but I encountered a few problems after using them. Let’s talk about those problems and how you can solve them.</p><h3>Transform Properties</h3><p>These days, we do most of the layout alignment with modules of CSS Flexbox and CSS Grid. However, in some cases, we want to position things via the transform property using the translateX() function, for example.</p><p>The problem with the transform property is that its axes do not work in logical directions. For example, transform: translateX(100px) will always move to the right, regardless of the direction value of the website.</p><pre>transform: translateX(100px); /* will move the element always right */</pre><h4>Solution</h4><p>If we need to translate an element based on the type of language, we need the value to change to a negative value instead of a positive value, or if it is negative, it will need to change to a positive one.</p><p>To do so, I create a CSS variable that by default has a value of 1.</p><pre>:root {<br>  --transform-direction: 1;<br>}</pre><p>I multiply this value with the translateX value using the CSS calc() function.</p><pre>transform: translateX( calc(100px * var(--transform-direction)) );</pre><p>With the default value of 1, the translation behaves the same.</p><p><strong>Support for RTL languages:<br></strong>Now, the only thing left for me to do is to change the value of the --transform-direction variable to -1.</p><p>To do so, I simply create another :root selector, which overrides only when the main &lt;html&gt; element has the native dir=”rtl” attribute on it.</p><pre>:root[dir=&quot;rtl&quot;] {<br>  --transform-direction: -1;<br>}</pre><p>This will take effect only when the &lt;html&gt; element has the dir=”rtl” attribute:</p><pre>&lt;html dir=&quot;rtl&quot;&gt;</pre><h3>Related Direction Arrows Icons</h3><p>When changing the website direction, arrows can point in the wrong direction.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/854/1*Hf3K229jYZCzRevYgcSRdw.png" /></figure><p>To solve this issue, we can again use the --transform-direction variable, but now in a slightly different way.</p><p>To flip the icon horizontally, I’m using the scaleX function of the transform property with the --transform-direction value.</p><p>Now, when the scaleX value of the transform property is equal to -1, this value will flip the arrows in the horizontal direction in their place.</p><pre>.icon-arrow-left,<br>.icon-arrow-right {<br>  transform: scaleX(var(--transform-direction));<br>}</pre><p>This opposite direction can look strange to us, but remember that this is to support right-to-left languages such as Arabic and Hebrew.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/842/1*lSAesz9d-LAD71qz7w3jnQ.png" /></figure><h3>More Things</h3><p>Some CSS Logical Properties, or more precisely, logical values, are currently not widely supported.</p><p>The float property has 2 new logical values: inline-start and inline-end. Unfortunately, for now, they are only supported in Firefox.</p><p>To solve this, I am adding two new variables that represent the start and the end of the line.</p><p>The default values, are for left-to-right languages, with the ability to override those values in case we have the dir=“rtl” attribute of the &lt;html&gt; element.</p><p><strong>CSS Code Example:</strong></p><pre>/* default - left-to-right languages */<br>:root {<br>  --start-direction: left;<br>  --end-direction: right;<br>}<br><br>/* Support for right-to-left languages */<br>:root[dir=&quot;rtl&quot;] {<br>  --start-direction: right;<br>  --end-direction: left;<br>}</pre><p>Now the only thing left for me to do is to use the variables according to my need. Example:</p><pre>float: var(--start-direction);</pre><p>Those variables can be useful in more cases, such as setting the background-position property, for example:</p><pre>background-position: var(--end-direction) top;<br>background-repeat: no-repeat;</pre><h3>CSS Variables for Help</h3><p>As we saw here, I defined three CSS variables that helped me to complete the support of CSS Logical Properties.</p><p><strong>The CSS code looks like this:</strong></p><pre>/* default - left-to-right languages */<br>:root {<br>  --transform-direction: 1;<br>  --start-direction: left;<br>  --end-direction: right;<br>}<br><br>/* Support for right-to-left languages */<br>:root[dir=&quot;rtl&quot;] {<br>  --transform-direction: -1;<br>  --start-direction: right;<br>  --end-direction: left;<br>}</pre><p>If you are using <strong>Sass preprocessor,</strong> you can write it in this way:</p><pre>:root {<br>  /* default - left-to-right languages */<br>  --transform-direction: 1;<br>  --start-direction: left;<br>  --end-direction: right;<br><br>  /* Support for right-to-left languages */<br>  &amp;[dir=&quot;rtl&quot;] {<br>    --transform-direction: -1;<br>    --start-direction: right;<br>    --end-direction: left;<br>  }<br>}</pre><h3>To Summarize</h3><p>In this post, we examined how you can support a multi-direction website.</p><p>The first step is to use native CSS Logical Properties wherever you can. The second step is to use additional CSS variables for the less supported CSS Logical Properties.</p><h3>Final Words</h3><p><a href="https://pink.appwrite.io/">Pink Design</a> is finally out today. <a href="https://pink.appwrite.io/">Pink Design</a> was built with new inventive CSS methods, and prioritizes accessibility and developer experience. As a company developing an open-source product, this is a big step for Appwrite’s community of contributors. As always, we will keep improving <a href="https://pink.appwrite.io/">Pink Design</a>, allowing it to grow alongside <a href="https://appwrite.io/">Appwrite</a>.</p><p>Thank you for being a part of our journey! If you haven’t already, browse the 💻 <a href="https://github.com/appwrite/pink">Pink Design GitHub Repository</a> or check out our 🚀 <a href="https://pink.appwrite.io/getting-started">Getting Started Guide</a> to use Pink Design in your projects or when contributing to <a href="https://appwrite.io/">Appwrite</a>.</p><p>Until next time!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ea8f1f20bb91" width="1" height="1" alt=""><hr><p><a href="https://medium.com/appwrite-io/supporting-css-multi-direction-languages-in-2023-ea8f1f20bb91">Supporting CSS Multi Direction Languages in 2023</a> was originally published in <a href="https://medium.com/appwrite-io">Appwrite</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[CSS Color Architecture]]></title>
            <link>https://medium.com/appwrite-io/css-color-architecture-ca5de26f2df7?source=rss----aeb817f12ad4---4</link>
            <guid isPermaLink="false">https://medium.com/p/ca5de26f2df7</guid>
            <category><![CDATA[front-end-development]]></category>
            <category><![CDATA[design-systems]]></category>
            <category><![CDATA[css]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[open-source]]></category>
            <dc:creator><![CDATA[Elad Shechter]]></dc:creator>
            <pubDate>Mon, 30 Jan 2023 12:50:33 GMT</pubDate>
            <atom:updated>2023-06-21T13:44:02.042Z</atom:updated>
            <content:encoded><![CDATA[<p>One of the hardest things in programming languages is organizing code in a way that will be easy to understand and maintain.</p><p>In this post, I want to explain how I work and organize the colors in our <a href="https://pink.appwrite.io/">Pink Design</a> system project.</p><p>Like everything in life, we have many good ways and even more wrong ways to do the same thing. Before I show you how I organize our CSS variables, let’s discuss the wrong ways to organize colors in CSS.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Vo-AKCnc6ZftHecEopfLfA.png" /></figure><p>Note:<em> some parts of our color architecture use </em><a href="https://sass-lang.com/"><em>Sass preprocess</em></a><em>.</em></p><h3>The Wrong Ways to Define CSS Color Variables</h3><p>When reviewing other CSS architecture, I try to think of inefficiencies that make it difficult to maintain.</p><h4>Using Globals variables for Everything Without Semantic Meaning</h4><p>I took this small example using the inspect feature from the :root element on the <a href="https://linkedin.com/">LinkedIn</a> website.</p><p>As you can see in the example below, there are more than 900 CSS variables on one :root selector!</p><p>Finding something in such an extensive list of variables is almost impossible.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KeDtXixGrU-TOCXnWaKm2w.png" /></figure><h4>Coupling Colors with Semantic Names</h4><p>The second option I frequently see is global variable color with semantic names, such as --header-background-color.</p><p>The problem with defining logical global naming, first and foremost, is that you have too many of them.</p><p>The second problem with creating dark-mode themes is that web designers do not work with the logic that specific colors need to change to other colors in dark-mode. This can cause the creation of too many types of variables that are hard to understand or maintain.</p><p><strong>Example from old Appwrite console 1.0:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*saqDL0KqGHDu8bl_QgGmeA.png" /></figure><p>Furthermore, the overrides of global colors make the code’s debugging unclear, with all the crossline of the overrides in the inspect element of Chrome.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3QR253EZlQR-AL5YRewXlA.png" /></figure><p>After understanding these issues, I thought about how to better structure our CSS color variables.</p><h3>How We Decided to Manage Our CSS Color Variables</h3><p>My main idea was to create a CSS variable for every color group family on the hue spectrum that would connect every group of colors (e.g., blue, green, orange, and red). In this way, I can change the primary hue of each color group and easily replace all shades of this color family.</p><p>The only issue I had with this approach was that the color had been defined with hex code colors, by the design team, which are a type of RGB colors and are more difficult to use when creating different shades of the same hue.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*C--2KIeO_v1PSETitPBUSw.png" /></figure><p>In this case, I chose to convert the HEX/RGB colors into HSL colors and try to find the typical hue of every group of colors.</p><h4>Converting from HEX/RGB to HSL</h4><p>If we take the information (blue) colors and convert them into HSL colors, we can see that all the hues (first value) are different; they range between 188 and 192.</p><p>The main idea was to keep the first value as another CSS variable.</p><pre>:root {<br>  --color-info-hue: /* ? */;<br><br>  --color-info-10:  189 87% 97%;  /* #F1FCFE */<br>  --color-info-50:  192 90% 89%;  /* #C8F2FC */<br>  --color-info-100: 189 100% 38%; /* #00A7C3 */<br>  --color-info-120: 190 100% 26%; /* #007187 */<br>  --color-info-200: 188 87% 12%;  /* #04333A */<br>}</pre><p>To solve this issue, I decided to use the CSS calc() function, subtracting or adding the difference to the base hue value.</p><p>I decided to take the base hue from the primary color of every family group; in our case, the primary color was the “100” color, and the hue of the info (blue) family group was 189.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*msDpmh9vhNuX1HxvVt5LQQ.png" /></figure><p><strong>The result looked like this:</strong></p><pre>:root {<br>  --color-info-hue: 189;<br><br>  --color-info-10:  var(--color-info-hue) 87% 97%;            /* #F1FCFE */<br>  --color-info-50:  calc(var(--color-info-hue) + 3) 90% 89%;  /* #C8F2FC */<br>  --color-info-100: var(--color-info-hue) 100% 38%;           /* #00A7C3 */<br>  --color-info-120: calc(var(--color-info-hue) + 1) 100% 26%; /* #007187 */<br>  --color-info-200: calc(var(--color-info-hue) - 1) 87% 12%;  /* #04333A */<br>}</pre><p>In this way, I can play with the hue and change all colors created from it.</p><h4>How to Use These Variables?</h4><p>When using the color variables, every call must be wrapped with the hsl() function. <strong>For example:</strong></p><pre>background-color: hsl( var(--color-info-100) );</pre><p>The hsl() function wasn’t added to the variable itself because I want an easy way to control the opacity of the colors if needed.</p><p><strong>Example:</strong></p><pre>background-color: hsl( var(--color-info-100) / 0.5 ); /* with 50% opacity */</pre><h3>Private Local Variable Logic</h3><p>Because we have different color modes (light/dark modes), in most cases, every partial’s color will change to another color in the second color mode.</p><p>In my method, all the colors are global, both light and dark mode colors. To manage the light and dark mode’s color, I added local color variables, which will reference global color variables according to the mode.</p><p>To not have a “mess” of too many global variables, I use the concept of private variables for each partial.</p><p>To indicate a variable is private, I start it with p-. For example:</p><pre>.partial {<br>    --p-variable-name: value;<br>}</pre><p>In our button partial, for example, I have the main private variable for the text color, background-color, and border-color.</p><pre>.button {<br>    /* Light-mode Theme */<br>    --p-text-color:   value;<br>    --p-button-color: value;<br>    --p-border-color: value;<br>}</pre><p>The usage of those variables looks like this:</p><pre>.button {<br>    color:            hsl( var(--p-text-color)   ); <br>    background-color: hsl( var(--p-button-color) );<br>    border-color:     hsl( var(--p-border-color) );<br>}</pre><p>Variables in a complex partial can have a lot of states. For example, a button can have a default, :hover, :focus, :active, or :disabled state. Those essential inner variables use other inner variables to present any state.</p><p>The code of my button variables looks like this:</p><pre>.button {<br>    /* Light Theme */<br>    --p-text-color:            var(--p-text-color-default);<br>    --p-button-color:          var(--p-button-color-default);<br>    --p-border-color:          var(--p-border-color-default);<br><br>    --p-text-color-default:    var(--color-neutral-5);<br>    --p-button-color-default:  var(--color-primary-200);<br>    --p-border-color-default:  var(--color-primary-300);<br><br>    --p-text-color-hover:      var(--p-text-color-default);<br>    --p-button-color-hover:    var(--color-primary-100);<br>    --p-border-color-hover:    var(--p-border-color-default);<br><br>    --p-text-color-focus:      var(--p-text-color-default);<br>    --p-button-color-focus:    var(--color-primary-200);<br>    --p-border-color-focus:    var(--color-primary-200);<br><br>    --p-text-color-active:     var(--p-text-color-default);<br>    --p-button-color-active:   var(--color-primary-300);<br>    --p-border-color-active:   var(--color-primary-300);<br><br>    --p-text-color-disabled:   var(--color-neutral-50);<br>    --p-button-color-disabled: var(--color-neutral-10);<br>    --p-border-color-disabled: var(--color-neutral-10);<br>}</pre><h4>Defining States of Button</h4><p>What is nice now is that I only need to update the variable’s value whenever I want to change the buttons.</p><p>These variables can, then, be applied based on the state of the partial.</p><p><strong>Basic State Definitions (written in Sass):</strong></p><pre>/* global Sass Variable */<br>$disabled: &quot;:disabled, .is-disabled&quot;;<br><br>.button {<br>    &amp;:is(:hover) {<br>        &amp;:where(:not(#{$disabled})) {<br>            --p-text-color:   var(--p-text-color-hover);<br>            --p-button-color: var(--p-button-color-hover);<br>            --p-border-color: var(--p-border-color-hover);<br>        }<br>    }<br>    &amp;:is(:focus-visible) {<br>        &amp;:where(:not(#{$disabled})) {<br>            --p-text-color:   var(--p-text-color-focus);<br>            --p-button-color: var(--p-button-color-focus);<br>            --p-border-color: var(--p-border-color-focus);<br>        }<br>    }<br>    &amp;:is(:active) {<br>        &amp;:where(:not(#{$disabled})) {<br>            --p-text-color:   var(--p-text-color-active);<br>            --p-button-color: var(--p-button-color-active);<br>            --p-border-color: var(--p-border-color-active);<br>        }<br>    }<br>    &amp;:where(#{$disabled}) {<br>            --p-text-color:   var(--p-text-color-disabled);<br>            --p-button-color: var(--p-button-color-disabled);<br>            --p-border-color: var(--p-border-color-disabled);<br>    }<br>}</pre><p>I use the Sass variable $disabled so that I can use the style of the disabled button on other elements, such as link elements.</p><p><strong>Sass Code:</strong></p><pre>/* global Sass Variable */<br>$disabled: &quot;:disabled, .is-disabled&quot;;<br><br>.button {<br>    &amp;:where(#{$disabled}) {<br>            --p-text-color:   var(--p-text-color-disabled);<br>            --p-button-color: var(--p-button-color-disabled);<br>            --p-border-color: var(--p-border-color-disabled);<br>    }<br>}</pre><p><strong>Compiled CSS:</strong></p><pre>.button:where(:disabled, .is-disabled) {<br>      --p-text-color:   var(--p-text-color-disabled);<br>      --p-button-color: var(--p-button-color-disabled);<br>      --p-border-color: var(--p-border-color-disabled);    <br>}</pre><p><strong>Will target:</strong></p><pre>&lt;button class=&quot;button&quot; disabled&gt; &lt;/button&gt;<br><br>&lt;a class=&quot;button is-disabled&quot;&gt; &lt;/a&gt;</pre><h3>Dark Mode Treatment</h3><p>After taking care of all the button light-mode states, we now want to take care of our dark-mode states.</p><p>Before doing so, I define another global Sass variable representing the dark-mode CSS class state. This state class name will be used in most of our partials to create unique colors for dark mode.</p><pre>$theme-dark: &quot;.theme-dark&quot;;</pre><p>The .theme-dark class is better defined directly on the &lt;html&gt; element, of course, only when you use the dark-mode state.</p><p>If defining it on the &lt;html&gt; element is an issue, it can be defined on the &lt;body&gt; element instead.</p><pre>&lt;body class=&quot;theme-dark&quot;&gt; &lt;/body&gt;</pre><p>This is done to achieve easy global control of all the HTML elements.</p><h4>Dark-Mode Treatment Inside the Partial</h4><p>To create the definition of dark mode in the button partial, I add this code segment at the bottom of the partial:</p><pre>.button {<br>   /* regular styles and light-mode definitions */<br><br>  #{$theme-dark} &amp; { <br>         /* definitions for dark-mode */<br>     }<br>}</pre><p>This Sass code will compile to this selector:</p><pre>.button { /* regular styles and light-mode definitions */ }<br><br>.theme-dark .button { /* definitions for dark-mode */ }</pre><p>Because all the states of the buttons are already declared, the only thing left to do is to define the states’ private color variables in the dark-mode “section”.</p><p>If some colors remain the same, they do not need to be overridden in dark mode.</p><pre>.button {<br>  #{$theme-dark} &amp; { <br>        /* changed colors */<br>        --p-border-color-default:  var(--color-primary-200);<br><br>        --p-button-color-hover:    var(--color-primary-100);<br>        --p-border-color-hover:    var(--color-primary-100);<br><br>        --p-border-color-focus:    var(--color-primary-300);<br><br>        --p-border-color-active:   var(--color-primary-300);<br><br>        --p-text-color-disabled:   var(--color-neutral-100);<br>        --p-button-color-disabled: var(--color-neutral-150);<br>        --p-border-color-disabled: var(--color-neutral-150);<br>   }<br>}</pre><p>What is nice about this method is that <strong>we do not need to repeat any CSS selectors or any properties definitions</strong>.</p><h3>More Types of Buttons</h3><p>In our project, we needed to have different types of buttons.</p><p>Because we have already created a solid structure, we only need to define those variables according to the new state of the button.</p><h4>Define New State</h4><p>To define a new state, we add our new state class (.is-secondary):</p><pre>&lt;button class=&quot;button is-secondary&quot;&gt;&lt;/button&gt;</pre><p>Now, to update the colors for the new type of button, we just override the private colors:</p><pre>.button {<br>   &amp;.is-secondary {<br>        /* Light Mode */<br>        --p-text-color-default:   var(--color-neutral-100);<br>        --p-button-color-default: var(--color-neutral-5);<br>        --p-border-color-default: var(--color-neutral-30);<br><br>        --p-text-color-hover:     var(--p-text-color-default);<br>        --p-button-color-hover:   var(--color-neutral-10);<br>        --p-border-color-hover:   var(--p-border-color-default);<br><br>        --p-text-color-focus:     var(--p-text-color-default);<br>        --p-button-color-focus:   var(--p-button-color-default);<br>        --p-border-color-focus:   var(--transparent);<br><br>        --p-text-color-active:    var(--color-neutral-300);<br>        --p-button-color-active:  var(--color-neutral-30);<br>        --p-border-color-active:  var(--color-neutral-30);<br><br>        --p-text-color-disabled:   var(--color-neutral-50);<br>        --p-button-color-disabled: var(--p-button-color-default);<br>        --p-border-color-disabled: var(--color-neutral-30);<br><br>        /** Dark Mode **/<br>        #{$theme-dark} &amp; {<br>            --p-text-color-default:    var(--color-neutral-5);<br>            --p-button-color-default:  var(--color-neutral-300);<br>            --p-border-color-default:  var(--color-neutral-150);<br><br>            --p-text-color-hover:      var(--p-text-color-default);<br>            --p-button-color-hover:    var(--transparent);<br>            --p-border-color-hover:    var(--color-neutral-120);<br><br>            --p-text-color-focus:      var(--p-text-color-default);<br>            --p-button-color-focus:    var(--p-button-color-default);<br>            --p-border-color-focus:    var(--transparent);<br><br>            --p-text-color-active:     var(--p-text-color-default);<br>            --p-button-color-active:   var(--p-button-color-default);<br>            --p-border-color-active:   var(--color-neutral-100);<br><br>            --p-text-color-disabled:   var(--color-neutral-100);<br>            --p-button-color-disabled: var(--p-button-color-default);<br>            --p-border-color-disabled: var(--color-neutral-150);<br>        }<br>    }<br>}</pre><p>As you can see, I’m only defining variables here, without any properties and or any state selector pseudo-class like :hover, :focus and so on.</p><p><a href="https://codepen.io/elad2412/pen/RwBpyZg/ae478a2e98caa0990570aaf0ac7a2a52"><strong>CodePen Full Demo:</strong></a></p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Felad2412%2Fembed%2Fpreview%2Fae478a2e98caa0990570aaf0ac7a2a52%3Fdefault-tabs%3Dcss%252Cresult%26height%3D600%26host%3Dhttps%253A%252F%252Fcodepen.io%26slug-hash%3Dae478a2e98caa0990570aaf0ac7a2a52&amp;display_name=CodePen&amp;url=https%3A%2F%2Fcodepen.io%2Felad2412%2Fpen%2FRwBpyZg%2Fae478a2e98caa0990570aaf0ac7a2a52&amp;image=https%3A%2F%2Fshots.codepen.io%2Felad2412%2Fpen%2FRwBpyZg%2Fae478a2e98caa0990570aaf0ac7a2a52-512.jpg%3Fversion%3D1673428096&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/27c61262b5d2ce8de4b317790ba41d37/href">https://medium.com/media/27c61262b5d2ce8de4b317790ba41d37/href</a></iframe><p><a href="https://codepen.io/elad2412/pen/RwBpyZg/ae478a2e98caa0990570aaf0ac7a2a52">Open CodePen Demo in separate tab</a></p><h3>Global Colors State</h3><p>In most cases, we do not want to define global color variables that are updated to other colors in dark mode.</p><p>However, while this is correct for most cases, in some specific cases we will want to define a state color that looks like one specific color in light mode and another in dark mode.</p><h4>Global Logic Colors</h4><p>For that, I created another solution, which I am calling “global logic colors.”</p><p>For these, I created global CSS variables that are defined in a separate :root selector; of course, they reference other global color variables.</p><p>For dark mode, these variables are changed to another global color variable. Example:</p><pre>:root {<br>  /* Global Logic Colors - Light Mode */<br>  --color-text-info:      var(--color-info-100);<br>  --color-text-danger:    var(--color-danger-100);<br>  --color-text-warning:   var(--color-warning-100);<br>  --color-text-success:   var(--color-success-100);<br><br>  --color-border:         var(--color-neutral-10);<br>  --scroll-color:         var(--color-neutral-50);<br><br>  #{$theme-dark} {<br>    /* Global Logic Colors - Dark Mode */<br>    --color-text-info:    var(--color-info-120);<br>    --color-text-danger:  var(--color-danger-120);<br>    --color-text-warning: var(--color-warning-120);<br>    --color-text-success: var(--color-success-120);<br><br>    --color-border:       var(--color-neutral-200);<br>    --scroll-color:       var(--color-neutral-150);<br>  }<br>}</pre><p>These CSS variables are used in two ways:</p><ol><li><strong>Direct usage inside a partial</strong></li></ol><pre>.icon-checked { color: hsl( var(--color-text-success) ); }</pre><p>2. <strong>As a global utility class</strong></p><pre>/* Global Utilities colors classes */<br>.u-color-text-disabled { color: hsl( var(--color-text-disabled) ); }<br>.u-color-text-offline  { color: hsl( var(--color-text-offline)  ); }<br>.u-color-text-info     { color: hsl( var(--color-text-info).    ); }<br>.u-color-text-danger   { color: hsl( var(--color-text-danger).  ); }<br>.u-color-text-warning  { color: hsl( var(--color-text-warning). ); }<br>.u-color-text-success  { color: hsl( var(--color-text-success)  ); }</pre><p>The global utility classes can be used directly on an element and will provide different colors according to the light mode or dark mode theme.</p><p>In both ways, the colors are updated according to the state of the color mode scheme.</p><h3>To Summarize</h3><p>In this post, we discussed common ways to define CSS color variables and their problems. After that, we explored how to reorganize CSS variables using private variables to create a CSS architecture with well-organized colors.</p><h3>Final Words</h3><p><a href="https://pink.appwrite.io/">Pink Design</a> is finally out today. <a href="https://pink.appwrite.io/">Pink Design</a> was built with new inventive CSS architectures and prioritizes accessibility and developer experience. As a company developing an open-source product, this is a big step for Appwrite’s community of contributors. As always, we will keep improving <a href="https://pink.appwrite.io/">Pink Design</a>, allowing it to grow alongside <a href="https://appwrite.io/">Appwrite</a>.</p><p>Thank you for being a part of our journey! If you haven’t already, browse the 💻 <a href="https://github.com/appwrite/pink">Pink Design GitHub Repository</a> or check out our 🚀 <a href="https://pink.appwrite.io/getting-started">Getting Started Guide</a> to use Pink Design in your projects or when contributing to <a href="https://appwrite.io/">Appwrite</a>.</p><p>Until next time!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ca5de26f2df7" width="1" height="1" alt=""><hr><p><a href="https://medium.com/appwrite-io/css-color-architecture-ca5de26f2df7">CSS Color Architecture</a> was originally published in <a href="https://medium.com/appwrite-io">Appwrite</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[CSS Layers for CSS Resets]]></title>
            <link>https://medium.com/appwrite-io/css-layers-for-css-resets-f60f270aa1cd?source=rss----aeb817f12ad4---4</link>
            <guid isPermaLink="false">https://medium.com/p/f60f270aa1cd</guid>
            <category><![CDATA[front-end-development]]></category>
            <category><![CDATA[css]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[design-systems]]></category>
            <category><![CDATA[open-source]]></category>
            <dc:creator><![CDATA[Elad Shechter]]></dc:creator>
            <pubDate>Wed, 25 Jan 2023 12:37:09 GMT</pubDate>
            <atom:updated>2023-01-25T12:37:09.494Z</atom:updated>
            <content:encoded><![CDATA[<p>I have always been one of those people who preferred the aggressive CSS reset methods. These methods delete most of the default styles of the browser, such as removing the default heading style of &lt;h1&gt; to a &lt;h6&gt; elements that have a larger font-size and font-weight.</p><p>However, I also like how Normalize CSS handles shadow DOM elements, which we do not have in any of the CSS Reset methods.</p><p>Because of this, I always find methods to mix them both. Even then, however, I have had some issues with CSS specificity that I needed to find a method to workaround.</p><p>Fast forwarding to today, all browsers now support CSS Layers. Therefore, while working on <a href="https://pink.appwrite.io/">Pink Design</a>, the open source design system of <a href="https://appwrite.io/">Appwrite</a>, we started to rethink how we could handle this better.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KCZglVjugqNR-BYD_KGUyw.png" /></figure><p>Before we start, let’s talk a bit about CSS reset methods.</p><h3>CSS Reset Methods</h3><p>For many years, there was a “fight” over which method of resetting CSS was better.</p><p>In this competition, we had two familiar methods:</p><p><strong>1. Normalize CSS</strong> — a gentle approach to fix differences between browsers while keeping the native styles of HTML elements such as the heading elements of &lt;h1&gt;, &lt;h2&gt;, and so on.</p><p>As mentioned before, Normalize CSS also takes care of shadow DOM elements that sometimes look different in different browsers.</p><p><strong>Demo of treatment of shadow DOM elements in Normalize CSS:</strong></p><pre>/**<br> * 1. Correct the inability to style clickable types in iOS and Safari.<br> * 2. Change font properties to `inherit` in Safari.<br> */<br>::-webkit-file-upload-button {<br>  -webkit-appearance: button; /* 1 */<br>  font: inherit; /* 2 */<br>}</pre><p><strong>2. CSS Reset</strong> — in contrast, CSS Reset is a more aggressive method that often revokes the default style of the “user-agent stylesheet” of the browser.</p><p><strong>Demo of CSS reset</strong></p><p>This code will revoke the special font-size, font-weight and margin of the &lt;h1&gt; to a &lt;h6&gt; elements:</p><pre>h1, h2, h3, h4, h5, h6 {<br>  margin: 0;<br>  font-size: inherit; <br>  font-weight: inherit;<br>}</pre><h3>Combining Methods</h3><p>By combining both methods, Normalize CSS and CSS Reset, you can profit from both approaches.</p><p>This ensures that both inner shadow DOM elements are taken care of, and unhelpful styles inherited from the “user-agent stylesheet” are being ignored.</p><p>The easiest way to accomplish this is by loading both. Demo of how to implement in Sass preprocessor:</p><pre>/* CSS Resets */<br>@use &#39;normalize&#39;;<br>@use &#39;reset&#39;;</pre><p>You would think that if we first load Normalize CSS and then CSS Reset, this would make our CSS Reset have a stronger Specificity, right? Not precisely; let’s talk about some issues with this.</p><h3>Issues with Combining Methods</h3><p>In Appwrite Pink, we use Normalize CSS while combining it with ‘<a href="https://elad2412.github.io/the-new-css-reset/">The New CSS Reset</a>’. ‘The New CSS Reset’ is a new method of resetting CSS that uses the new native CSS reset features.</p><p>For both projects of “<a href="https://necolas.github.io/normalize.css/">Normalize CSS</a>” &amp; “<a href="https://elad2412.github.io/the-new-css-reset/">The New CSS Reset</a>”, we take them as is, without any changes (from <a href="https://npmjs.com/">NPM</a>), even the unnecessary parts from Normalize CSS, like fixing the different style of the &lt;h1&gt; element that will be removed with the CSS Reset.</p><p><strong>Header </strong><strong>&lt;h1&gt; style in “Normalize CSS”:</strong></p><pre>/**<br> * Correct the font size and margin on `h1` elements within `section` and<br> * `article` contexts in Chrome, Firefox, and Safari.<br> */<br><br>h1 {<br>  font-size: 2em;<br>  margin: 0.67em 0;<br>}</pre><p><strong>General remove style in “The New CSS Reset” (includes </strong><strong>&lt;h1&gt; elements):</strong></p><pre>/*<br>    Remove all the styles of the &quot;User-Agent-Stylesheet&quot;, <br>    except for the &#39;display&#39; property.<br>    - The &quot;symbol *&quot; part is to solve Firefox SVG sprite bug<br> */<br>*:where(:not(html, iframe, canvas, img, svg, video, audio):not(svg *, symbol *)) {<br>    all: unset;<br>    display: revert;<br>}</pre><p>But here start our problems. To understand the problems, let&#39;s talk about basic CSS which defines our styles:</p><h4>Order D<strong>oes</strong> Matter</h4><p>The order of the CSS selectors is important. This is because, usually, what is coming last is stronger than what is coming first. In our case, the order of our CSS Resets files is correct.</p><p>First, we want to load the “Normalize CSS”, which will normalize our differences between different browsers, and then we want to remove what we don’t need with a CSS reset, in our case, which is done with “The New CSS Reset”.</p><p><strong>Example of imports in Scss:</strong></p><pre>/* CSS Resets files order */<br>@use &#39;normalize&#39;; /* 1 */<br>@use &#39;reset&#39;;     /* 2 */<br>/* In general, last code is stronger in CSS */</pre><h4>CSS Specificity</h4><p>We have the strength of our selectors defined according to the CSS selector strength (elements, class names, and ID names). From weakest to strongest selectors, we have the element, class, and ID selectors.</p><p><strong>Example:</strong></p><p>In this example, the selector of the ID will win the “CSS Specificity War”, because the ID selector is stronger than the selector of a class name or an element.</p><p>This means that the color of the &lt;h1&gt; element, in this case, will be pink.</p><pre>&lt;h1 class=&quot;title&quot; id=&quot;mainTitle&quot;&gt;some content&lt;/h1&gt;</pre><pre>#mainTitle { color:pink;   } /* 1 (ID), 0 (Classes), 0(element) */<br>.title     { color:yellow; } /* 0 (ID), 1 (Classes), 0(element) */<br>h1         { color:red;    } /* 0 (ID), 0 (Classes), 1(element) */</pre><h4>Our CSS Specificity Conflict</h4><p>If we take a look at Normalize CSS selector of &lt;h1&gt; elements, it has the power of one element:</p><pre>/* 0 (ID), 0 (Classes), 1 (element) */<br>h1 {...}</pre><p>This is a relatively low-strength selector.</p><p>Let’s have a look at the main CSS Reset selector from “The New CSS Reset” method:</p><pre>/* 0 (ID), 0 (Classes), 0 (element) */<br>*:where(:not(html, iframe, canvas, img, svg, video, audio):not(svg *, symbol *)) {...}</pre><p>To make it with the lowest specificity possible, the :where() pseudo selector is used. One of the main ideas of the :where() pseudo selector is to remove any CSS specificity created by the selector.</p><p>But here comes the conflict, the style of the &lt;h1&gt; is stronger than the style of the CSS Reset, and this is an issue for us because we want the CSS Reset to overcome the Normalize CSS.</p><p>One way to solve this conflict is to remove the unnecessary parts of Normalize CSS, which means removing all the un shadow DOM parts style. But this can be an issue if we load the project automatically from an NPM package, which is complex to maintain.</p><h3>CSS Layers to the Rescue</h3><p>CSS layers were invented to solve cases like this, where we want to tell the browsers that a specific layer is more important than others, and ignore the CSS specificity of another layer.</p><p>To do so, we have the @layer rule, which defines a layer. This will wrap part of the styles, define the parts of the layer, and enact out the CSS specificity only inside the layer itself.</p><pre>@layer normalize {<br>  /* CSS Normalize Here */<br>}<br>@layer the-new-css-reset {<br>  /* CSS Reset here */<br>}</pre><p>This in itself will solve our issue.</p><p>To be more precise in defining the order of the layer, we can add the “layer statement” that will determine the order you want the code to appear.</p><p><strong>Example:</strong></p><pre>/* layer statement - define the order, <br>   even if the order of the code will not be in the same way */<br>@layer normalize, the-new-css-reset;<br><br>@layer normalize {<br>  /* CSS Normalize Here */<br>}<br>@layer the-new-css-reset {<br>  /* CSS Reset here */<br>}</pre><p><strong>CodePen Demo:</strong></p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Felad2412%2Fembed%2Fpreview%2F289ca1b328f93a24e1e1df8ae276a916%3Fdefault-tabs%3Dcss%252Cresult%26height%3D600%26host%3Dhttps%253A%252F%252Fcodepen.io%26slug-hash%3D289ca1b328f93a24e1e1df8ae276a916&amp;display_name=CodePen&amp;url=https%3A%2F%2Fcodepen.io%2Felad2412%2Fpen%2FYzjVPpW%2F289ca1b328f93a24e1e1df8ae276a916&amp;image=https%3A%2F%2Fshots.codepen.io%2Felad2412%2Fpen%2FYzjVPpW%2F289ca1b328f93a24e1e1df8ae276a916-512.jpg%3Fversion%3D1673429149&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/2a6db95ad29f0293f4a0faf5eac0428a/href">https://medium.com/media/2a6db95ad29f0293f4a0faf5eac0428a/href</a></iframe><h4>Sass Preprocessor Support</h4><p>To keep the separation of files while using Sass, we will need to add some adjustments to our Sass code.</p><pre>@use &#39;sass:meta&#39;;<br><br>@layer normalize, the-new-css-reset;<br><br>@layer normalize {<br>  @include meta.load-css(&#39;normalize&#39;);<br>}<br>@layer the-new-css-reset {<br>  @include meta.load-css(&#39;the-new-css-reset&#39;);<br>}</pre><p>This way, we can keep our CSS layers separate in separate files and ensure that the last layers will win the “cascade war” while keeping our code well organized.</p><h3>Browser Support</h3><p>CSS layers have already been implemented in all evergreen browsers for quite a while. In iOS, the functionality exists from version 15.4, which at the time of writing this post, we are currently on version 16.3.</p><h3>To Summarize</h3><p>This post covered how we can solve CSS specificity issues, specifically on CSS reset layers.</p><p>This method of using CSS layers to solve CSS conflicts will be more commonly used as we approach the end of 2023, as users upgrade their browsers.</p><p>While building Pink Design, we had the luxury of building a product for developers, a type of user that updates their browsers regularly. Therefore, we chose to move forward with this new method using CSS Layers.</p><h3>Final Words</h3><p><a href="https://pink.appwrite.io/">Pink Design</a> is finally out today. <a href="https://pink.appwrite.io/">Pink Design</a> was built with new inventive CSS methods, and prioritizes accessibility and developer experience. As a company developing an open-source product, this is a big step for Appwrite’s community of contributors. As always, we will keep improving <a href="https://pink.appwrite.io/">Pink Design</a>, allowing it to grow alongside <a href="https://appwrite.io/">Appwrite</a>.</p><p>Thank you for being a part of our journey! If you haven’t already, browse the 💻 <a href="https://github.com/appwrite/pink">Pink Design GitHub Repository</a> or check out our 🚀 <a href="https://pink.appwrite.io/getting-started">Getting Started Guide</a> to use Pink Design in your projects or when contributing to <a href="https://appwrite.io/">Appwrite</a>.</p><p>Until next time!</p><p><strong>Further reading/watching on CSS Layers:</strong></p><ul><li><a href="https://css-tricks.com/css-cascade-layers/">A Complete Guide to CSS Cascade Layers</a> — by <a href="https://twitter.com/terriblemia"><em>Miriam Suzanne</em></a></li><li><a href="https://www.smashingmagazine.com/2022/01/introduction-css-cascade-layers/">Getting Started With CSS Cascade Layers</a> — by <a href="https://twitter.com/5t3ph"><em>Stephanie Eckles</em></a></li><li><a href="https://www.youtube.com/watch?v=zEPXyqj7pEA">The CSS Cascade, a deep dive</a> (video) — by <a href="https://twitter.com/bramus"><em>Bramus Van Damme</em></a></li></ul><p><strong>Further reading on The New CSS Reset:</strong></p><ul><li><a href="https://elad.medium.com/how-does-css-work-92fe7116916d">How Does CSS Work?</a> — by <a href="https://twitter.com/eladsc"><em>Elad Shechter</em></a></li><li><a href="https://elad.medium.com/the-new-css-reset-53f41f13282e">The New CSS Reset</a> — by <a href="https://twitter.com/eladsc"><em>Elad Shechter</em></a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f60f270aa1cd" width="1" height="1" alt=""><hr><p><a href="https://medium.com/appwrite-io/css-layers-for-css-resets-f60f270aa1cd">CSS Layers for CSS Resets</a> was originally published in <a href="https://medium.com/appwrite-io">Appwrite</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Announcing Pink Design]]></title>
            <link>https://medium.com/appwrite-io/announcing-pink-design-30652e2a2be3?source=rss----aeb817f12ad4---4</link>
            <guid isPermaLink="false">https://medium.com/p/30652e2a2be3</guid>
            <category><![CDATA[open-source]]></category>
            <category><![CDATA[community]]></category>
            <category><![CDATA[backend-as-a-service]]></category>
            <category><![CDATA[design-systems]]></category>
            <dc:creator><![CDATA[Chen]]></dc:creator>
            <pubDate>Wed, 25 Jan 2023 11:09:01 GMT</pubDate>
            <atom:updated>2023-01-25T11:09:01.841Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9DaicioWL8x-09bjLt5Avg.png" /></figure><p>Building software is fun. Building open source software is even better. At Appwrite, open source is at the core of everything we do, and collaboration with our community is what drives us to create better products, but collaborating to build the same product can pose many challenges. To deliver features quickly, consistently, and maintain product identity, it is imperative that everyone working on the same product follow the same guidelines; this is why we’re excited to announce Pink Design.</p><p>Pink Design, or Pink, is Appwrite’s fully open source design system for building consistent and reusable user interfaces.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F2I1gqIiVTEk%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D2I1gqIiVTEk&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F2I1gqIiVTEk%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/0c3808f40b8ce01cd7656e8a288114af/href">https://medium.com/media/0c3808f40b8ce01cd7656e8a288114af/href</a></iframe><p>When we began redesigning our product almost a year ago, we discovered that the lack of a design system caused a lot of inconsistencies. It was difficult for a growing team to build a common identity without guidelines. Two months ago, we released Console 2.0 after several months of hard work. During the development of the new console, we also created our components library and documented every decision we made in order to prioritize our core product values better and be more welcoming for community contributions. This became Pink Design.</p><p>So why is Pink Design essential?</p><p><strong>For Consistency</strong></p><p>Consistent behavior is crucial while building a product. It reduces frustration and guides the user to learn the interface faster. This is why we designed Pink — the library contains foundations, layouts, elements, and components with thoroughly documented usage guidelines.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*razmwhkkJ9V2ZK2HJwo4IQ.png" /></figure><p><strong>For Collaboration</strong></p><p>Appwrite is open source with a growing developer community. With the help of our community members, we always strive to ship new features faster and more efficiently. Pink Design was created to facilitate contributions and collaboration internally and with our community. Pink allows all contributors to build features using a shared set of components, reducing friction.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Ep3XWZiyesc7ivQ4gxMcnA.gif" /></figure><p><strong>For Accessibility</strong></p><p>To make sure people with disabilities and different skill levels have equal opportunities, we designed every component in our library to comply with most accessibility standards — in both light and dark modes.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MLvbbY12TyMC277wn21j6Q.gif" /></figure><p><strong>For Better Dev-Experience</strong></p><p>Developer experience has always been a priority for Appwrite since the beginning, and simplifying software development is what guides us in everything we do. Therefore, Pink Design was created so you could easily integrate with your preferred framework or include the library in your CSS file.</p><p><strong>What’s Next?</strong></p><p>Pink Design is finally out today. As a company developing an open source product, this is a big step for Appwrite’s community of contributors. As always, we will keep improving Pink Design, allowing it to grow alongside Appwrite.</p><p>Thank you for being a part of our journey! If you haven’t already, browse the 💻 <a href="https://github.com/appwrite/pink">Pink Design GitHub Repository</a> or check out our 🚀 <a href="https://pink.appwrite.io/getting-started">Getting Started Guide</a> to use Pink Design in your projects or when contributing to Appwrite.</p><p>Until next time!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=30652e2a2be3" width="1" height="1" alt=""><hr><p><a href="https://medium.com/appwrite-io/announcing-pink-design-30652e2a2be3">Announcing Pink Design</a> was originally published in <a href="https://medium.com/appwrite-io">Appwrite</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Getting Started with Pink Design]]></title>
            <link>https://medium.com/appwrite-io/getting-started-with-pink-design-198faa6c7f5e?source=rss----aeb817f12ad4---4</link>
            <guid isPermaLink="false">https://medium.com/p/198faa6c7f5e</guid>
            <category><![CDATA[css]]></category>
            <category><![CDATA[open-source]]></category>
            <category><![CDATA[design-systems]]></category>
            <category><![CDATA[appwrite]]></category>
            <category><![CDATA[html]]></category>
            <dc:creator><![CDATA[Arman]]></dc:creator>
            <pubDate>Wed, 25 Jan 2023 11:01:22 GMT</pubDate>
            <atom:updated>2023-01-25T11:01:22.170Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dIKNOniN60FLjDoJnO7RnA.png" /></figure><p><a href="https://pink.appwrite.io">Pink Design</a> is Appwrite’s Open Source design system for building consistent and reusable user interfaces.</p><p>This design system was developed with Appwrite’s console in mind, with a particular focus on accessibility and usability, without giving up on style! ;)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/126/0*EkJwhtIi1MZe63Rw" /></figure><p>Pink Design is versatile in its application. It can be easily integrated with popular frameworks such as React, Svelte, Angular, or Vue or used in conjunction with standard HTML and CSS.</p><p>You can use Pink Design in your personal projects or contribute to its development and help us improve Appwrite.</p><h3>🎨 How do I get Pink Design?</h3><p>There are two ways to add Pink Design to your project:</p><p>By linking the stylesheet directly in your HTML file, like so:</p><pre>&lt;link rel=&quot;stylesheet&quot; href=&quot;https://unpkg.com/@appwrite.io/pink&quot; /&gt;<br>&lt;!-- optionally, add icons --&gt;<br>&lt;link rel=&quot;stylesheet&quot; href=&quot;https://unpkg.com/@appwrite.io/pink-icons&quot; /&gt;</pre><p>Or by installing it through npm and importing it in your project’s JavaScript file, as follows:</p><pre>npm install @appwrite.io/pink</pre><p>and then by importing it like this:</p><pre>import &quot;@appwrite.io/pink/dist/pink.css&quot;;<br><br>// optionally, add icons<br>import &quot;@appwrite.io/pink-icons&quot;;</pre><p>And voilà, once you’ve completed either of these steps, you can start using Pink Design’s UI elements and components!</p><p>Make sure to check the <a href="https://pink.appwrite.io/getting-started">Getting Started</a> guide for more information 😊</p><h3>⌨️ It’s coding time</h3><p>Pink Design provides many pre-designed UI elements and components, such as buttons, inputs, cards, and more. You can easily use them by adding the corresponding classes to your HTML.</p><pre>&lt;button class=&quot;button&quot;&gt;<br>  &lt;span class=&quot;text&quot;&gt;Hello world&lt;/span&gt;<br>&lt;/button&gt;</pre><p>Easy as that! 🔥</p><h3>🏁 Conclusion</h3><p>And that’s all it takes to add Pink Design to your project. You can view the following resources as well if you want to explore Pink Design further:</p><p><a href="https://github.com/appwrite/pink">Pink Design GitHub</a></p><p><a href="https://discord.com/invite/appwrite">Appwrite Discord</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=198faa6c7f5e" width="1" height="1" alt=""><hr><p><a href="https://medium.com/appwrite-io/getting-started-with-pink-design-198faa6c7f5e">Getting Started with Pink Design</a> was originally published in <a href="https://medium.com/appwrite-io">Appwrite</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introducing Console 2.0: Functions]]></title>
            <link>https://medium.com/appwrite-io/introducing-console-2-0-functions-357b4ed7b6e9?source=rss----aeb817f12ad4---4</link>
            <guid isPermaLink="false">https://medium.com/p/357b4ed7b6e9</guid>
            <dc:creator><![CDATA[Carla]]></dc:creator>
            <pubDate>Wed, 23 Nov 2022 13:14:10 GMT</pubDate>
            <atom:updated>2022-11-23T13:14:10.722Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Nx5C1MsstN9ul7cijG4NSg.png" /></figure><p>Our main goal while redesigning the Appwrite console was to improve the user experience in line with the needs and requirements of developers looking for a BaaS (Backend as a Service) solution. While keeping our core values, such as simplicity and consistency, in mind, we attempted to understand the essential problems developers faced in the previous version of the console.</p><p>With the collaboration of our developer community, we gathered feedback and prioritised a few updates to the functions screens.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BBrsrbdd64aPDXCUtk0jbg.png" /><figcaption>Proposed updates to the Functions screens based on effort vs. impact</figcaption></figure><p>Let’s take a closer look at some of the changes we made.</p><p><strong>Home screen details</strong></p><p>Our research showed that users wanted to see more details about their functions without the need to navigate to another screen. Like a few other screens in the redesigned console, the new design provides those extra details: function IDs that can easily be copied, the details of the next scheduled CRON job if a time period has been set, or if the user has yet to create a deployment for a function.</p><p><strong>Function creation</strong></p><p>There is so much more to creating a function than simply choosing a name and selecting a runtime. Community feedback indicated that in the previous version of the console, it wasn’t apparent that you could customise a function during the creation process. Setting execute access, scheduling deployments, or adding variables — things our users felt were essential for customisation — could only be done after a function was created.</p><p>The new function setup process now guides users through these optional extra steps, and once complete, directs them to a new Deployments tab where they can create a deployment.</p><figure><img alt="Animation of the creation and customization of a new function in the Appwrite console" src="https://cdn-images-1.medium.com/max/1024/1*DzlQ1BTb8TuE625LnWE9MA.gif" /><figcaption>The new Create Function flow</figcaption></figure><p><strong>Deployment details</strong></p><p>Speaking of deployments, a common issue that arose throughout our research was that the previous version of the console did not make clear which ones were active versus inactive when viewing a function’s details. We decided to separate this information from the function details entirely and create a Deployments tab where active deployments are displayed at the top of the screen. Inactive deployments remain visible in a more condensed table below the currently active deployment. This is in contrast to the previous design, which gave unnecessary emphasis to the name of the function and the function runtime, and the deployment details were displayed in a single table, active or otherwise.</p><figure><img alt="New versus old deployment details in the Appwrite console" src="https://cdn-images-1.medium.com/max/1024/1*8MGyaSDMuW4CKZ-gBy1OWw.gif" /></figure><p><strong>Execution (log) details</strong></p><p>When engaging with our users, there was some confusion as to which logs were being displayed and where in the Functions screens, so our first line of business was to specify that the ‘Logs’ mentioned in the tab navigation were, in fact, <em>execution logs</em>. We changed the name of this tab in our redesign to reflect this, and so far the response has been positive.</p><p>We also made the decision to include tags with a hover state to display the trigger status of an execution. If an execution was triggered by an event, on hover the user can see the details of the trigger event. If the execution was triggered via a schedule, on hover the user can see the scheduled time for the next execution. (Currently, nothing happens when hovering over the ‘http’ trigger tag).</p><p><strong>Full-screen deployment &amp; execution logs</strong></p><p>When viewing logs for either deployments or executions, users will now have the full screen at their disposal. Previously, users were limited to viewing their logs in a modal — which is fine if there are only a few lines in the log to view. As it turned out, there were more than a few instances where a user’s build log would span hundreds of lines.</p><figure><img alt="Full-screen (new) vs. modal (old) display of execution logs in the Appwrite console" src="https://cdn-images-1.medium.com/max/1024/1*e1mtRKzewYyIXr_RrZVABg.png" /><figcaption>Full-screen (new) vs. modal (old) display of execution logs in the Appwrite console</figcaption></figure><p><strong>Editable function variables</strong></p><p>Another often-requested feature for the Functions service was the ability to edit variables. This wasn’t technically feasible for us in the previous version of the console. If users wanted to edit a variable, they would have needed to delete it and create a new one with the updated details. More recently, our talented engineering team overcame this roadblock. As a result, the redesign of the functions settings screen includes a menu to allow for the editing and deleting of variables. We have also added an inline interactive text component that permits users to view variable values without the friction of having to click to open a modal to see this information.</p><figure><img alt="Animation of editing an existing function variable key name in the new Appwrite console" src="https://cdn-images-1.medium.com/max/1024/1*1GC6xcll5wTNjjjQ-5Mrbg.gif" /></figure><p><strong>What’s next?<br></strong>We may have overhauled our console design, but we are far from finished. Design is an iterative process, after all. We are working on further improvements to the Function screens, including a GUI for scheduling CRON jobs and GitHub integration for deployments.</p><p>Thank you for being a part of our journey as we strive to create the best developer experience. We hope you enjoy these changes to the Appwrite console. As always, we’re more than happy to hear your thoughts. Leave a comment, reach out on Discord, or create a GitHub discussion.</p><p>Check out our release on 🚀 <a href="https://www.producthunt.com/posts/console-2-0">Product Hunt</a> or our 💻 <a href="https://github.com/appwrite/console">GitHub repository</a>.</p><p>Until next time!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=357b4ed7b6e9" width="1" height="1" alt=""><hr><p><a href="https://medium.com/appwrite-io/introducing-console-2-0-functions-357b4ed7b6e9">Introducing Console 2.0: Functions</a> was originally published in <a href="https://medium.com/appwrite-io">Appwrite</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introducing Console 2.0: Databases]]></title>
            <link>https://medium.com/appwrite-io/introducing-console-2-0-databases-f74c0de43e50?source=rss----aeb817f12ad4---4</link>
            <guid isPermaLink="false">https://medium.com/p/f74c0de43e50</guid>
            <category><![CDATA[backend-as-a-service]]></category>
            <category><![CDATA[redesign]]></category>
            <category><![CDATA[open-source]]></category>
            <dc:creator><![CDATA[Chen]]></dc:creator>
            <pubDate>Tue, 22 Nov 2022 10:56:39 GMT</pubDate>
            <atom:updated>2022-11-22T10:56:39.020Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*A63b5VwuCkVkklbXnIot-A.png" /></figure><p>Our main goal while redesigning the Appwrite console was to improve the user experience in line with the needs and requirements of developers looking for a BaaS (Backend as a Service) solution. While keeping our core values such as simplicity and consistency in mind, we attempted to understand the essential problems developers faced in the previous version of the console.</p><p>With the collaboration of our developer community, we gathered feedback and prioritized a few updates to the Databases screens.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*woo0Sp5OqQeqI4diBv2bCQ.png" /><figcaption>Changes in Databases screens prioritized by effort vs. impact</figcaption></figure><p>Let’s take a closer look at some of the changes we made.</p><p><strong>Databases and collections</strong></p><p>With Appwrite’s Databases Service, you can create multiple databases. Each database can contain many collections. The Databases and Collections screens have been revamped to make it easier for developers to detect disabled collections and easily copy databases and collections IDs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-lKVRqgkm31tVeM6ebLC8Q.gif" /></figure><p><strong>New permissions</strong></p><p>Permissions can be complicated, we know! That is why we designed a simpler way to manage them in the Appwrite console. Now you can switch a toggle to enable or disable Document Security. If security is enabled, you can update your permissions at the document level. If security is disabled, you can update your permissions at the collection level.</p><p>These permissions can be granted to anyone, all guests, all users, or specific users or teams. We’ve even added a setting that enables developers to create custom permissions. Easy, right?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vIbWKLQnrvzpqdHzwhSGqQ.gif" /></figure><p><strong>Document creation</strong></p><p>Creating attributes is still required before creating a document since they define its structure and help the Appwrite API validate input from your users. Once your attributes have been set, you can create your documents using a simple two-step process. For the first step, you will need to create the document’s data, which means filling in all of the attribute fields you set up earlier. Next, you will be able to set permissions, depending on whether you have enabled document security.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4fJbDYI45I0O0-KSP5hlRQ.gif" /></figure><p><strong>Documents overview</strong></p><p>If you have a large table of documents with many attributes, finding what you need in the documents overview screen can be very difficult. In the previous console, if you had 10 or more attributes, there was no way to tell which document you were looking at without a lot of horizontal scrolling. With the new console design, the ID column is sticky. That way you can always see the document ID and copy it easily to use in your code.</p><p><strong>Attributes and indexes</strong></p><p>Your attributes and indexes play essential roles in your projects. We revamped the screens for both and added a menu to allow for quick actions such as opening an overview, creating an index for a specific attribute, and deleting attributes or indexes from the table.</p><p><strong>What’s next?</strong></p><p>We may have overhauled our console design, but we are far from finished. Design is an iterative process after all. We are working on further improvements to the Databases screens such as filtering and searching for documents, as well as deleting multiple attributes and/or indexes at once.</p><p>Thank you for being a part of our journey as we strive to create the best developer experience. We hope you enjoy these changes to the Appwrite console. As always, we’re more than happy to hear your thoughts. Leave a comment, reach out on Discord, or create a GitHub discussion.</p><p>Check out our release on 🚀 <a href="https://www.producthunt.com/posts/console-2-0">Product Hunt</a> or our 💻 <a href="https://github.com/appwrite/console">GitHub repository</a></p><p>Until next time!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f74c0de43e50" width="1" height="1" alt=""><hr><p><a href="https://medium.com/appwrite-io/introducing-console-2-0-databases-f74c0de43e50">Introducing Console 2.0: Databases</a> was originally published in <a href="https://medium.com/appwrite-io">Appwrite</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introducing Console 2.0: Storage]]></title>
            <link>https://medium.com/appwrite-io/introducing-console-2-0-storage-2a5a50b4105b?source=rss----aeb817f12ad4---4</link>
            <guid isPermaLink="false">https://medium.com/p/2a5a50b4105b</guid>
            <dc:creator><![CDATA[Carla]]></dc:creator>
            <pubDate>Mon, 21 Nov 2022 12:55:07 GMT</pubDate>
            <atom:updated>2022-11-21T12:55:07.041Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EuhVK_uFgEh2NQNZyWaVzw.png" /></figure><p>Our main goal while redesigning the Appwrite console was to improve the user experience in line with the needs and requirements of developers looking for a BaaS (Backend as a Service) solution. While keeping our core values such as simplicity and consistency in mind, we attempted to understand the essential problems developers faced in the previous version of the console.</p><p>With the collaboration of our developer community, we gathered feedback and prioritised a few updates to the storage screens.</p><figure><img alt="Impact vs effort matrix for the Appwrite Console Storage service" src="https://cdn-images-1.medium.com/max/1024/1*K8AKv8zHBG3bVM62VS44lA.png" /><figcaption>Proposed updates to the Storage screens based on effort vs. impact</figcaption></figure><p>Let’s take a closer look at some of the changes we made.</p><p><strong>Home screen details</strong></p><p>Overwhelmingly, our research found that users wanted to see more information about their storage buckets at a glance — in particular, the bucket’s current status. The previous version of this screen showed a list of buckets but provided only the bucket name. Users would need to navigate to the bucket settings screen to see the information they wanted.</p><p>The revamped bucket details card, following our new design system, now displays a couple extra details: whether the bucket is currently disabled, or if encryption or antivirus features have been enabled. The bucket details card also allows users to click and copy their bucket ID.</p><figure><img alt="New versus old version of the Buckets overview screen in the Appwrite console" src="https://cdn-images-1.medium.com/max/1024/1*9bYtmzDrW9x42YOYSwMhDw.gif" /></figure><p><strong>Uploading Files</strong></p><p>We updated the file upload functionality to enable drag-and-drop for an effortless uploading process. Files being uploaded have also been made more visible so that users can check their status in a window that persists across the console until closed by the user.</p><figure><img alt="Animation of the new drag and drop upload process in the Appwrite console" src="https://cdn-images-1.medium.com/max/1024/1*FaBVa7g2sBRl21BQQdNpkg.gif" /></figure><p><strong>Updating file extensions</strong></p><p>Previously, users could update the list of allowed file extensions in a bucket by manually typing them into an input field. Placeholder text within the field provided some suggested extensions, but our users found the manual process to be tedious. To alleviate some of this frustration, we inserted a set of tags with the most common extensions below the input field so users would have the option to click and add extensions.</p><p><strong>New permissions</strong></p><p>Permissions can be complicated, we know! That is why we designed a simpler way to manage them in the Appwrite console. Now you can switch a toggle to enable or disable File Security. If security is enabled, you can update your permissions at the file level. If security is disabled, you can update your permissions at the bucket level.</p><p>These permissions can be granted to anyone, all guests, all users, or to specific users or teams. We’ve even added a setting that enables developers to create custom permissions. Easy, right?</p><figure><img alt="Old versus new File settings screen in the Appwrite console" src="https://cdn-images-1.medium.com/max/1024/1*m_5CItlp7Sne5budMUgRCw.png" /><figcaption>Once file security is enabled, permissions can be easily selected via a dropdown menu</figcaption></figure><p><strong>What’s next?<br></strong>We may have overhauled our console design, but we are far from finished. Design is an iterative process, after all. We are working on further improvements to the storage screens such as enabling the sorting and filtering of files, file search by ID or URL, and the addition of more file details (for instance, the user ID of who uploaded a file outside of the console).</p><p>Thank you for being a part of our journey as we strive to create the best developer experience. We hope you enjoy these changes to the Appwrite console. As always, we’re more than happy to hear your thoughts. Leave a comment, reach out on Discord, or create a GitHub discussion.</p><p>Check out our release on 🚀 <a href="https://www.producthunt.com/posts/console-2-0">Product Hunt</a> or our 💻 <a href="https://github.com/appwrite/console">GitHub repository</a>.</p><p>Until next time!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2a5a50b4105b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/appwrite-io/introducing-console-2-0-storage-2a5a50b4105b">Introducing Console 2.0: Storage</a> was originally published in <a href="https://medium.com/appwrite-io">Appwrite</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introducing Console 2.0: Auth]]></title>
            <link>https://medium.com/appwrite-io/introducing-console-2-0-auth-838b9d8c49b5?source=rss----aeb817f12ad4---4</link>
            <guid isPermaLink="false">https://medium.com/p/838b9d8c49b5</guid>
            <category><![CDATA[console]]></category>
            <category><![CDATA[backend-as-a-service]]></category>
            <category><![CDATA[open-source]]></category>
            <category><![CDATA[redesign]]></category>
            <category><![CDATA[launch]]></category>
            <dc:creator><![CDATA[Chen]]></dc:creator>
            <pubDate>Wed, 16 Nov 2022 10:34:10 GMT</pubDate>
            <atom:updated>2022-11-20T13:08:18.112Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-DoilhdqWEY68KtVP0RXNA.png" /></figure><p>Our main goal while redesigning the Appwrite console was to improve the user experience in line with the needs and requirements of developers looking for a BaaS (Backend as a Service) solution. While keeping our core values such as simplicity and consistency in mind, we attempted to understand the essential problems developers faced in the previous version of the console.</p><p>With the collaboration of our developer community, we gathered feedback and prioritized a few updates to the Auth screens.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_1zhA3TLij8faTOGx7ZkwA.png" /><figcaption>Changes in Auth screens prioritized by effort vs. impact</figcaption></figure><p>Let’s take a closer look at some of the changes we made.</p><p><strong>Account session</strong></p><p>With Appwrite, developers can implement login and registration logic using the Account API. There are different ways to sign in, meaning not all users will be using email and password authentication. When creating a user in the previous console, developers had to enter three inputs: name, email, and password, which does not reflect our current API. Not only should the name be optional, but a phone number cannot be added to a user account. In the new console, we added input for a phone number, as well as making all inputs optional. Fun fact, if all inputs are left empty, an anonymous user will be created.</p><p><strong>Search</strong></p><p>One of the most critical patterns for a better user experience is the search feature. In the new console, you can search users by name, email, phone, or ID. Unlike the previous version, a smoother experience is provided by the table updating in real-time as you type.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6xhlp2HDnPThkiHjgUK5qA.gif" /></figure><p><strong>User preferences</strong></p><p>One of the most requested features from our community was the ability to edit user preferences in the console. In the new console, you can update your user preferences by storing information on the user’s objects so they can easily be shared across devices and sessions.</p><p><strong>Security</strong></p><p>The security settings are now located next to Settings in the tabs navigation. The ‘Users Limit’ option was previously available only in the Settings tab, above the authentication methods. We believe security is too important to be hidden and based on feedback from our developer community that ‘Users Limit’ can be hard to notice, we found it correct to make a distinction between security settings and authentication settings.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6PBPGiBLZyRoZqxLGHAiBw.png" /><figcaption>Security tab in new console vs. ‘Set Limit’ link in previous console</figcaption></figure><p><strong>Settings</strong></p><p>On the Settings tab, you will find authentication methods and an extensive list of OAuth2 providers you can enable for your project. The challenge on this screen was to reduce the visual overload without hiding any of the providers. In order to keep the interface clean from distractions, we gathered all authentication methods on one card. The next step was to move the toggle and documents link from the provider’s card to the modal. Now when the user enables providers, they are shown at the top of the list.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pEfuPdE61vFFqO351wna5w.gif" /></figure><p><strong>What’s next?</strong></p><p>We may have overhauled our console design, but we are far from finished. Design is an iterative process, after all. We are working on further improvements to the Auth screens such as setting a session length in the Security tab, creating a membership for an existing user in a more intuitive way, and improving the flow of enabling an OAuth provider.</p><p>Thank you for being a part of our journey as we strive to create the best developer experience. We hope you enjoy these changes to the Appwrite console. As always, we’re more than happy to hear your thoughts. Leave a comment, reach out on Discord, or create a GitHub discussion.</p><p>Check out our release on 🚀 <a href="https://www.producthunt.com/posts/console-2-0">Product Hunt</a> or our 💻 <a href="https://github.com/appwrite/console">GitHub repository</a></p><p>Until next time!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=838b9d8c49b5" width="1" height="1" alt=""><hr><p><a href="https://medium.com/appwrite-io/introducing-console-2-0-auth-838b9d8c49b5">Introducing Console 2.0: Auth</a> was originally published in <a href="https://medium.com/appwrite-io">Appwrite</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>