<?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: Pavel Štěrba</title>
    <description>The latest articles on DEV Community by Pavel Štěrba (@pavelsterba).</description>
    <link>https://dev.to/pavelsterba</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%2F945401%2F5d9e59be-6921-4d18-94fe-122ab36964c2.jpeg</url>
      <title>DEV Community: Pavel Štěrba</title>
      <link>https://dev.to/pavelsterba</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pavelsterba"/>
    <language>en</language>
    <item>
      <title>TailwindCSS Typography</title>
      <dc:creator>Pavel Štěrba</dc:creator>
      <pubDate>Sat, 12 Nov 2022 16:20:01 +0000</pubDate>
      <link>https://dev.to/pavelsterba/tailwindcss-typography-d0</link>
      <guid>https://dev.to/pavelsterba/tailwindcss-typography-d0</guid>
      <description>&lt;p&gt;During &lt;a href="https://tailwindcss.com/docs/preflight"&gt;preflight&lt;/a&gt;, TailwindCSS removes default styles set by browser. Even tho it's useful for consistency between browsers, you are also losing default formatting for text elements like headinga, paragraphs or lists.&lt;/p&gt;

&lt;p&gt;For custom designs, you will most likely define typography styles from scratch, but if you just want to display text data (like for example in a blog rendered from Markdown), it can be useful to have proper typography without any additional work. Let's take a look to &lt;strong&gt;TailwindCSS Typography&lt;/strong&gt; first party plugin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;Just add it as another dependency to your project and download it from npm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -D @tailwindcss/typography
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And add it to configuration file inside &lt;code&gt;plugin&lt;/code&gt; section:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@tailwindcss/typography&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="c1"&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;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;Most important class provided by this plugin is &lt;code&gt;prose&lt;/code&gt;. Just wrap you text content wit it and you are ready to go:&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;article&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"prose"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Article Title&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To modify text size, you can use various classes provided as well. Make sure that you are using them with &lt;code&gt;prose&lt;/code&gt; class, not just on their own.&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;article&lt;/span&gt; &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;"prose prose-lg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;prose-lg&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hYrePpz8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j3b1rmju15l8ncgjcb7o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hYrePpz8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j3b1rmju15l8ncgjcb7o.png" alt="Prose size" width="880" height="1077"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Full list of supported size modifiers is:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Class&lt;/th&gt;
&lt;th&gt;Font size&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;prose-sm&lt;/td&gt;
&lt;td&gt;0.875rem (14px)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;prose-base&lt;/td&gt;
&lt;td&gt;1rem (16px)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;prose-lg&lt;/td&gt;
&lt;td&gt;1.125rem (18px)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;prose-xl&lt;/td&gt;
&lt;td&gt;1.25rem (20px)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;prose-2xl&lt;/td&gt;
&lt;td&gt;1.5rem (24px)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Aside from font size, &lt;code&gt;prose&lt;/code&gt; also set maximum width of element for better readability. If you want to use more space or remove this behaviour completely, add class &lt;code&gt;max-w-none&lt;/code&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;article&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"prose max-w-none"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  ...
&lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Dark mode
&lt;/h2&gt;

&lt;p&gt;TailwindCSS can handle dark mode with ease with variant &lt;code&gt;dark:*&lt;/code&gt;. In Typography plugin, you have by default various shades of gray text available, but all of them are better in light mode. To use it in dark themed page, just use &lt;code&gt;prose-invert&lt;/code&gt; class beside your &lt;code&gt;prose&lt;/code&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;article&lt;/span&gt; &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;"prose prose-invert"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;prose&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--32PKU-O1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pw2wgg41a9e60wdvcb2r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--32PKU-O1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pw2wgg41a9e60wdvcb2r.png" alt="Dark mode" width="618" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Modify single element
&lt;/h2&gt;

&lt;p&gt;If you need more control over generated styles, you can target single element with &lt;code&gt;prose-*:*&lt;/code&gt;. For example, if you want to underline all &lt;code&gt;h1&lt;/code&gt; tags, you can do it with:&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;article&lt;/span&gt; &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;"prose prose-h1:underline"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;prose&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bbRbzDkE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7unik9iksnaarnaf5jf4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bbRbzDkE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7unik9iksnaarnaf5jf4.png" alt="Modify single element" width="595" height="167"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Block without formatting
&lt;/h2&gt;

&lt;p&gt;In some cases, you want to disable typography for a certain block. For this purpose, just add &lt;code&gt;not-prose&lt;/code&gt; to your element and enjoy content without styling:&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;article&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"prose"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;prose&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"not-prose ..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;prose&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;prose&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BO9cWMDm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w87w6116cvti5rcl1fu1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BO9cWMDm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w87w6116cvti5rcl1fu1.png" alt="Block without formatting" width="651" height="552"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>tailwindcss</category>
    </item>
    <item>
      <title>What's new in Tailwind v3.2</title>
      <dc:creator>Pavel Štěrba</dc:creator>
      <pubDate>Fri, 11 Nov 2022 10:02:31 +0000</pubDate>
      <link>https://dev.to/pavelsterba/whats-new-in-tailwind-v32-46m0</link>
      <guid>https://dev.to/pavelsterba/whats-new-in-tailwind-v32-46m0</guid>
      <description>&lt;p&gt;TailwindCSS v3.2 is out for a few weeks and even tho full list of changes is available on &lt;a href="https://github.com/tailwindlabs/tailwindcss/releases/tag/v3.2.0" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; or &lt;a href="https://tailwindcss.com/blog/tailwindcss-v3-2" rel="noopener noreferrer"&gt;TailwindCSS Blog&lt;/a&gt;, let's take a closer look at some features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multiple config files
&lt;/h2&gt;

&lt;p&gt;If you are using multiple styles in your project (for example one for web and one for admin section), you can specify, which config file should be used for generating CSS file with new &lt;code&gt;@config&lt;/code&gt; directive:&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="c"&gt;/* web.css */&lt;/span&gt;
&lt;span class="k"&gt;@config&lt;/span&gt; &lt;span class="s1"&gt;"../tailwind.web.config.js"&lt;/span&gt;

&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;tailwind&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;utilities&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c"&gt;/* admin.css */&lt;/span&gt;
&lt;span class="k"&gt;@config&lt;/span&gt; &lt;span class="s1"&gt;"../tailwind.admin.config.js"&lt;/span&gt;

&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;tailwind&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;utilities&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Styling based on browser support
&lt;/h2&gt;

&lt;p&gt;Now you can conditionally style elements based on browser support of certain feature with &lt;code&gt;supports-[...]&lt;/code&gt; variant:&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;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-red-600 supports-[display:grid]:bg-green-600 ..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Grid support in browser
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="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%2Farticles%2F2uwwfcb3j0tw55teb10k.png" class="article-body-image-wrapper"&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%2Farticles%2F2uwwfcb3j0tw55teb10k.png" alt="Styling based on browser support"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Styling based on ARIA attribute
&lt;/h2&gt;

&lt;p&gt;You can also style conditionally based on ARIA attributes with new &lt;code&gt;aria-*&lt;/code&gt; variants:&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;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-green-600 aria-hidden:bg-red-600 ..."&lt;/span&gt; &lt;span class="na"&gt;aria-hidden=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Hidden for screen readers.
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="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%2Farticles%2F9anhpj0kqxnn2oxcog5t.png" class="article-body-image-wrapper"&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%2Farticles%2F9anhpj0kqxnn2oxcog5t.png" alt="Styling based on ARIA attribute"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By default, you can use eight most used boolean ARIA values, but can of course add new ones to config file:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;aria-checked&lt;/li&gt;
&lt;li&gt;aria-disabled&lt;/li&gt;
&lt;li&gt;aria-expanded&lt;/li&gt;
&lt;li&gt;aria-hidden&lt;/li&gt;
&lt;li&gt;aria-pressed&lt;/li&gt;
&lt;li&gt;aria-readonly&lt;/li&gt;
&lt;li&gt;aria-required&lt;/li&gt;
&lt;li&gt;aria-selected&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Styling based on data attribute
&lt;/h2&gt;

&lt;p&gt;Last conditional styling is based on data attribute with &lt;code&gt;data-[...]&lt;/code&gt; variant. There are no default variants generated by TailwindCSS, but you can use easy format &lt;code&gt;data-[key=value]&lt;/code&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;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-red-600 data-[size=small]:bg-green-600 ..."&lt;/span&gt; &lt;span class="na"&gt;data-size=&lt;/span&gt;&lt;span class="s"&gt;"small"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  data-size="small"
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-red-600 data-[size=small]:bg-green-600 ..."&lt;/span&gt; &lt;span class="na"&gt;data-size=&lt;/span&gt;&lt;span class="s"&gt;"large"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  data-size="large"
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="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%2Farticles%2F4s482fnflv4hk7mrjniw.png" class="article-body-image-wrapper"&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%2Farticles%2F4s482fnflv4hk7mrjniw.png" alt="Styling based on data attribute"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Breakpoint for max width
&lt;/h2&gt;

&lt;p&gt;New &lt;code&gt;max-*&lt;/code&gt; variant allows us to apply style until certain breakpoint is reached:&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;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-red-600 max-lg:bg-green-600 ..."&lt;/span&gt; &lt;span class="na"&gt;aria-hidden=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Green background for small display.
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="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%2Farticles%2Fps74zdqll3m4vxm6rgz0.png" class="article-body-image-wrapper"&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%2Farticles%2Fps74zdqll3m4vxm6rgz0.png" alt="Breakpoint for max width"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Nested groups
&lt;/h2&gt;

&lt;p&gt;Groups are useful when you need to style elements based on hover on parent element. For that, you can use &lt;code&gt;group&lt;/code&gt; and &lt;code&gt;group-hover&lt;/code&gt; variant. Since v3.2 you can also nest them with &lt;code&gt;group/name&lt;/code&gt; and &lt;code&gt;group-hover/name&lt;/code&gt; syntax:&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;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"group/outer ..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"group/inner ..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-red-600 group-hover/outer:bg-orange-600 group-hover/inner:bg-green-600 ..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="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%2Farticles%2Fwgmj8fme7dm54zgohzop.png" class="article-body-image-wrapper"&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%2Farticles%2Fwgmj8fme7dm54zgohzop.png" alt="Nested groups"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  First party plugin for container queries
&lt;/h2&gt;

&lt;p&gt;Container queries are big thing in CSS world and even tho it's not implemented in TailwindCSS core yet, you can use their first party plugin with new &lt;code&gt;@&lt;/code&gt; syntax:&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;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"@container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"block @lg:flex"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- ... --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>css</category>
      <category>tailwindcss</category>
      <category>news</category>
    </item>
    <item>
      <title>HTTP Status Codes as PHP Exception</title>
      <dc:creator>Pavel Štěrba</dc:creator>
      <pubDate>Sat, 05 Nov 2022 09:57:28 +0000</pubDate>
      <link>https://dev.to/pavelsterba/http-status-codes-as-php-exception-562d</link>
      <guid>https://dev.to/pavelsterba/http-status-codes-as-php-exception-562d</guid>
      <description>&lt;p&gt;HTTP status codes are not just &lt;em&gt;404 Not Found&lt;/em&gt; a &lt;em&gt;500 Server Internal Error&lt;/em&gt;, there's &lt;a href="https://httpwg.org/specs/rfc9110.html#status.codes"&gt;plenty more&lt;/a&gt;. During your API development, you will sooner or later face a situation, where you will have use wider variety of HTTP statuses.&lt;/p&gt;

&lt;p&gt;You can implement them one by one for your project, or you can use library &lt;strong&gt;&lt;a href="https://github.com/pavelsterba/http-exceptions"&gt;HTTP Exceptions&lt;/a&gt;&lt;/strong&gt;, which recently released major version 2.0 with all HTTP status codes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;Just add it as dependency to your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require pavelsterba/http-exceptions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;All exceptions can be thrown without any additional information - message and code are predefined and you just have to send them to endpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HttpException\ServerError\InternalServerErrorException&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpException\HttpException&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 500 Internal Server Error&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getCode&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 500&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to customize error message or attach previous exception, you can of course pass them as parameters to constructor (but you have to pass status code as well), or you can use static &lt;code&gt;get&lt;/code&gt; method to customize it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;HttpException\ServerError\InternalServerErrorException&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="nv"&gt;$ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nc"&gt;InternalServerErrorException&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Server down, sorry."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$ex&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;h2&gt;
  
  
  Exceptions hierarchy
&lt;/h2&gt;

&lt;p&gt;Since version 2.0, you are able to have your API fully exception driven, because exceptions for Informational, Successfull and Redirection codes are implemented. Full hierarchy or exceptions is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Exception
└─ HttpException\HttpException
   ├─ HttpException\InformationalException
   │  ├─ HttpException\Informational\ContinueException
   │  ├─ HttpException\Informational\SwitchingProtocolsException
   │  ├─ HttpException\Informational\ProcessingException
   │  └─ HttpException\Informational\EarlyHintsException
   ├─ HttpException\SuccessfulException
   │  ├─ HttpException\Successful\OKException
   │  ├─ HttpException\Successful\CreatedException
   │  ├─ HttpException\Successful\AcceptedException
   │  ├─ HttpException\Successful\NonAuthoritativeInformationException
   │  ├─ HttpException\Successful\NoContentException
   │  ├─ HttpException\Successful\ResetContentException
   │  ├─ HttpException\Successful\PartialContentException
   │  ├─ HttpException\Successful\MultiStatusException
   │  ├─ HttpException\Successful\AlreadyReportedException
   │  └─ HttpException\Successful\IMUsedException
   ├─ HttpException\RedirectionException
   │  ├─ HttpException\Redirection\MultipleChoicesException
   │  ├─ HttpException\Redirection\MovedPermanentlyException
   │  ├─ HttpException\Redirection\FoundException
   │  ├─ HttpException\Redirection\SeeOtherException
   │  ├─ HttpException\Redirection\NotModifiedException
   │  ├─ HttpException\Redirection\UseProxyException
   │  ├─ HttpException\Redirection\TemporaryRedirectException
   │  └─ HttpException\Redirection\PermanentRedirectException
   ├─ HttpException\ClientErrorException
   │  ├─ HttpException\ClientError\BadRequestException
   │  ├─ HttpException\ClientError\UnauthorizedException
   │  ├─ HttpException\ClientError\PaymentRequiredException
   │  ├─ HttpException\ClientError\ForbiddenException
   │  ├─ HttpException\ClientError\NotFoundException
   │  ├─ HttpException\ClientError\MethodNotAllowedException
   │  ├─ HttpException\ClientError\NotAcceptableException
   │  ├─ HttpException\ClientError\ProxyAuthenticationRequiredException
   │  ├─ HttpException\ClientError\RequestTimeoutException
   │  ├─ HttpException\ClientError\ConflictException
   │  ├─ HttpException\ClientError\GoneException
   │  ├─ HttpException\ClientError\LengthRequiredException
   │  ├─ HttpException\ClientError\PreconditionFailedException
   │  ├─ HttpException\ClientError\PayloadTooLargeException
   │  ├─ HttpException\ClientError\URITooLongException
   │  ├─ HttpException\ClientError\UnsupportedMediaTypeException
   │  ├─ HttpException\ClientError\RangeNotSatisfiableException
   │  ├─ HttpException\ClientError\ExpectationFailedException
   │  ├─ HttpException\ClientError\IMaTeapotException
   │  ├─ HttpException\ClientError\MisdirectedRequestException
   │  ├─ HttpException\ClientError\UnprocessableEntityException
   │  ├─ HttpException\ClientError\LockedException
   │  ├─ HttpException\ClientError\FailedDependencyException
   │  ├─ HttpException\ClientError\TooEarlyException
   │  ├─ HttpException\ClientError\UpgradeRequiredException
   │  ├─ HttpException\ClientError\PreconditionRequiredException
   │  ├─ HttpException\ClientError\TooManyRequestsException
   │  ├─ HttpException\ClientError\RequestHeaderFieldsTooLargeException
   │  └─ HttpException\ClientError\UnavailableForLegalReasonsException
   └─ HttpException\ServerErrorException
      ├─ HttpException\ServerError\InternalServerErrorException
      ├─ HttpException\ServerError\NotImplementedException
      ├─ HttpException\ServerError\BadGatewayException
      ├─ HttpException\ServerError\ServiceUnavailableException
      ├─ HttpException\ServerError\GatewayTimeoutException
      ├─ HttpException\ServerError\HTTPVersionNotSupportedException
      ├─ HttpException\ServerError\VariantAlsoNegotiatesException
      ├─ HttpException\ServerError\InsufficientStorageException
      ├─ HttpException\ServerError\LoopDetectedException
      ├─ HttpException\ServerError\NotExtendedException
      └─ HttpException\ServerError\NetworkAuthenticationRequiredException
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this in mind, you can catch them as you like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpException\ClientError\NotFoundException&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Only NotFoundException catched&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpException\ClientErrorException&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// All ClientError exceptions&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpException\HttpException&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// All HTTP exceptions from library&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Everything else...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>php</category>
      <category>webdev</category>
      <category>api</category>
    </item>
  </channel>
</rss>
