<?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>Forem: Reuven Hozias</title>
    <description>The latest articles on Forem by Reuven Hozias (@hreuven).</description>
    <link>https://forem.com/hreuven</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%2F347468%2Fd11cc096-056b-46de-8d42-e57c0ec2de98.png</url>
      <title>Forem: Reuven Hozias</title>
      <link>https://forem.com/hreuven</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/hreuven"/>
    <language>en</language>
    <item>
      <title>Dev tools: Debug WebSocket Connections Fast</title>
      <dc:creator>Reuven Hozias</dc:creator>
      <pubDate>Thu, 11 Sep 2025 10:37:07 +0000</pubDate>
      <link>https://forem.com/hreuven/dev-tools-debug-websocket-connections-fast-5393</link>
      <guid>https://forem.com/hreuven/dev-tools-debug-websocket-connections-fast-5393</guid>
      <description>&lt;p&gt;WebSocket connections power real-time web apps—from chat applications to live trading platforms. But when they break, debugging can be frustrating and time-consuming.&lt;/p&gt;

&lt;p&gt;A &lt;a href="https://toolzbay.com/websocket-echo-tester" rel="noopener noreferrer"&gt;WebSocket Echo Tester&lt;/a&gt; makes troubleshooting simple.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Does It Do?
&lt;/h2&gt;

&lt;p&gt;This tool connects to any WebSocket server and echoes back your messages in real-time. It's perfect for testing connections, validating message formats, and debugging issues before they reach production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Developers Love It
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Instant Validation&lt;/strong&gt;: Quickly check if your WebSocket server is reachable and responding correctly.&lt;br&gt;
&lt;strong&gt;Real-Time Testing&lt;/strong&gt;: Send messages and see responses immediately—no complex setup required.&lt;br&gt;
&lt;strong&gt;Format Testing&lt;/strong&gt;: Experiment with JSON, plain text, or binary data to ensure your messages are properly formatted.&lt;br&gt;
&lt;strong&gt;Zero Setup&lt;/strong&gt;: Browser-based tool that works instantly—just enter your WebSocket URL and start testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Use Cases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Test WebSocket APIs during development&lt;/li&gt;
&lt;li&gt;Validate third-party service connections&lt;/li&gt;
&lt;li&gt;Troubleshoot network and firewall issues&lt;/li&gt;
&lt;li&gt;Monitor connection stability&lt;/li&gt;
&lt;li&gt;Verify authentication mechanisms&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to Use It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Enter your WebSocket URL (e.g., &lt;code&gt;wss://echo.websocket.org&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Click Connect&lt;/li&gt;
&lt;li&gt;Send test messages and watch the real-time responses&lt;/li&gt;
&lt;li&gt;Monitor connection status and error messages&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Beyond Basic Echo Testing
&lt;/h2&gt;

&lt;p&gt;While echo testing is fundamental, our tool also helps with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Connection lifecycle management&lt;/strong&gt;: Test how your application handles connection establishment, maintenance, and cleanup&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error handling&lt;/strong&gt;: Simulate various error conditions to ensure your application responds gracefully&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Message queuing&lt;/strong&gt;: Understand how messages are handled when connections are temporarily unavailable&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication testing&lt;/strong&gt;: Verify that your WebSocket authentication mechanisms work correctly&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Start Testing Today
&lt;/h2&gt;

&lt;p&gt;Stop wrestling with WebSocket connection issues. The &lt;a href="https://toolzbay.com/websocket-echo-tester" rel="noopener noreferrer"&gt;WebSocket Echo Tester&lt;/a&gt; gives you the instant feedback you need to build reliable real-time applications.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;About &lt;a href="https://toolzbay.com" rel="noopener noreferrer"&gt;ToolzBay&lt;/a&gt;&lt;/strong&gt;: High-quality web utilities that make developers' lives easier. From API testing tools to data converters, our growing collection of utilities is designed to solve real problems without the hassle of complex setups or subscriptions.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>tooling</category>
      <category>productivity</category>
      <category>javascript</category>
    </item>
    <item>
      <title>JavaScript in 2025: Your Roadmap to Modern Features</title>
      <dc:creator>Reuven Hozias</dc:creator>
      <pubDate>Mon, 01 Sep 2025 14:43:29 +0000</pubDate>
      <link>https://forem.com/hreuven/javascript-in-2025-your-roadmap-to-modern-features-31ff</link>
      <guid>https://forem.com/hreuven/javascript-in-2025-your-roadmap-to-modern-features-31ff</guid>
      <description>&lt;p&gt;&lt;em&gt;Welcome to the first article in our comprehensive series exploring the latest JavaScript features that are reshaping how we write code in 2025.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Article 1&lt;/strong&gt;: JavaScript in 2025: Your Roadmap to Modern Features&lt;br&gt;
&lt;strong&gt;Article 2&lt;/strong&gt;: ES2024's immutable array methods and when to use them&lt;br&gt;
&lt;strong&gt;Article 3&lt;/strong&gt;: Promise.withResolvers() and modern async patterns&lt;br&gt;
&lt;strong&gt;Article 4&lt;/strong&gt;: Set operations for elegant data manipulation&lt;br&gt;
&lt;strong&gt;Article 5&lt;/strong&gt;: Regular expression enhancements with the /v flag&lt;br&gt;
&lt;strong&gt;Article 6&lt;/strong&gt;: Advanced ArrayBuffer capabilities for performance-critical applications&lt;br&gt;
&lt;strong&gt;Article 7&lt;/strong&gt;: Preview of upcoming features in ES2025 and beyond&lt;br&gt;
&lt;strong&gt;Article 8&lt;/strong&gt;: Practical migration strategies for modernizing your codebase&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Staying Current with JavaScript Matters
&lt;/h2&gt;

&lt;p&gt;The JavaScript ecosystem moves fast, but not arbitrarily. Each new feature addresses real pain points that developers face daily. Consider how async/await transformed asynchronous programming, or how destructuring assignment simplified object and array manipulation. Today's new features continue this tradition of solving practical problems while improving code quality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For your career&lt;/strong&gt;: Modern JavaScript features are increasingly expected in job interviews and code reviews. Companies want developers who can leverage the latest language capabilities to write cleaner, more efficient code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For your projects&lt;/strong&gt;: New JavaScript features often provide better performance, enhanced security, and improved developer experience. Features like immutable array methods reduce bugs, while improved Promise utilities make async code more reliable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For your team&lt;/strong&gt;: Understanding modern JavaScript helps you &lt;br&gt;
communicate better with other developers and contribute to more maintainable codebases that your future self (and colleagues) will thank you for.&lt;/p&gt;

&lt;h2&gt;
  
  
  The JavaScript Evolution Timeline: From ES2020 to ES2025
&lt;/h2&gt;

&lt;p&gt;JavaScript's evolution follows a predictable yearly release cycle, but understanding where we've been helps us appreciate where we're going.&lt;/p&gt;

&lt;h3&gt;
  
  
  ES2020 Highlights (June 2020)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Optional Chaining (?.)&lt;/strong&gt;: Made property access safer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nullish Coalescing (??)&lt;/strong&gt;: Provided better default value handling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BigInt&lt;/strong&gt;: Enabled arbitrary-precision integer arithmetic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic Imports&lt;/strong&gt;: Allowed conditional module loading
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ES2020 made this possible&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Anonymous&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userModule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./userModule.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ES2021 Highlights (June 2021)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Logical Assignment Operators (&lt;code&gt;||=, &amp;amp;&amp;amp;=, ??=&lt;/code&gt;)&lt;/strong&gt;: Streamlined conditional assignments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WeakRef&lt;/strong&gt;: Enabled weak references to objects&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;String.prototype.replaceAll()&lt;/strong&gt;: Finally, a native way to replace all occurrences
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ES2021 simplified common patterns&lt;/span&gt;
&lt;span class="nx"&gt;apiUrl&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replaceAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;old&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// No more regex needed!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ES2022 Highlights (June 2022)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Top-level &lt;code&gt;await&lt;/code&gt;&lt;/strong&gt;: Made module initialization cleaner&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private Fields (&lt;code&gt;#field&lt;/code&gt;)&lt;/strong&gt;: Brought true private properties to classes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Static Class Fields&lt;/strong&gt;: Enabled class-level properties
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ES2022 enabled cleaner class design&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;APIClient&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Private field&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;baseURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;apiKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ES2023 Highlights (June 2023)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Array Methods&lt;/strong&gt;: &lt;code&gt;findLast(), findLastIndex(), toReversed(), toSorted(), toSpliced()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hashbang Grammar&lt;/strong&gt;: Better script execution support&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ES2024: The Current State (June 2024)
&lt;/h3&gt;

&lt;p&gt;ES2024 brought some of the most practical improvements we've seen in years:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Immutable Array Methods&lt;/strong&gt;: &lt;code&gt;with(), toReversed(), toSorted(), toSpliced()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set Operations&lt;/strong&gt;: Native mathematical operations like &lt;code&gt;union(), intersection()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Promise.withResolvers()&lt;/strong&gt;: Simplified promise creation patterns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regular Expression /v Flag&lt;/strong&gt;: Enhanced Unicode and set notation support&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Looking Ahead: ES2025 and Beyond
&lt;/h3&gt;

&lt;p&gt;While ES2025 specifications are still being finalized, several exciting features are advancing through the TC39 process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Temporal API&lt;/strong&gt;: A complete overhaul of date/time handling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pattern Matching&lt;/strong&gt;: Powerful conditional logic improvements&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Import Attributes&lt;/strong&gt;: Better support for importing JSON and other file types&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Understanding the TC39 Process: How JavaScript Features Are Born
&lt;/h2&gt;

&lt;p&gt;Ever wonder how JavaScript gets new features? The TC39 committee (Technical Committee 39) meets regularly to discuss proposals, with new specifications submitted for ratification each July.&lt;/p&gt;

&lt;p&gt;Every JavaScript feature follows a structured path through five maturity stages:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 0 (Strawperson)&lt;/strong&gt;: Initial ideas that are "planned to be presented to the committee by a TC39 champion"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 1 (Proposal)&lt;/strong&gt;: The problem is formally described, and a general solution is outlined&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 2 (Draft)&lt;/strong&gt;: The syntax and semantics are precisely described in the specification language&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 3 (Candidate)&lt;/strong&gt;: Exciting features ready for implementation feedback, requiring at least one browser implementation&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 4 (Finished)&lt;/strong&gt;: Features with "at least two independent implementations that pass acceptance tests" are included in the next ECMAScript revision&lt;/p&gt;

&lt;p&gt;This process ensures that features are thoroughly tested and refined before reaching your browser. TC39 meets "every two months to discuss proposals", making the evolution of JavaScript both predictable and collaborative.&lt;/p&gt;

&lt;h2&gt;
  
  
  Browser Support: Navigating the Modern Landscape
&lt;/h2&gt;

&lt;p&gt;One of the biggest concerns developers have about adopting new features is browser support. The good news? Modern browsers implement features individually rather than entire ECMAScript versions, and "almost every modern browser is still missing features from ES2017-ES2020", but the features they do support are quite comprehensive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Resources for Checking Support
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://caniuse.com/" rel="noopener noreferrer"&gt;Can I Use&lt;/a&gt;&lt;/strong&gt;: Provides "up-to-date browser support tables for support of front-end web technologies"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MDN Compatibility Tables&lt;/strong&gt;: Detailed browser support information with usage notes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TC39 Proposals Repository&lt;/strong&gt;: Track feature progression through standardization stages&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Practical Browser Support Strategy
&lt;/h2&gt;

&lt;h3&gt;
  
  
  For Production Code:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Target features with &amp;gt;90% browser support for critical functionality&lt;/li&gt;
&lt;li&gt;Use progressive enhancement for newer features&lt;/li&gt;
&lt;li&gt;Implement feature detection rather than browser detection&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  For Modern Development:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Leverage build tools like Babel for transpilation&lt;/li&gt;
&lt;li&gt;Use TypeScript for an enhanced development experience&lt;/li&gt;
&lt;li&gt;Consider polyfills for essential missing features
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Feature detection example&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;withResolvers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Use native Promise.withResolvers()&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withResolvers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Fallback implementation&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rej&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;reject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rej&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What's Here Now vs. What's Coming
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Available Today (ES2024 and Earlier)
&lt;/h3&gt;

&lt;p&gt;These features have solid browser support and can be used in production:&lt;/p&gt;

&lt;h4&gt;
  
  
  Immutable Array Operations:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// [1, 2, 99, 4, 5]&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sorted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toSorted&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// [5, 4, 3, 2, 1]&lt;/span&gt;
&lt;span class="c1"&gt;// Original array unchanged: [1, 2, 3, 4, 5]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Set Mathematical Operations:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;union&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;setA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;union&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setB&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Set {1, 2, 3, 4, 5}&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;intersection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;setA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setB&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Set {3}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Enhanced Promise Patterns:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withResolvers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// Much cleaner than the traditional Promise constructor pattern&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Coming Soon (ES2025 and Stage 3 Proposals)
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Temporal API (Stage 3):
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Current Date API problems solved&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Temporal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plainDateISO&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Much better than new Date()&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;meeting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Temporal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PlainDate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2025-03-15&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Pattern Matching (Stage 1, but promising):
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Potential future syntax&lt;/span&gt;
&lt;span class="nf"&gt;match &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;when&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;positive&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="nx"&gt;when&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;negative&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; 
  &lt;span class="nx"&gt;when&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zero&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="nx"&gt;when&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="nx"&gt;when&lt;/span&gt; &lt;span class="nx"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;unknown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Your Action Plan: Adopting Modern JavaScript
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Immediate Steps (This Week)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Audit your current codebase for opportunities to use ES2022-ES2024 features&lt;/li&gt;
&lt;li&gt;Update your development environment to support the latest JavaScript features&lt;/li&gt;
&lt;li&gt;Review your transpilation setup to ensure you're targeting appropriate browser versions&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Short-term Goals (Next Month)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Experiment with immutable array methods in non-critical code&lt;/li&gt;
&lt;li&gt;Try Set operations for data manipulation tasks&lt;/li&gt;
&lt;li&gt;Explore Promise.withResolvers() in async workflows&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Long-term Strategy (Next Quarter)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Plan a gradual migration strategy for your team&lt;/li&gt;
&lt;li&gt;Establish coding standards that incorporate modern JavaScript patterns&lt;/li&gt;
&lt;li&gt;Stay informed about Stage 3 proposals that might affect your architecture decisions&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion: JavaScript's Bright Future
&lt;/h2&gt;

&lt;p&gt;JavaScript in 2025 represents the culmination of years of thoughtful language design and community feedback. The features we're seeing today solve real problems while maintaining backward compatibility and developer ergonomics.&lt;/p&gt;

&lt;p&gt;The key to success isn't trying to learn everything at once, but rather understanding the landscape and adopting features strategically. Start with the most impactful changes for your specific use cases, and gradually expand your toolkit as you become comfortable with each new capability.&lt;/p&gt;

&lt;p&gt;Modern JavaScript isn't just about new syntax—it's about writing code that's more maintainable, more performant, and more enjoyable to work with. Whether you're building a simple website or a complex application, these new features provide tools that will make your development experience better.&lt;/p&gt;

&lt;p&gt;Ready to dive deeper? Next week, we'll explore ES2024's immutable array methods and see how they can eliminate entire categories of bugs while making your code more predictable and easier to reason about.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This article is part of our 8-part series on modern JavaScript features. Follow along as we explore the language's evolution and learn how to leverage its latest capabilities in your projects.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next week&lt;/strong&gt;: "ES2024 Deep Dive: Array Methods That Will Change Your Code"&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>frontend</category>
      <category>html</category>
    </item>
    <item>
      <title>CSS: @starting-style a new &amp; cool at-rule</title>
      <dc:creator>Reuven Hozias</dc:creator>
      <pubDate>Wed, 27 Nov 2024 17:33:04 +0000</pubDate>
      <link>https://forem.com/hreuven/css-starting-style-a-new-cool-at-rule-171o</link>
      <guid>https://forem.com/hreuven/css-starting-style-a-new-cool-at-rule-171o</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;@starting-style&lt;/code&gt; CSS at-rule is used to define starting values for properties set on an element that you want to transition from when the element receives its first style update, i.e. when an element is first displayed on a previously loaded page.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's take a toast message as an example. To display it to the user, we will change its visibility, but the result will be that it appears immediately. Now we can use the new &lt;code&gt;@starting-style&lt;/code&gt; rule to define the starting animation for this element.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some simple examples
&lt;/h2&gt;

&lt;p&gt;Let's use this baseline HTML, a simple rectangle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;hotpink&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;h4&gt;
  
  
  Add initial &lt;code&gt;background-color&lt;/code&gt; transition from blue to pink
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;...
  &lt;/span&gt;&lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;background-color&lt;/span&gt; &lt;span class="m"&gt;4s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@starting-style&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.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%2F7nppyom7dk5blffgbbg3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F7nppyom7dk5blffgbbg3.gif" alt="Image description" width="240" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Add rotation to the previous example
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;...
  &lt;/span&gt;&lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt; &lt;span class="m"&gt;4s&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;background-color&lt;/span&gt; &lt;span class="m"&gt;4s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;);}&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@starting-style&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;360deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.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%2Fya76863zgcgvsp0foinl.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fya76863zgcgvsp0foinl.gif" alt="Image description" width="240" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anyways, you get the idea. &lt;br&gt;
Animate your popups, and menus or create an animated logo,&lt;br&gt;
It's straightforward.&lt;/p&gt;

&lt;h2&gt;
  
  
  NOTE
&lt;/h2&gt;

&lt;p&gt;This feature currently has &lt;a href="https://caniuse.com/?search=%40starting-style" rel="noopener noreferrer"&gt;limited availability&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>design</category>
      <category>html</category>
    </item>
    <item>
      <title>CSS: Easy dark mode</title>
      <dc:creator>Reuven Hozias</dc:creator>
      <pubDate>Thu, 14 Nov 2024 10:19:50 +0000</pubDate>
      <link>https://forem.com/hreuven/css-easy-dark-mode-320</link>
      <guid>https://forem.com/hreuven/css-easy-dark-mode-320</guid>
      <description>&lt;p&gt;A dark mode is a display option that switches the color theme of a website or application from a light background (with dark text) to a dark background (with light text). This mode has grown popular for its benefits in reducing eye strain in low-light environments, saving energy on devices with OLED screens, and offering a visually appealing alternative to traditional light themes.&lt;br&gt;
Usually, you can toggle between 3 modes: dark, light and System theme setting.&lt;/p&gt;
&lt;h1&gt;
  
  
  Old way
&lt;/h1&gt;

&lt;p&gt;Till now we've used the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme" rel="noopener noreferrer"&gt;prefers-color-scheme&lt;/a&gt; CSS media feature:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The prefers-color-scheme CSS media feature is used to detect if a user has requested light or dark color themes. A user indicates their preference through an operating system setting (e.g. light or dark mode) or a user agent setting.&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefers-color-scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.post&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#753&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#dcb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefers-color-scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.post&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#bcd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#334&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we need to maintain 2 themes, one for each mode.&lt;br&gt;
Taking this approach in a large-scale application may be difficult.&lt;/p&gt;
&lt;h2&gt;
  
  
  New and better way
&lt;/h2&gt;

&lt;p&gt;Luckily, CSS has introduced a new property to make our life easier, &lt;code&gt;light-dark()&lt;/code&gt; and it is &lt;a href="https://caniuse.com/?search=light-dark" rel="noopener noreferrer"&gt;supported&lt;/a&gt; by all major browsers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The light-dark() CSS  function enables setting two colors for a property - returning one of the two colors options by detecting if the developer has set a light or dark color scheme or the user has requested light or dark color theme - without needing to encase the theme colors within a prefers-color-scheme media feature query.&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;color-scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;light-dark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;#292524&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#f5f5f4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;light-dark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;#f5f5f4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#292524&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just use the &lt;code&gt;light-dark()&lt;/code&gt; property on each element we wish to toggle between modes, that's it!&lt;/p&gt;

</description>
      <category>html</category>
      <category>webdev</category>
      <category>css</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>CSS: masonry layout</title>
      <dc:creator>Reuven Hozias</dc:creator>
      <pubDate>Wed, 06 Nov 2024 08:51:12 +0000</pubDate>
      <link>https://forem.com/hreuven/css-masonry-layout-1jff</link>
      <guid>https://forem.com/hreuven/css-masonry-layout-1jff</guid>
      <description>&lt;p&gt;What is masonry layout?&lt;/p&gt;

&lt;p&gt;from MDN:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Masonry layout is a layout method where one axis uses a typical strict grid layout, most often columns, and the other a masonry layout. On the masonry axis, rather than sticking to a strict grid with gaps being left after shorter items, the items in the following row rise up to completely fill the gaps.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;pinterest.com's layout is one classic example of it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fvr1t1llna9ruutqd59kh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fvr1t1llna9ruutqd59kh.png" alt="Image description" width="695" height="727"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What can we use from our CSS toolbox?&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;grid&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;We use a simple HTML markup:&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;"photos"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./img/image-1.jpg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"sample"&lt;/span&gt;&lt;span class="nt"&gt;&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;My first shot was &lt;code&gt;grid&lt;/code&gt; &amp;amp; &lt;code&gt;grid-template-column&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.photos&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto-fill&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="err"&gt;img{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.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%2Fsdvxdk4od2oz85gzwo7j.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fsdvxdk4od2oz85gzwo7j.gif" alt="Image description" width="500" height="351"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The responsiveness is great, but we have gaps below each image.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;column-count&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;next, use the &lt;code&gt;column-count&lt;/code&gt; CSS container property.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The column-count CSS property breaks an element's content into the specified number of columns.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.photos&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;column-count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="err"&gt;img{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.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%2Fy33p4gsqgl110l8hq6p2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fy33p4gsqgl110l8hq6p2.gif" alt="Image description" width="800" height="663"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not good.&lt;br&gt;
The current layout looks as desired, but the images are scaled and not responsive. While we could use media queries to control responsiveness, we’re aiming for a more robust solution.&lt;/p&gt;
&lt;h2&gt;
  
  
  Using &lt;code&gt;columns&lt;/code&gt;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;The columns CSS shorthand property sets the number of columns to use when drawing an element's contents, as well as those columns' widths.&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.photos&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;250px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="err"&gt;img{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.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%2F9ck3k2h31wz65g2hsxo1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F9ck3k2h31wz65g2hsxo1.gif" alt="Image description" width="500" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A single line of code. Amazing!&lt;/p&gt;

&lt;h2&gt;
  
  
  How does this work?
&lt;/h2&gt;

&lt;p&gt;Each column is given a minimum width of 250px. If there is extra space beyond 250px, the columns will expand to fill the space. If the space is reduced, the number of columns will decrease accordingly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extras
&lt;/h2&gt;

&lt;p&gt;We can limit the number of columns by setting the layout to a maximum of X columns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.photos&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;250px&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="err"&gt;...&lt;/span&gt;
  &lt;span class="err"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.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%2Fzmwkqw7qqf868ci4s72t.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fzmwkqw7qqf868ci4s72t.gif" alt="Image description" width="800" height="608"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;columns&lt;br&gt;
 is not limited to masonry image layouts alone. We can also use it to style text columns: same CSS, different content.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fsceciklvr7nq0gle4i37.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fsceciklvr7nq0gle4i37.gif" alt="Image description" width="800" height="483"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Was this helpful?&lt;br&gt;
What was your use case?&lt;/p&gt;

</description>
      <category>html</category>
      <category>css</category>
      <category>webdev</category>
      <category>design</category>
    </item>
    <item>
      <title>CSS-only tooltip using popover &amp; anchor</title>
      <dc:creator>Reuven Hozias</dc:creator>
      <pubDate>Tue, 22 Oct 2024 08:27:09 +0000</pubDate>
      <link>https://forem.com/hreuven/css-only-tooltip-using-popover-anchor-2d4o</link>
      <guid>https://forem.com/hreuven/css-only-tooltip-using-popover-anchor-2d4o</guid>
      <description>&lt;p&gt;To improve performance in a project I'm working on, I'm refactoring some components and replacing them with more native implementations.&lt;br&gt;
In this post, I will start with a component that we use widely: the tooltip. I will use two relatively new features: the Popover API and Anchor CSS.&lt;/p&gt;

&lt;p&gt;Popover API and Anchor CSS:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Popover API provides developers with a standard, consistent, flexible mechanism for displaying popover content on top of other page content. Popover content can be controlled declaratively using HTML attributes or JavaScript.&lt;/p&gt;

&lt;p&gt;The anchor() CSS function can be used within an anchor-positioned element's inset property values, returning a length value relative to the position of the edges of its associated anchor element.&lt;/p&gt;
&lt;h2&gt;
  
  
  🤔
&lt;/h2&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Our baseline
&lt;/h2&gt;

&lt;p&gt;Let's start with a basic info icon that will serve as our tooltip opener,&lt;br&gt;
Nothing fancy here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"info-icon"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Popover API
&lt;/h2&gt;

&lt;p&gt;We're adding an information div, marking it as a &lt;code&gt;popover&lt;/code&gt; and passing a unique &lt;code&gt;id&lt;/code&gt; to it. &lt;code&gt;popovertarget&lt;/code&gt; property is added to the icon, excepting the popover &lt;code&gt;id&lt;/code&gt; string.&lt;br&gt;
note that &lt;code&gt;popovertarget&lt;/code&gt; can be only of type &lt;code&gt;button&lt;/code&gt; or &lt;code&gt;input&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;button&lt;/span&gt; &lt;span class="na"&gt;popovertarget=&lt;/span&gt;&lt;span class="s"&gt;"info"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"info-icon"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"info"&lt;/span&gt; &lt;span class="na"&gt;popover&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Lorem ipsum dolor sit amet&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;Clicking the info button toggles the popover visibility, and clicking outside closes it. This initial implementation results in a more modal-style element.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F4zjy9p0qh06n3kd6gczo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F4zjy9p0qh06n3kd6gczo.gif" alt="Image description" width="575" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's go one step further, and position the tooltip using the &lt;code&gt;anchor&lt;/code&gt; CSS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding anchor CSS
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;anchor&lt;/code&gt; CSS is still experimental but getting adopted quickly by all major browsers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All major browser engines are working on implementing this spec.&lt;br&gt;
Can be enabled via the #enable-experimental-web-platform-features flag in chrome://flags&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We'll add the &lt;code&gt;anchor&lt;/code&gt; property to our info div. It expects a string &lt;code&gt;id&lt;/code&gt; of the element we're anchoring to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"info-opener"&lt;/span&gt;
        &lt;span class="na"&gt;popovertarget=&lt;/span&gt;&lt;span class="s"&gt;"info"&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"info-icon"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"info"&lt;/span&gt; &lt;span class="na"&gt;popover=&lt;/span&gt;&lt;span class="s"&gt;"auto"&lt;/span&gt; &lt;span class="na"&gt;anchor=&lt;/span&gt;&lt;span class="s"&gt;"info-opener"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Lorem ipsum dolor sit amet
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Placing the tooltip
&lt;/h2&gt;

&lt;p&gt;To position the target tooltip beside the anchor (info icon), we'll use the anchor() CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"info-opener"&lt;/span&gt;
        &lt;span class="na"&gt;popovertarget=&lt;/span&gt;&lt;span class="s"&gt;"info"&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"info-icon"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"info"&lt;/span&gt;
     &lt;span class="na"&gt;popover=&lt;/span&gt;&lt;span class="s"&gt;"auto"&lt;/span&gt;
     &lt;span class="na"&gt;anchor=&lt;/span&gt;&lt;span class="s"&gt;"info-opener"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"info-tooltip left"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Lorem ipsum dolor sit amet
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.left&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;.75rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;clip-path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;polygon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="m"&gt;100%&lt;/span&gt; &lt;span class="m"&gt;0%&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;100%&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;5px&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;5px&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;50%&lt;/span&gt; &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="m"&gt;0%&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;5px&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;50%&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="m"&gt;5px&lt;/span&gt; &lt;span class="m"&gt;0%&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.info-tooltip&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;popover&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#007bff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.info-tooltip&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;popover&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;anchor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;anchor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-50%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which results in:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fisoyitbnrl3adcox483m.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fisoyitbnrl3adcox483m.gif" alt="Image description" width="401" height="260"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Breaking it down
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;.info-tooltip&lt;/code&gt; class styles the element and adds anchor-like functionality.&lt;/p&gt;

&lt;p&gt;What does this anchoring do? It attaches the tooltip to a logical grid cell—one of a 3 by 3 grid representing our info element.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;left&lt;/code&gt; property aligns the tooltip's left side with the info element's right side, adding 2px of space. The &lt;code&gt;top&lt;/code&gt; property centers the tooltip vertically to the tooltip's midpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some extras
&lt;/h2&gt;

&lt;p&gt;The popover property accepts two values:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;auto&lt;/code&gt;: This is the default behavior. Click anywhere on the page to &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;toggle&lt;/code&gt;: the popover visibility.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;manual&lt;/code&gt;: Toggles the visibility only by clicking the opener element.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another property that can be utilized from the opener element is popoverTargetAction:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;toggle&lt;/code&gt;: This is the default action— as the name implies, it toggles the visibility.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;show&lt;/code&gt;: Only triggers showing the popover; you can’t close it.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;hide&lt;/code&gt;: Only hides the popover.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;We briefly covered two relatively new features: the &lt;a href="https://caniuse.com/?search=popover" rel="noopener noreferrer"&gt;Popover&lt;/a&gt; API and the CSS anchor() feature. Both are extremely powerful and combining them can enable amazing, JavaScript-free functionality.&lt;/p&gt;

&lt;p&gt;As mentioned, both are relatively new. The Popover API has wide browser support and can be safely used. The &lt;a href="https://caniuse.com/css-anchor-positioning" rel="noopener noreferrer"&gt;anchor()&lt;/a&gt; feature, on the other hand, is still experimental and is not yet recommended for use in production environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next up
&lt;/h2&gt;

&lt;p&gt;In upcoming posts, I’ll demonstrate more advanced usage of these features. Stay tuned!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
      <category>ux</category>
      <category>html</category>
    </item>
    <item>
      <title>CSS: select all siblings using not()</title>
      <dc:creator>Reuven Hozias</dc:creator>
      <pubDate>Mon, 21 Oct 2024 15:51:44 +0000</pubDate>
      <link>https://forem.com/hreuven/css-select-all-siblings-using-not-50bb</link>
      <guid>https://forem.com/hreuven/css-select-all-siblings-using-not-50bb</guid>
      <description>&lt;p&gt;Our UX team wanted me to create a navigation menu that dims the rest of the items instead of highlighting the hovered item.&lt;/p&gt;

&lt;h2&gt;
  
  
  CSS to the rescue!
&lt;/h2&gt;

&lt;p&gt;The solution is quite simple when using the CSS &lt;code&gt;not()&lt;/code&gt; pseudo-class:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fai0m60pyfo92h5w0cr6l.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fai0m60pyfo92h5w0cr6l.gif" alt="Image description" width="378" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The HTML
&lt;/h2&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;"menu-items"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Home&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;About&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;Contact&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;Services&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;Blog&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;Portfolio&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;h2&gt;
  
  
  The SCSS
&lt;/h2&gt;

&lt;p&gt;I've removed the styling properties so we can focus on the actual functionality:&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="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;menu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;    
&lt;span class="mi"&gt;2&lt;/span&gt;     &lt;span class="nx"&gt;visibility&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt; 
&lt;span class="mi"&gt;4&lt;/span&gt;     &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt;         &lt;span class="na"&gt;visibility&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;visible&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="mi"&gt;6&lt;/span&gt;         &lt;span class="na"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;opacity&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="nx"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="mi"&gt;7&lt;/span&gt;     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="mi"&gt;8&lt;/span&gt; 
&lt;span class="mi"&gt;9&lt;/span&gt;     &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;hover&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;not&lt;/span&gt;&lt;span class="p"&gt;(:&lt;/span&gt;&lt;span class="nx"&gt;hover&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="mi"&gt;10&lt;/span&gt;        &lt;span class="nx"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.45&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="mi"&gt;11&lt;/span&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have a container with a &lt;code&gt;.menu-items&lt;/code&gt; class.&lt;br&gt;
In line #4, we're selecting all its child elements and adding an opacity animation transition to them.&lt;/p&gt;

&lt;p&gt;Line #9 handles the hover effect on elements by setting the opacity of all &lt;strong&gt;non-hovered&lt;/strong&gt; elements using the &lt;code&gt;not()&lt;/code&gt; pseudo-class to a lower value.&lt;/p&gt;

&lt;p&gt;And what's going on with the &lt;code&gt;visibility&lt;/code&gt; property?&lt;br&gt;
We're setting the visibility of the &lt;code&gt;.menu-items&lt;/code&gt; container to &lt;code&gt;hidden&lt;/code&gt; and then setting the child elements back to &lt;code&gt;visible&lt;/code&gt;. This causes the effect to turn off when we hover between the elements.&lt;/p&gt;

&lt;p&gt;That's it :)&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
      <category>scss</category>
      <category>ui</category>
    </item>
    <item>
      <title>React 19 new features - the 'use' hook</title>
      <dc:creator>Reuven Hozias</dc:creator>
      <pubDate>Wed, 09 Oct 2024 06:14:55 +0000</pubDate>
      <link>https://forem.com/hreuven/react-19-new-features-the-use-hook-4e8b</link>
      <guid>https://forem.com/hreuven/react-19-new-features-the-use-hook-4e8b</guid>
      <description>&lt;p&gt;&lt;strong&gt;React 19&lt;/strong&gt; (RC version—as of September 2024) is the latest release of the popular web development library.&lt;br&gt;
V19 is a significant milestone, bringing many new features and hooks. This post will discuss one of these hooks, the &lt;code&gt;use&lt;/code&gt; hook.&lt;/p&gt;
&lt;h2&gt;
  
  
  The &lt;code&gt;use&lt;/code&gt; hook
&lt;/h2&gt;

&lt;p&gt;This hook allows developers to suspend the rendering of a UI component until an asynchronous task, such as fetching data or loading resources, is completed by suspending the received promise, without the need for complex state management.&lt;/p&gt;
&lt;h2&gt;
  
  
  Fetching data example
&lt;/h2&gt;

&lt;p&gt;Our simple component follows the classic approach, using the &lt;code&gt;useEffect&lt;/code&gt; hook to fetch data from a mock API (MSW in my case). We manage the local state to store the data, along with isLoading and isError states to track the fetch status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUsers&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsError&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsLoading&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the page first loads, we run this &lt;code&gt;useEffect&lt;/code&gt; hook to fetch the data, store it, and update the various states:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setUsers&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setIsError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setIsLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We show some UI while the request is being processed or if we encounter an error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Error&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and finally! We render the users list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; 
  &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;, &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A lot of boilerplate code!&lt;/p&gt;

&lt;h2&gt;
  
  
  Now, let’s refactor!
&lt;/h2&gt;

&lt;p&gt;Let’s remove the &lt;code&gt;useState&lt;/code&gt; and &lt;code&gt;useEffect&lt;/code&gt; hooks. We will keep the &lt;code&gt;fetchData&lt;/code&gt; method as it is.&lt;br&gt;
Now we will fetch the data using the new &lt;code&gt;use&lt;/code&gt; hook, which takes a promise and returns either JSON data or an error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The way this hook works is similar to doing something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Handling &lt;code&gt;isLoading&lt;/code&gt; and &lt;code&gt;isError&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;To handle these state changes, we’ll go to our App component. We’ll use the React &lt;code&gt;Suspense&lt;/code&gt; component, which is designed to respond to asynchronous events. It displays a fallback UI until its children have finished loading.&lt;/p&gt;

&lt;p&gt;For error handling when working with &lt;code&gt;Suspense&lt;/code&gt;, it’s common practice to use an &lt;code&gt;ErrorBoundary&lt;/code&gt;. We’ll add an &lt;code&gt;ErrorBoundary&lt;/code&gt; &lt;a href="https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary" rel="noopener noreferrer"&gt;component&lt;/a&gt; that implements React’s &lt;code&gt;getDerivedStateFromError()&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ErrorBoundary&lt;/span&gt; &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Error&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt; &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserList&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ErrorBoundary&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The refactor phase is completed!&lt;/p&gt;

&lt;h2&gt;
  
  
  Some extra’s
&lt;/h2&gt;

&lt;p&gt;The usual rules for hooks do not apply here — you can use this hook anywhere you'd like!&lt;/p&gt;

&lt;p&gt;Unlike regular hooks, the use hook can be used conditionally with an if statement, allowing you to decide whether to trigger it or not. For example, if you want to wrap a new API request with a feature flag and toggle it for testing, simply pass the feature flag to the &lt;code&gt;UserList&lt;/code&gt; component and wrap the use hook. It's that simple!&lt;/p&gt;

&lt;p&gt;Let's modify the &lt;code&gt;App&lt;/code&gt; component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ErrorBoundary&lt;/span&gt; &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Error&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt; &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserList&lt;/span&gt; &lt;span class="na"&gt;testNewApi&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ErrorBoundary&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify the &lt;code&gt;UserList&lt;/code&gt; component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;testNewApi&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use this hook to obtain a &lt;code&gt;Context&lt;/code&gt; object, rather than using the regular method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use the &lt;code&gt;use&lt;/code&gt; hook here, for example, if you want to retrieve the context based on a conditional statement.&lt;/p&gt;

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

&lt;p&gt;In this article, I've outlined the syntax of the &lt;code&gt;use&lt;/code&gt; hook and provided usage examples. This should help you grasp this hook and how to use it effectively. I hope you find this information beneficial for your future projects.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react19</category>
      <category>react</category>
    </item>
  </channel>
</rss>
