<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Jesse Hall - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Jesse Hall - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 25 May 2026 10:48:51 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/codeSTACKr/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Understanding Modern Development Frameworks: A Guide for Developers and Technical Decision-makers ]]>
                </title>
                <description>
                    <![CDATA[ As a developer for over 20 years, I've seen firsthand how choosing the right framework can make or break a project. The term "framework" has become so broad that it's often misunderstood. Let's clear up the confusion and help you make better technica... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/understanding-modern-development-frameworks-guide-for-devs/</link>
                <guid isPermaLink="false">673cc307f6df251b434f7f90</guid>
                
                    <category>
                        <![CDATA[ Developer ]]>
                    </category>
                
                    <category>
                        <![CDATA[ framework ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Jesse Hall ]]>
                </dc:creator>
                <pubDate>Tue, 19 Nov 2024 16:55:35 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1731968979425/412c6bc7-e717-481b-aa9e-4962c9687115.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>As a developer for over 20 years, I've seen firsthand how choosing the right framework can make or break a project. The term "framework" has become so broad that it's often misunderstood. Let's clear up the confusion and help you make better technical decisions.</p>
<h2 id="heading-what-is-a-framework">What is a Framework?</h2>
<p>In terms of software development, a framework is a structured set of tools, libraries, and conventions that provides a foundation for building applications more efficiently by handling common functionalities so developers can focus on unique features.</p>
<p>A modern web application can combine multiple frameworks to handle different aspects of development efficiently:</p>
<ul>
<li><p>React with Tailwind CSS manages the user interface and styling.</p>
</li>
<li><p>FastAPI or Django with LangChain handle backend operations and AI functionality, while MongoDB acts as a memory store.</p>
</li>
</ul>
<p>These frameworks communicate through APIs and defined interfaces to work together—for example, a user interaction in the React front end can trigger an AI process through LangChain in the Python back end, which uses MongoDB Atlas Vector Search to retrieve relevant data and then display it back to the user with Tailwind CSS styles.</p>
<h2 id="heading-table-of-contents">Table of Contents:</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-the-framework-landscape-in-2024">The framework landscape in 2024</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-application-frameworks">Application frameworks</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-ai-frameworks">AI frameworks</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-web-frameworks">Web frameworks</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-cssui-frameworks">CSS/UI frameworks</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-testing-amp-infrastructure">Testing &amp; infrastructure</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-making-the-right-choice">Making the right choice</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-bottom-line">The bottom line</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-additional-resources">Additional resources</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-frequently-asked-questions-faq">Frequently asked questions (FAQ)</a></p>
</li>
</ul>
<h2 id="heading-the-framework-landscape-in-2024">The Framework Landscape in 2024</h2>
<p>Think of frameworks as tools in a technical toolbox. Understanding what each tool is designed to do—and what it isn't—ensures you use the right solution for the task at hand.</p>
<h3 id="heading-the-evolution-of-development-frameworks">The Evolution of Development Frameworks</h3>
<p>The framework landscape has transformed dramatically over the past decade. What started as simple libraries for rendering web pages has evolved into sophisticated ecosystems that can:</p>
<ul>
<li><p>Handle complex state management.</p>
</li>
<li><p>Process real-time data streams.</p>
</li>
<li><p>Integrate AI capabilities.</p>
</li>
<li><p>Scale automatically based on demand.</p>
</li>
<li><p>Deploy across multiple platforms from a single codebase.</p>
</li>
</ul>
<h3 id="heading-why-framework-choice-matters">Why Framework Choice Matters</h3>
<p>Frameworks are puzzle pieces: each has a unique shape and function. When chosen wisely, they fit together seamlessly to create a cohesive application. But forcing incompatible pieces together can lead to inefficiencies and broken functionality.</p>
<p>Here's why your choice matters:</p>
<h4 id="heading-technical-impact">Technical impact</h4>
<ul>
<li><p><strong>Performance</strong>: Different frameworks have different performance characteristics. Instagram chose React for its virtual DOM, which handles frequent updates efficiently.</p>
</li>
<li><p><strong>Scalability</strong>: Uber's back end uses Node.js because it excels at handling numerous concurrent connections.</p>
</li>
<li><p><strong>Maintenance</strong>: Shopify standardized on React Native to maintain a single codebase for mobile applications.</p>
</li>
</ul>
<h4 id="heading-business-impact">Business impact</h4>
<ul>
<li><p><strong>Development speed</strong>: The right framework can accelerate development by 2-3x.</p>
</li>
<li><p><strong>Team productivity</strong>: Familiar frameworks reduce onboarding time from months to weeks.</p>
</li>
<li><p><strong>Cost efficiency</strong>: Proper framework selection can significantly reduce hosting and maintenance costs.</p>
</li>
</ul>
<h4 id="heading-common-pitfalls">Common pitfalls</h4>
<ul>
<li><p><strong>Over-engineering</strong>: Using Next.js when a simple HTML page would suffice</p>
</li>
<li><p><strong>Under-engineering</strong>: Using vanilla JavaScript for a complex, state-heavy application</p>
</li>
<li><p><strong>Misaligned tools</strong>: Using Electron (a desktop app framework) to build a simple website</p>
</li>
<li><p><strong>Trend-chasing</strong>: Adopting the newest framework without considering maintenance implications</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731967899960/8c8b60fb-4370-4bb1-91fd-5b8b18db22e9.png" alt="A diagram of frameworks and their categorizations" width="5971" height="3417" loading="lazy"></p>
<p>Let’s dive deeper into the various categories of development frameworks and how they can help you build better applications.</p>
<p><strong>Note</strong>: I give framework examples throughout this article, but these are not exhaustive lists and new frameworks are created <code>daily|weekly|monthly</code>.</p>
<h2 id="heading-application-frameworks">Application Frameworks</h2>
<p>These are your Swiss Army knives of development—comprehensive toolkits that handle the entire application lifecycle. While each framework has its specialties, they typically provide:</p>
<ul>
<li><p>Database integration and ORM support.</p>
</li>
<li><p>Authentication and authorization.</p>
</li>
<li><p>API routing and middleware.</p>
</li>
<li><p>Template engines or component systems.</p>
</li>
<li><p>Asset management.</p>
</li>
<li><p>Security features.</p>
</li>
<li><p>Development tools and debugging support.</p>
</li>
</ul>
<p><strong>What is an application?</strong> An application is the combination of individual components working together, including a user interface and backend services, to perform specific functions or a set of functions for users. It’s designed to be fully deployable and operate in production environments.</p>
<p>You'll encounter them in three main flavors:</p>
<h3 id="heading-full-stack-web-application-frameworks">Full-Stack Web Application Frameworks</h3>
<ul>
<li><p><a target="_blank" href="https://www.djangoproject.com/"><strong>Django</strong></a> <strong>and</strong> <a target="_blank" href="https://rubyonrails.org/"><strong>Rails</strong></a>: Perfect for data-heavy applications with complex business logic. They follow the "batteries included" philosophy, providing everything you need out of the box.</p>
</li>
<li><p><a target="_blank" href="https://nextjs.org/"><strong>Next.js</strong></a> <strong>and</strong> <a target="_blank" href="https://nuxtjs.org/"><strong>Nuxt.js</strong></a>: Modern full-stack frameworks optimized for React and Vue.js, respectively. They excel at building performant applications with capabilities like server-side rendering, static site generation, and API integration.</p>
</li>
<li><p><a target="_blank" href="https://spring.io/projects/spring-boot"><strong>Spring Boot</strong></a>: Enterprise-grade framework favored for large-scale Java applications, particularly in financial and banking sectors.</p>
</li>
</ul>
<h3 id="heading-mobile-application-frameworks">Mobile Application Frameworks</h3>
<ul>
<li><p><a target="_blank" href="https://flutter.dev/"><strong>Flutter</strong></a>: Google's toolkit for building natively compiled apps for mobile, web, and desktop from a single codebase. Known for smooth animations and native performance.</p>
</li>
<li><p><a target="_blank" href="https://reactnative.dev/"><strong>React Native</strong></a>: Ideal when you want to leverage your team's React knowledge for mobile development. Great for apps that need to feel native while maintaining code sharing between platforms.</p>
</li>
<li><p><a target="_blank" href="https://developer.apple.com/xcode/swiftui/"><strong>SwiftUI</strong></a> <strong>and</strong> <a target="_blank" href="https://developer.android.com/jetpack/compose"><strong>Jetpack Compose</strong></a>: Native frameworks for iOS and Android, respectively. Ideal when platform-specific features and optimal performance are crucial.</p>
</li>
</ul>
<h3 id="heading-desktop-application-frameworks">Desktop Application Frameworks</h3>
<ul>
<li><p><a target="_blank" href="https://www.electronjs.org/"><strong>Electron</strong></a>: Powers apps like VS Code and Slack. Ideal for leveraging existing web development knowledge without having to learn OS-specific languages to build cross-platform desktop applications.</p>
</li>
<li><p><a target="_blank" href="https://tauri.app/"><strong>Tauri</strong></a>: A modern alternative to Electron with smaller bundle sizes and better performance. Uses native system webviews to run apps more efficiently, with less memory and faster startup times. Developers can use their existing web development skills without learning new programming languages for each OS.</p>
</li>
<li><p><a target="_blank" href="https://wiki.python.org/moin/PyQt"><strong>PyQt</strong></a>: A good option for building GUI applications in Python, especially for data science projects. It has a rich set of libraries and widgets, suitable for both small tools and complex apps.</p>
</li>
</ul>
<h3 id="heading-gaming-frameworks">Gaming Frameworks</h3>
<ul>
<li><p><a target="_blank" href="https://unity.com/"><strong>Unity</strong></a>: A popular framework used for creating 2D and 3D games. It supports multiple platforms, making it a versatile choice for game developers. Unity is known for its user-friendly interface and extensive asset store.</p>
</li>
<li><p><a target="_blank" href="https://www.unrealengine.com/"><strong>Unreal Engine</strong></a>: Known for its high-quality graphics, Unreal Engine is a powerful framework used for both AAA games and indie projects. It provides advanced visual tools and real-time rendering capabilities.</p>
</li>
<li><p><a target="_blank" href="https://godotengine.org/"><strong>Godot</strong></a>: An open-source game engine that's lightweight and flexible. Godot is often used for smaller or indie game projects and features an intuitive scene system that makes development straightforward.</p>
</li>
</ul>
<h2 id="heading-ai-frameworks">AI Frameworks</h2>
<p>Here's a crucial point many miss: AI frameworks like TensorFlow or LangChain are powerful, but they're not standalone solutions. These frameworks require integration with other tools and frameworks for data handling, user interface, and deployment to create a complete, production-ready application. These are just another piece of the puzzle.</p>
<p><strong>The exception?</strong> Data scientists can use these tools directly in Jupyter notebooks for research and prototyping. But for production applications, you'll need more.</p>
<p>Let's look at the major players and their sweet spots:</p>
<h3 id="heading-ai-model-development-frameworks">AI Model Development Frameworks</h3>
<ul>
<li><p><a target="_blank" href="https://www.tensorflow.org/"><strong>TensorFlow</strong></a>: Google's powerhouse for deep learning, TensorFlow is perfect for applications involving computer vision, neural networks, and production-grade ML. Pinterest uses it for image recognition and recommendations, highlighting its strength in processing large amounts of image data efficiently.</p>
</li>
<li><p><a target="_blank" href="https://pytorch.org/"><strong>PyTorch</strong></a>: Developed by Facebook, PyTorch is a flexible framework ideal for research, natural language processing, and quick prototyping. Tesla has utilized PyTorch for various machine learning tasks, including research related to autonomous driving vision systems, demonstrating its versatility in cutting-edge applications.</p>
</li>
<li><p><a target="_blank" href="https://github.com/google/jax"><strong>JAX</strong></a>: A high-performance numerical computing framework by Google, JAX is well-suited for scientific computing and large-scale transformers. DeepMind has used JAX for advanced AI research, including projects like AlphaFold for protein structure prediction, showcasing its effectiveness in large-scale computational problems.</p>
</li>
</ul>
<h3 id="heading-ai-model-deployment-and-serving-frameworks">AI Model Deployment and Serving Frameworks</h3>
<ul>
<li><p><a target="_blank" href="https://github.com/tensorflow/serving"><strong>TensorFlow Serving</strong></a>: A deployment tool for TensorFlow models, perfect for serving high-performance ML models in production environments. For example, it has been used to serve image classification models for e-commerce platforms, ensuring rapid and scalable response times.</p>
</li>
<li><p><a target="_blank" href="https://pytorch.org/serve/"><strong>TorchServe</strong></a>: A robust tool for deploying PyTorch models, perfect for scalable PyTorch model serving. It has been used for deploying chatbot models for real-time customer support, providing flexibility and efficiency in managing conversational AI.</p>
</li>
<li><p><a target="_blank" href="https://developer.nvidia.com/triton-inference-server"><strong>NVIDIA Triton Inference Server</strong></a>: A multi-framework model serving tool, NVIDIA Triton Inference Server is capable of handling models from TensorFlow, PyTorch, ONNX, and more. It is ideal for managing inference requests for multi-modal AI applications, making it highly suitable for complex AI deployments.</p>
</li>
</ul>
<h3 id="heading-llm-integration-frameworks">LLM Integration Frameworks</h3>
<ul>
<li><p><a target="_blank" href="https://langchain.io/"><strong>LangChain</strong></a>: The Swiss Army knife for LLM applications. Ideal for building chatbots and document Q&amp;A systems. It has been employed to create customer service bots capable of accessing company knowledge bases, demonstrating its usefulness in enhancing customer interactions.</p>
</li>
<li><p><a target="_blank" href="https://www.llamaindex.ai/"><strong>LlamaIndex</strong></a>: Specializing in data connection, LlamaIndex is perfect for building search engines over private data. It has been used to create semantic search systems for internal documents, facilitating more effective data retrieval and organizational knowledge management.</p>
</li>
<li><p><a target="_blank" href="https://huggingface.co/docs/transformers/en/index"><strong>Hugging Face Transformers</strong></a>: A pre-trained model hub, Hugging Face Transformers allows for the quick deployment of state-of-the-art models. It has been used to add sentiment analysis to customer feedback systems, highlighting its capability in natural language understanding.</p>
</li>
</ul>
<h3 id="heading-ai-data-processing-frameworks">AI Data Processing Frameworks</h3>
<ul>
<li><p><a target="_blank" href="https://spark.apache.org/mllib/"><strong>Apache Spark (MLlib)</strong></a>: Ideal for large-scale data transformation and ML, used for processing millions of user interactions in recommendation systems. Its scalability and efficiency make it a popular choice for big data ML tasks.</p>
</li>
<li><p><a target="_blank" href="https://pandas.pydata.org/"><strong>Pandas</strong></a>: A widely-used data manipulation and analysis tool that is perfect for data cleaning, analysis, and feature engineering. It is often employed in preparing customer data for churn prediction models, owing to its intuitive data handling capabilities.</p>
</li>
<li><p><a target="_blank" href="https://www.pola.rs/"><strong>Polars</strong></a>: A high-performance data manipulation framework, used when Pandas is not fast enough for processing requirements. It has been applied in real-time financial data analysis, delivering faster data processing and efficiency.</p>
</li>
</ul>
<h3 id="heading-ai-automation-and-orchestration-frameworks">AI Automation and Orchestration Frameworks</h3>
<ul>
<li><p><a target="_blank" href="https://crewai.com/"><strong>CrewAI</strong></a>: Used to orchestrate multiple AI agents, making it perfect for complex workflows requiring multiple AI models. It has been used to create a content creation pipeline that plans, writes, and edits, showcasing its ability to automate creative processes.</p>
</li>
<li><p><a target="_blank" href="https://github.com/Torantulino/Auto-GPT"><strong>Auto-GPT</strong></a>: Develops autonomous AI agents, ideal for self-directed task completion. It has been utilized for automated research and data gathering, highlighting its potential for automating repetitive knowledge tasks.</p>
</li>
<li><p><a target="_blank" href="https://github.com/microsoft/semantic-kernel"><strong>Microsoft Semantic Kernel</strong></a>: An AI orchestration tool perfect for integrating AI into .NET applications. It has been used to add AI capabilities to existing enterprise applications, providing a seamless integration of AI functions into established workflows.</p>
</li>
</ul>
<h3 id="heading-ai-data-ingestion-and-document-processing-frameworks">AI Data Ingestion and Document Processing Frameworks</h3>
<ul>
<li><p><a target="_blank" href="https://nifi.apache.org/"><strong>Apache NiFi</strong></a>: A powerful tool for data flow automation, well-suited for real-time data ingestion and processing. It has been used to extract and transform log data before analysis, ensuring efficient data flow for various use cases.</p>
</li>
<li><p><a target="_blank" href="https://haystack.deepset.ai/"><strong>Haystack</strong></a>: Specialized in document processing for search and QA systems. It has been utilized to create pipelines for indexing documents and answering questions, making it ideal for building internal knowledge base searches.</p>
</li>
<li><p><a target="_blank" href="https://unstructured.io/"><strong>Unstructured</strong></a>: Designed for extracting data from a variety of formats, including PDFs, HTML, and images. It’s perfect for handling unstructured content in document processing workflows and has been used to extract relevant information from scanned documents for data analysis.</p>
</li>
<li><p><a target="_blank" href="https://airbyte.com/"><strong>Airbyte</strong></a>: An open-source data integration tool that is ideal for connecting and syncing data across multiple sources. It has been used to ingest data from third-party APIs into analytics systems, enabling effective data consolidation.</p>
</li>
</ul>
<h3 id="heading-interactive-ai-web-frameworks">Interactive AI Web Frameworks</h3>
<ul>
<li><p><a target="_blank" href="https://gradio.app/"><strong>Gradio</strong></a>: Simplifies the process of building web UIs for machine learning models, making it perfect for creating quick demos for ML models. It has been used to create interactive image classifiers for end users, providing an accessible interface for testing ML capabilities.</p>
</li>
<li><p><a target="_blank" href="https://streamlit.io/"><strong>Streamlit</strong></a>: A Python-based web app framework for ML and data science, ideal for turning data scripts into shareable web apps. It has been used to build user-friendly dashboards for exploring model predictions, enhancing the accessibility of ML models.</p>
</li>
</ul>
<h3 id="heading-mlops-and-ai-monitoring-frameworks">MLOps and AI Monitoring Frameworks</h3>
<ul>
<li><p><a target="_blank" href="https://mlflow.org/"><strong>MLflow</strong></a>: Used for experiment tracking and model lifecycle management, perfect for keeping track of experiments and model versions. It has been applied to manage multiple iterations of predictive models, supporting organized development workflows.</p>
</li>
<li><p><a target="_blank" href="https://www.kubeflow.org/"><strong>Kubeflow</strong></a>: A Kubernetes-native platform for MLOps, ideal for deploying, scaling, and managing machine learning models on Kubernetes. It has been used to run end-to-end ML workflows in production environments, ensuring scalability and consistency.</p>
</li>
<li><p><a target="_blank" href="https://prometheus.io/"><strong>Prometheus</strong></a> &amp; <a target="_blank" href="https://grafana.com/"><strong>Grafana</strong></a>: Monitoring and alerting tools for ML infrastructure, perfect for tracking model inference performance and system metrics. They have been used to monitor latency and resource usage of deployed ML services, ensuring optimal operational performance.</p>
</li>
</ul>
<h2 id="heading-web-frameworks">Web frameworks</h2>
<p>Web development has evolved into two distinct camps—think of them as the front-of-house and kitchen staff in a restaurant. Both essential, both specialized, but with very different responsibilities.</p>
<p><strong>Note</strong>: We already discussed full-stack web application frameworks above, which marry these two together.</p>
<h3 id="heading-frontend-frameworks">Frontend Frameworks</h3>
<p>Frontend frameworks handle what users see and interact with, managing everything from data display to user interactions, user input, and how the overall user experience is structured. These frameworks ensure that the interface is visually appealing, intuitive, and responsive to user actions.</p>
<p>They play a critical role in how smoothly data is presented, processed, and updated in real time, providing dynamic elements like animations, form validation, and client-side routing to enhance usability.</p>
<p>By using frontend frameworks, developers can create highly interactive and cohesive user experiences that feel natural and engaging.</p>
<ul>
<li><p><a target="_blank" href="https://reactjs.org/"><strong>React</strong></a>: Ideal for large-scale applications with complex state management. It features a virtual DOM for optimal performance, making it suitable for highly interactive user interfaces.</p>
</li>
<li><p><a target="_blank" href="https://vuejs.org/"><strong>Vue.js</strong></a>: Perfect for both small projects and enterprise applications. It has a gentle learning curve combined with powerful scalability, making it an approachable yet robust frontend solution.</p>
</li>
<li><p><a target="_blank" href="https://svelte.dev/"><strong>Svelte</strong></a>: Ideal for when you have performance-critical applications and want smaller bundles. It compiles away framework code for lighter applications, providing better performance and a smaller footprint.</p>
</li>
</ul>
<h3 id="heading-backend-frameworks">Backend Frameworks</h3>
<p>Backend frameworks manage server-side logic, data processing, and system integration, handling everything from receiving and processing client requests to interacting with databases and external APIs. These frameworks ensure that the server processes are efficient, scalable, and secure, supporting high concurrency and maintaining consistent data flows.</p>
<p>They provide the essential tools for developers to build, maintain, and optimize the server-side of applications, including tasks such as handling authentication, managing business logic, and ensuring data consistency.</p>
<p>A well-chosen backend framework allows developers to focus more on creating features rather than dealing with low-level server management.</p>
<ul>
<li><p><a target="_blank" href="https://expressjs.com/"><strong>Express.js</strong></a>: Perfect for APIs and microservices, offering minimal structure with maximum flexibility. It is highly popular in Node.js environments for building efficient server-side logic.</p>
</li>
<li><p><a target="_blank" href="https://fastapi.tiangolo.com/"><strong>FastAPI</strong></a>: Designed for high-performance APIs, with automatic API documentation and type checking. It is commonly used for fast and secure backend implementations in Python.</p>
</li>
<li><p><a target="_blank" href="https://nestjs.com/"><strong>NestJS</strong></a>: For large-scale Node.js applications, featuring an Angular-inspired architecture that enhances scalability. It provides a well-structured framework for enterprise-level backends.</p>
</li>
</ul>
<h2 id="heading-cssui-frameworks">CSS/UI Frameworks</h2>
<p>Modern CSS frameworks have evolved beyond simple styling to become complete design systems. Gone are the days when CSS frameworks just provided basic grid systems and button styles.</p>
<p>Today's frameworks are sophisticated tools that enable consistent design at scale. They offer features such as responsive layouts, dark mode support, accessibility enhancements, and interactive components.</p>
<p>They've become essential for maintaining design consistency across large applications and teams, while significantly reducing development time and technical debt. Some frameworks even include built-in performance optimization, design tokens for brand customization, and tools for managing design systems across multiple platforms.</p>
<p>They fall into two main categories:</p>
<h3 id="heading-utility-first-frameworks">Utility-first Frameworks</h3>
<ul>
<li><p><a target="_blank" href="https://tailwindcss.com/"><strong>Tailwind CSS</strong></a>: Custom designs with consistent systems. It features rapid prototyping capabilities, highly customizable design tokens, and small production bundles through PurgeCSS.</p>
</li>
<li><p><a target="_blank" href="https://unocss.dev/"><strong>UnoCSS</strong></a>: A customizable, efficient, utility-first CSS solution. It provides on-demand CSS for optimal performance and minimal bundle size, making it a modern tool for design system management.</p>
</li>
</ul>
<h3 id="heading-component-based-frameworks">Component-based Frameworks</h3>
<ul>
<li><p><a target="_blank" href="https://getbootstrap.com/"><strong>Bootstrap</strong></a>: Rapid prototyping and traditional web applications. It offers an extensive library of pre-built components, a responsive grid system, and a rich ecosystem of themes and plugins.</p>
</li>
<li><p><a target="_blank" href="https://mui.com/"><strong>Material UI</strong></a>: For applications following Material Design guidelines. It includes a comprehensive component library, a theming system, and accessibility compliance features.</p>
</li>
</ul>
<h2 id="heading-testing-and-infrastructure">Testing and Infrastructure</h2>
<p>These frameworks form the backbone of reliable, scalable applications. While they might not get as much attention as flashy frontend frameworks or AI tools, they're the critical infrastructure that keeps modern applications running smoothly at scale.</p>
<p>Testing frameworks ensure code quality and prevent regressions, while containerization and orchestration frameworks handle the increasingly complex world of cloud deployment and scaling.</p>
<p>In an era where a single code change can affect millions of users instantly, or where an application might need to scale from hundreds to millions of requests in minutes, these frameworks aren't just nice-to-have—they're essential for survival. Major tech companies like Netflix, Amazon, and Google rely on these tools to maintain their rapid development pace while ensuring reliability and performance at massive scale.</p>
<h3 id="heading-testing-frameworks">Testing Frameworks</h3>
<ul>
<li><p><a target="_blank" href="https://jestjs.io/"><strong>Jest</strong></a>: Features snapshot testing, code coverage, and mocking capabilities, making it a popular choice for ensuring the quality of JavaScript codebases.</p>
</li>
<li><p><a target="_blank" href="https://www.cypress.io/"><strong>Cypress</strong></a>: Provides real browser testing and time-travel debugging, ideal for end-to-end testing of web applications.</p>
</li>
<li><p><a target="_blank" href="https://docs.pytest.org/en/stable/"><strong>PyTest</strong></a>: Known for its simple syntax, powerful extensions, and easy fixture management, making it a go-to framework for testing Python applications.</p>
</li>
</ul>
<h3 id="heading-containerization-and-orchestration">Containerization and Orchestration</h3>
<ul>
<li><p><a target="_blank" href="https://www.docker.com/"><strong>Docker</strong></a>: Used for application containerization, providing consistent development and deployment environments with isolated dependencies and efficient resource usage.</p>
</li>
<li><p><a target="_blank" href="https://kubernetes.io/"><strong>Kubernetes</strong></a>: Orchestration of large-scale distributed applications. It provides automated scaling, self-healing deployments, and rolling updates, ensuring that containerized applications can grow as needed.</p>
</li>
</ul>
<h2 id="heading-making-the-right-choice">Making the Right Choice</h2>
<p>Selecting the right framework can determine the success of your entire project. Consider these critical points to guide your decision-making process:</p>
<h3 id="heading-1-application-type-and-scale">1. Application Type and Scale</h3>
<ul>
<li><p>Small site? Consider React or Vue.js.</p>
</li>
<li><p>Large application? Next.js or Django might be better.</p>
</li>
<li><p>Need SEO? Look for SSR capabilities.</p>
</li>
</ul>
<h3 id="heading-2-team-capabilities">2. Team Capabilities</h3>
<ul>
<li><p>Strong JavaScript? Consider Node.js ecosystem.</p>
</li>
<li><p>Python experts? Django or FastAPI might be better.</p>
</li>
<li><p>Need quick ramp-up? Combine key frameworks like Vue.js and Bootstrap.</p>
</li>
</ul>
<h3 id="heading-3-technical-requirements">3. Technical Requirements</h3>
<ul>
<li><p>High-performance computing? Consider Rust frameworks.</p>
</li>
<li><p>Real-time updates? Look at WebSocket support.</p>
</li>
<li><p>AI requirements? Integration with platforms like Hugging Face and frameworks like LangChain might be essential.</p>
</li>
</ul>
<h3 id="heading-4-scaling-strategy">4. Scaling Strategy</h3>
<ul>
<li><p>Vertical scaling? Simpler frameworks might suffice.</p>
</li>
<li><p>Horizontal scaling? You need frameworks with microservices support.</p>
</li>
<li><p>Global distribution? Consider edge computing capabilities.</p>
</li>
</ul>
<h3 id="heading-5-long-term-maintenance">5. Long-term Maintenance</h3>
<ul>
<li><p>Community size and activity</p>
</li>
<li><p>Available talent pool</p>
</li>
<li><p>Corporate backing and stability</p>
</li>
<li><p>Documentation quality</p>
</li>
<li><p>Upgrade path complexity</p>
</li>
</ul>
<h2 id="heading-the-bottom-line">The Bottom Line</h2>
<p>Framework selection isn't just a technical decision—it's a strategic one that affects your project's success, team productivity, and maintenance costs. So take the time to understand your options.</p>
<p>Now you should have all of the puzzle pieces, but it's up to you to put them together thoughtfully to create the perfect technology stack that meets both your current and future needs.</p>
<h2 id="heading-additional-resources">Additional Resources</h2>
<p>If you'd like to learn how <a target="_blank" href="https://mdb.link/register-frameworks">MongoDB</a> integrates seamlessly with many of the frameworks mentioned in this guide, check out the resources below. You'll find that it offers a flexible and scalable database solution that adapts to different use cases.</p>
<ul>
<li><p><a target="_blank" href="https://mdb.link/frameworks-nextjs">How to Integrate MongoDB Into Your Next.js App</a></p>
</li>
<li><p><a target="_blank" href="https://mdb.link/frameworks-farm">Introducing FARM Stack - FastAPI, React, and MongoDB</a></p>
</li>
<li><p><a target="_blank" href="https://mdb.link/frameworks-mern">How to Use MERN Stack: A Complete Guide</a></p>
</li>
<li><p><a target="_blank" href="https://mdb.link/frameworks-langchainjs">Build a JavaScript AI Agent With LangGraph.js and MongoDB</a></p>
</li>
<li><p><a target="_blank" href="https://mdb.link/frameworks-langchain">RAG with Atlas Vector Search, LangChain, and OpenAI</a></p>
</li>
</ul>
<h2 id="heading-frequently-asked-questions-faq"><strong>Frequently Asked Questions (FAQ)</strong></h2>
<h3 id="heading-what-is-a-development-framework">What is a development framework?</h3>
<p>A development framework is a set of tools, libraries, and conventions that provide a foundation for building applications efficiently. Frameworks handle common tasks so developers can focus on building unique features.</p>
<h3 id="heading-how-do-ai-and-development-frameworks-work-together">How do AI and development frameworks work together?</h3>
<p>AI frameworks can be combined with traditional development frameworks to create intelligent, data-driven applications. For instance, a backend framework like FastAPI can handle incoming requests, while an AI framework like LangChain processes natural language data, providing users with enhanced functionality like chatbots or recommendation systems.</p>
<h3 id="heading-why-is-choosing-the-right-framework-important">Why is choosing the right framework important?</h3>
<p>Choosing the right framework can impact your project's performance, scalability, and maintenance. It ensures that your application meets user expectations, is easy to manage, and can grow as needed.</p>
<h3 id="heading-how-do-i-decide-which-framework-to-use-for-my-project">How do I decide which framework to use for my project?</h3>
<p>Consider factors like application type, team expertise, performance needs, scalability, and long-term maintenance. Each of these can guide you in selecting a framework that matches your specific requirements.</p>
<h3 id="heading-can-i-use-multiple-frameworks-in-one-project">Can I use multiple frameworks in one project?</h3>
<p>Yes, combining multiple frameworks can be very effective. You might use one framework for the front end, another for backend services, and a third for AI integrations, ensuring that each part of your application is handled by the best-suited tool.</p>
<h3 id="heading-how-does-mongodb-fit-into-development-frameworks">How does MongoDB fit into development frameworks?</h3>
<p>MongoDB integrates with many frameworks, acting as the data layer for your applications. It provides a flexible, scalable solution that supports full-stack, backend, and AI frameworks to store and retrieve data efficiently.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How JavaScript's Temporal Proposal Will Change Date/Time Functions ]]>
                </title>
                <description>
                    <![CDATA[ JavaScript's handling of dates and times has long frustrated developers. The built-in Date object, created in JavaScript’s early days, has numerous limitations and quirks that complicate working with dates and times. Fortunately for us, the Temporal ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-javascripts-temporal-proposal-will-change-datetime-functions/</link>
                <guid isPermaLink="false">67350bbf437f61ba9155860d</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ datetime ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Jesse Hall ]]>
                </dc:creator>
                <pubDate>Wed, 13 Nov 2024 20:27:43 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/mRGtYItJRnA/upload/62e08fa08517011b9a4f54e9002b76ca.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>JavaScript's handling of dates and times has long frustrated developers. The built-in <code>Date</code> object, created in JavaScript’s early days, has numerous limitations and quirks that complicate working with dates and times.</p>
<p>Fortunately for us, the <a target="_blank" href="https://github.com/tc39/proposal-temporal">Temporal proposal</a> aims to address these issues by providing a modern, more intuitive API for date and time manipulation.</p>
<p>In this article, we’ll go over some of the challenges of working with <code>date</code>, what the Temporal API is and how it will work, and what you can use in the meantime until Temporal is ready for production use.</p>
<h2 id="heading-current-issues-with-date-in-javascript">Current Issues with <code>Date</code> in JavaScript</h2>
<h3 id="heading-1-mutable-api">1. Mutable API</h3>
<p>The <code>Date</code> object is mutable, which can lead to bugs and unexpected behavior:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Current Date behavior is mutable</span>
<span class="hljs-keyword">const</span> date = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-string">'January 1, 2024'</span>);
date.setMonth(<span class="hljs-number">1</span>); <span class="hljs-comment">// Modifies the original date object</span>
<span class="hljs-built_in">console</span>.log(date); <span class="hljs-comment">// February 1, 2024</span>

<span class="hljs-comment">// This mutability can lead to bugs when passing dates between functions</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">processDate</span>(<span class="hljs-params">date</span>) </span>{
  date.setDate(date.getDate() + <span class="hljs-number">1</span>); <span class="hljs-comment">// Modifies the original date!</span>
  <span class="hljs-keyword">return</span> date;
}
</code></pre>
<h3 id="heading-2-confusing-month-numbering">2. Confusing month numbering</h3>
<p>Months in <code>Date</code> are zero-based (0-11), while days are one-based (1-31):</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Confusing month numbering</span>
<span class="hljs-keyword">const</span> date = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-number">2024</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>); <span class="hljs-comment">// January 1, 2024</span>
<span class="hljs-built_in">console</span>.log(date.getMonth()); <span class="hljs-comment">// 0 (January)</span>
</code></pre>
<h3 id="heading-3-limited-time-zone-support">3. Limited time zone support</h3>
<p>The <code>Date</code> object has limited support for time zones and relies heavily on the system's local time zone:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Time zone handling is system-dependent</span>
<span class="hljs-keyword">const</span> date = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-string">'2024-01-01T00:00:00Z'</span>);
<span class="hljs-built_in">console</span>.log(date.toString()); <span class="hljs-comment">// Will show different results based on system timezone</span>
</code></pre>
<h2 id="heading-what-is-the-temporal-api">What is the Temporal API?</h2>
<p>Temporal is a proposed new JavaScript API that provides a modern solution for working with dates, times, and timestamps. It's currently a Stage 3 proposal, which means it's in the final stages of development but not yet ready for production use.</p>
<p>Key concepts of Temporal:</p>
<ol>
<li><p><strong>Immutable by default</strong>: All Temporal objects are immutable</p>
</li>
<li><p><strong>Clear separation of concerns</strong>: Different objects for different use cases</p>
</li>
<li><p><strong>Explicit time zone handling</strong>: Better support for working with time zones</p>
</li>
<li><p><strong>Consistent indexing</strong>: All units use 1-based numbering</p>
</li>
</ol>
<h2 id="heading-key-features-of-temporal">Key Features of Temporal</h2>
<h3 id="heading-1-different-types-for-different-needs">1. Different types for different needs</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// PlainDate for working with calendar dates</span>
<span class="hljs-keyword">const</span> date = Temporal.PlainDate.from(<span class="hljs-string">'2024-01-01'</span>);

<span class="hljs-comment">// PlainTime for working with wall-clock time</span>
<span class="hljs-keyword">const</span> time = Temporal.PlainTime.from(<span class="hljs-string">'09:00:00'</span>);

<span class="hljs-comment">// ZonedDateTime for working with specific time zones</span>
<span class="hljs-keyword">const</span> zonedDateTime = Temporal.ZonedDateTime.from(<span class="hljs-string">'2024-01-01T09:00:00[America/New_York]'</span>);
</code></pre>
<p>In this example, Temporal provides different object types for different use cases:</p>
<ul>
<li><p><code>PlainDate</code> is used when you only care about calendar dates without time or timezone information. Perfect for birthdays, holidays, and so on.</p>
</li>
<li><p><code>PlainTime</code> handles time independent of any date or timezone. Useful for recurring events like "9 AM daily standup".</p>
</li>
<li><p><code>ZonedDateTime</code> combines date, time, and timezone information for complete timestamp handling. Great for scheduling meetings across timezones.</p>
</li>
</ul>
<p>Each type is purpose-built and immutable, preventing accidental modifications. This clear separation helps developers choose the right tool for their specific needs, unlike the one-size-fits-all <code>Date</code> object that tries to handle everything and often leads to confusion.</p>
<h3 id="heading-2-immutable-operations">2. Immutable operations</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// All operations return new objects instead of modifying the original</span>
<span class="hljs-keyword">const</span> date = Temporal.PlainDate.from(<span class="hljs-string">'2024-01-01'</span>);
<span class="hljs-keyword">const</span> nextMonth = date.add({ <span class="hljs-attr">months</span>: <span class="hljs-number">1</span> }); 
<span class="hljs-built_in">console</span>.log(date.toString()); <span class="hljs-comment">// '2024-01-01' - original unchanged</span>
<span class="hljs-built_in">console</span>.log(nextMonth.toString()); <span class="hljs-comment">// '2024-02-01' - new object</span>
</code></pre>
<p>This example demonstrates how Temporal's immutable design prevents accidental mutations and makes date arithmetic more predictable.</p>
<p>With the current <code>Date</code> API, methods like <code>setMonth()</code> modify the original object, which can lead to bugs when that object is used in multiple places. In contrast, Temporal's methods always return new objects, leaving the original untouched.</p>
<h3 id="heading-3-better-time-zone-support">3. Better time zone support</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Explicit time zone handling</span>
<span class="hljs-keyword">const</span> nyDateTime = Temporal.ZonedDateTime.from({
  <span class="hljs-attr">timeZone</span>: <span class="hljs-string">'America/New_York'</span>,
  <span class="hljs-attr">year</span>: <span class="hljs-number">2024</span>,
  <span class="hljs-attr">month</span>: <span class="hljs-number">1</span>,
  <span class="hljs-attr">day</span>: <span class="hljs-number">1</span>,
  <span class="hljs-attr">hour</span>: <span class="hljs-number">9</span>
});

<span class="hljs-keyword">const</span> tokyoDateTime = nyDateTime.withTimeZone(<span class="hljs-string">'Asia/Tokyo'</span>);
<span class="hljs-built_in">console</span>.log(tokyoDateTime.toString()); <span class="hljs-comment">// '2024-01-01T23:00:00+09:00[Asia/Tokyo]'</span>
</code></pre>
<p>Unlike the current <code>Date</code> API, which often leads to confusion with implicit time zone conversions, Temporal makes time zone operations explicit and straightforward:</p>
<ol>
<li><p>We create a <code>ZonedDateTime</code> object specifically for New York time zone, with all components (year, month, day, hour) clearly specified. This explicit creation prevents any ambiguity about which time zone we're working with.</p>
</li>
<li><p>Using <code>withTimeZone()</code>, we can easily convert times between zones without complex calculations. The conversion from New York to Tokyo time is handled automatically.</p>
</li>
<li><p>The resulting string output includes the full time zone offset (<code>+09:00</code>) and the time zone name (<code>[Asia/Tokyo]</code>), providing complete clarity about the time being represented.</p>
</li>
</ol>
<p>This approach solves many common time zone-related issues developers face today, such as daylight saving time transitions, time zone offset calculations, and the ambiguity of local vs. UTC times. It's particularly valuable for applications that need to handle global scheduling, event coordination across time zones, or any scenario where precise time zone handling is crucial.</p>
<h2 id="heading-comparing-date-intl-and-temporal">Comparing Date, Intl, and Temporal</h2>
<h3 id="heading-current-approach-with-date-and-intl">Current approach with <code>Date</code> and <code>Intl</code>:</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Current approach using Date and Intl</span>
<span class="hljs-keyword">const</span> date = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-string">'2024-01-01T09:00:00Z'</span>);
<span class="hljs-keyword">const</span> formatter = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Intl</span>.DateTimeFormat(<span class="hljs-string">'en-US'</span>, {
  <span class="hljs-attr">timeZone</span>: <span class="hljs-string">'America/New_York'</span>,
  <span class="hljs-attr">dateStyle</span>: <span class="hljs-string">'full'</span>,
  <span class="hljs-attr">timeStyle</span>: <span class="hljs-string">'long'</span>
});

<span class="hljs-built_in">console</span>.log(formatter.format(date)); <span class="hljs-comment">// 'Monday, January 1, 2024 at 4:00:00 AM EST'</span>
</code></pre>
<p>With the current approach, we create a UTC timestamp using <code>Date</code>, need a separate <code>Intl.DateTimeFormat</code> object for formatting, handle time zone conversion implicitly during formatting, and have less control over the exact output format. The resulting output shows 4:00 AM EST because we created the date as 09:00 UTC and when formatted in New York time zone. This implicit conversion can be confusing and error-prone.</p>
<h3 id="heading-future-approach-with-temporal">Future approach with Temporal:</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Future approach using Temporal</span>
<span class="hljs-keyword">const</span> datetime = Temporal.ZonedDateTime.from(<span class="hljs-string">'2024-01-01T09:00:00[America/New_York]'</span>);
<span class="hljs-built_in">console</span>.log(datetime.toLocaleString(<span class="hljs-string">'en-US'</span>, {
  <span class="hljs-attr">weekday</span>: <span class="hljs-string">'long'</span>,
  <span class="hljs-attr">year</span>: <span class="hljs-string">'numeric'</span>,
  <span class="hljs-attr">month</span>: <span class="hljs-string">'long'</span>,
  <span class="hljs-attr">day</span>: <span class="hljs-string">'numeric'</span>,
  <span class="hljs-attr">hour</span>: <span class="hljs-string">'numeric'</span>,
  <span class="hljs-attr">minute</span>: <span class="hljs-string">'2-digit'</span>,
  <span class="hljs-attr">second</span>: <span class="hljs-string">'2-digit'</span>,
  <span class="hljs-attr">timeZoneName</span>: <span class="hljs-string">'short'</span>
})); <span class="hljs-comment">// 'Monday, January 1, 2024 at 9:00:00 AM EST'</span>
</code></pre>
<p>With Temporal, we create a <code>ZonedDateTime</code> with an explicit time zone, and the formatting options are directly integrated into the API. The time (9:00 AM) is exactly what we specified for New York, with no implicit conversions. This makes the code's behavior more predictable and easier to understand.</p>
<p>Arithmetic also becomes more intuitive with this approach.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> nextWeek = datetime.add({ <span class="hljs-attr">weeks</span>: <span class="hljs-number">1</span> });
<span class="hljs-keyword">const</span> duration = datetime.until(nextWeek);
<span class="hljs-built_in">console</span>.log(nextWeek.toPlainDate().toString()); <span class="hljs-comment">// '2024-01-08'</span>
<span class="hljs-built_in">console</span>.log(duration.toString()); <span class="hljs-comment">// 'PT168H'</span>
</code></pre>
<p>In this example, we can see several key advantages of Temporal's approach:</p>
<ol>
<li><p><strong>Explicit Time Zone Handling</strong>: By creating a <code>ZonedDateTime</code> with <code>[America/New_York]</code>, we explicitly state which time zone we're working with. There's no ambiguity about whether the time is UTC, local, or in another time zone.</p>
</li>
<li><p><strong>Integrated Formatting</strong>: The <code>toLocaleString()</code> method provides a clean, unified way to format dates without needing a separate formatter object. All the formatting options are similar to what you'd use with Intl.DateTimeFormat, maintaining familiarity while simplifying the API.</p>
</li>
<li><p><strong>Intuitive Arithmetic</strong>: The <code>add()</code> and <code>until()</code> methods demonstrate how Temporal makes date/time calculations more straightforward:</p>
<ul>
<li><p><code>add({ weeks: 1 })</code> clearly shows we're adding one week</p>
</li>
<li><p><code>until()</code> returns a proper duration object that can be easily understood and manipulated</p>
</li>
<li><p>The resulting duration of 'PT168H' represents a period of time (P) with 168 hours (T168H), following the ISO 8601 duration format</p>
</li>
</ul>
</li>
<li><p><strong>Type Safety</strong>: By having distinct types like <code>ZonedDateTime</code> and <code>PlainDate</code>, Temporal helps prevent common mistakes. The <code>toPlainDate()</code> method explicitly converts to a date-only representation when we don't need time information.</p>
</li>
</ol>
<p>This approach eliminates many of the gotchas and implicit behaviors that make the current <code>Date</code> API problematic, while providing a more powerful and flexible way to work with dates and times.</p>
<h2 id="heading-current-status-and-alternatives">Current Status and Alternatives</h2>
<h3 id="heading-current-status">Current status</h3>
<ul>
<li><p>Temporal is currently at Stage 3 of the TC39 process</p>
</li>
<li><p>It's not yet ready for production use</p>
</li>
<li><p>Browser support is not yet available natively</p>
</li>
</ul>
<h3 id="heading-recommended-alternatives">Recommended alternatives</h3>
<p>Until Temporal becomes widely available, consider using established libraries:</p>
<ol>
<li><p><a target="_blank" href="https://day.js.org/"><strong>Day.js</strong></a></p>
<ul>
<li><p>Lightweight</p>
</li>
<li><p>Good browser support</p>
</li>
<li><p>Good TypeScript support</p>
</li>
<li><p>Extensible with plugins</p>
</li>
<li><p>Has a large community and active development</p>
</li>
</ul>
</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-comment">// Using Day.js as an alternative</span>
<span class="hljs-keyword">import</span> dayjs <span class="hljs-keyword">from</span> <span class="hljs-string">'dayjs'</span>;
<span class="hljs-keyword">import</span> utc <span class="hljs-keyword">from</span> <span class="hljs-string">'dayjs/plugin/utc'</span>;
<span class="hljs-keyword">import</span> timezone <span class="hljs-keyword">from</span> <span class="hljs-string">'dayjs/plugin/timezone'</span>;

dayjs.extend(utc);
dayjs.extend(timezone);

<span class="hljs-keyword">const</span> date = dayjs(<span class="hljs-string">'2024-01-01'</span>).tz(<span class="hljs-string">'America/New_York'</span>);
<span class="hljs-keyword">const</span> nextWeek = date.add(<span class="hljs-number">1</span>, <span class="hljs-string">'week'</span>);
</code></pre>
<p>For a deeper dive into Day.js, check out this article: <a target="_blank" href="https://www.freecodecamp.org/news/javascript-date-time-dayjs/"><strong>JavaScript Dates – How to Use the DayJS Library to work with Date and Time in JS</strong></a></p>
<ol start="2">
<li><p><a target="_blank" href="https://date-fns.org/"><strong>date-fns</strong></a></p>
<ul>
<li><p>Functional programming approach</p>
</li>
<li><p>Tree-shakeable</p>
</li>
<li><p>Good TypeScript support</p>
</li>
</ul>
</li>
<li><p><a target="_blank" href="https://moment.github.io/luxon/"><strong>Luxon</strong></a></p>
<ul>
<li><p>Similar features to Temporal</p>
</li>
<li><p>Immutable by default</p>
</li>
<li><p>Native time zone and Intl support</p>
</li>
</ul>
</li>
</ol>
<h3 id="heading-why-wait-for-temporal">Why wait for Temporal?</h3>
<p>While these libraries are good alternatives, Temporal will offer several advantages:</p>
<ol>
<li><p>Native browser support (no additional bundle size)</p>
</li>
<li><p>Standardized API across all JavaScript environments</p>
</li>
<li><p>Better performance as a native implementation</p>
</li>
<li><p>Consistent behavior across all platforms</p>
</li>
</ol>
<p>Until Temporal reaches Stage 4 and has widespread browser support, I would recommend either using the built-in <code>Date</code> and <code>Intl</code> objects or one of the established libraries mentioned above for production applications. But prepare yourself and be ready for Temporal when it’s ready!</p>
<h2 id="heading-thanks-for-reading">Thanks for reading!</h2>
<p>Check out my other content and let me know how I can help you on your journey to becoming a web developer.</p>
<ul>
<li><p><a target="_blank" href="https://youtube.com/codeSTACKr">Subscribe To My YouTube Channel</a></p>
</li>
<li><p>Socials: <a target="_blank" href="https://twitter.com/codeSTACKr">Twitter</a> | <a target="_blank" href="https://www.linkedin.com/in/codeSTACKr/">LinkedIn</a> | <a target="_blank" href="https://instagram.com/codeSTACKr">Instagram</a></p>
</li>
<li><p><a target="_blank" href="https://codestackr.com/">Sign Up For My Newsletter</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Write HTML/CSS Faster with Emmet Cheat-Codes ]]>
                </title>
                <description>
                    <![CDATA[ Emmet is one of my favorite built-in features of VS Code. It is also available as an extension in other code editors. Think of Emmet as shorthand. With it, you can easily write a lot of code quickly. It dramatically speeds up your HTML & CSS workflow... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/write-html-css-faster-with-emmet-cheat-codes/</link>
                <guid isPermaLink="false">66d45f68246e57ac83a2c783</guid>
                
                    <category>
                        <![CDATA[ efficiency ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ self-improvement  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Visual Studio Code ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Jesse Hall ]]>
                </dc:creator>
                <pubDate>Tue, 22 Sep 2020 17:16:17 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/09/fCC_-Emmet.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Emmet is one of my favorite built-in features of VS Code. It is also available as an extension in other code editors.</p>
<p>Think of Emmet as shorthand. With it, you can easily write a lot of code quickly. It dramatically speeds up your HTML &amp; CSS workflow.</p>
<p>Understanding how to use Emmet is literally a superpower. Some have even called it a coding cheat-code. ?</p>
<p>And it's just one of many amazing built-in features of VS Code.</p>
<p>Recently, I launched a comprehensive and detailed course called <a target="_blank" href="https://courses.codestackr.com/vs-code-superhero?coupon=LAUNCH"><strong>Become A VS Code SuperHero</strong></a>.**** It covers all aspects of VS Code in great depth.</p>
<p>This article is based on one of the 11 sections of the course: <strong>Writing &amp; Formatting Code</strong>.</p>
<h2 id="heading-html">HTML</h2>
<p>With Emmet you can quickly create an HTML boilerplate in the blink of an eye. In an HTML file, simply type <code>!</code> and you’ll see that Emmet has popped up as a suggestion. Now hit <code>Enter</code>. There you have it, a basic, blank HTML web page ready to go.</p>
<p>If you’ve never seen HTML before and have no clue what all of this is, don’t worry. I’m just demonstrating the capabilities of VS Code and Emmet. You don’t have to know what any of this means right now.</p>
<h3 id="heading-basic-tags">Basic Tags</h3>
<p>To create basic HTML tags, just type the tag's name and hit <code>Enter</code>. Notice how Emmet puts your cursor inside the tag. You are now set up to continue typing inside the tag.</p>
<ul>
<li><p>Try typing: <code>div</code> then <code>Enter</code>, or <code>h1 Enter</code>, or <code>p Enter</code>.</p>
</li>
<li><p>These work as well: <code>bq</code> for a <code>&lt;blockquote&gt;</code>, <code>hdr</code> for a <code>&lt;header&gt;</code>, <code>ftr</code> for a <code>&lt;footer&gt;</code>, <code>btn</code> for a <code>&lt;button&gt;</code>, and <code>sect</code> for a section.</p>
</li>
</ul>
<h3 id="heading-classes">Classes</h3>
<p>If you are familiar with CSS, Emmet uses the same way to refer to classes using a <code>.</code>. To define a class along with the tag simply add it like this:</p>
<ul>
<li><p><code>div.wrapper</code> —&gt; <code>&lt;div class="wrapper"&gt;&lt;/div&gt;</code></p>
</li>
<li><p><code>h1.header.center</code> —&gt; <code>&lt;h1 class="header center"&gt;&lt;/h1&gt;</code></p>
</li>
</ul>
<h3 id="heading-ids">ID’s</h3>
<p>Id's work very much the same:</p>
<ul>
<li><code>div#hero</code> —&gt; <code>&lt;div id="hero"&gt;&lt;/div&gt;</code></li>
</ul>
<h3 id="heading-combining">Combining</h3>
<p>You can string these together:</p>
<ul>
<li><code>div#hero.wrapper</code> —&gt; <code>&lt;div id="hero" class="wrapper"&gt;&lt;/div&gt;</code></li>
</ul>
<h3 id="heading-attributes">Attributes</h3>
<p>We can also specify attributes for tags:</p>
<ul>
<li><code>img[src="cat.jpg"][alt="Cute cat pic"]</code> —&gt; <code>&lt;img src="cat.jpg" alt="Cute cat pic" /&gt;</code></li>
</ul>
<h3 id="heading-content">Content</h3>
<p>To include content within the tag, we simply wrap the content in curly braces, <code>{ }</code>.</p>
<ul>
<li><code>p{This is a paragraph}</code> —&gt; <code>&lt;p&gt;This is a paragraph&lt;/p&gt;</code></li>
</ul>
<h3 id="heading-siblings-amp-children">Siblings &amp; Children</h3>
<p>It just keeps getting better. We can also specify siblings and children using the <code>+</code> and <code>&gt;</code> characters.</p>
<ul>
<li><p><code>section+section</code> —&gt; <code>&lt;section&gt;&lt;/section&gt;&lt;section&gt;&lt;/section&gt;</code></p>
</li>
<li><p><code>ul&gt;li</code> —&gt; <code>&lt;ul&gt;&lt;li&gt;&lt;/li&gt;&lt;/ul&gt;</code></p>
</li>
</ul>
<h3 id="heading-climbing-up">Climbing Up</h3>
<p>You have to try to picture what you are building in your head as you type the Emmet shorthand. In this example we'll "climb up" the tree by using <code>^</code>.</p>
<p><code>div+div&gt;p&gt;span+em^bq</code></p>
<p>Result:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">em</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">em</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">blockquote</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">blockquote</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Here, we wanted the blockquote to be on the same level as the paragraph. Because of that, we needed to "climb up". Otherwise, it would be inside of the paragraph.</p>
<h3 id="heading-grouping">Grouping</h3>
<p>If your structure is very complex, you may want to group tags instead of traversing by climbing.</p>
<p>In this example, we'll create a header and footer without climbing using parenthesis <code>( )</code>.</p>
<p><code>div&gt;(header&gt;ul&gt;li&gt;a)+footer&gt;p</code></p>
<p>Result:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">header</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">""</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">footer</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">footer</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<h3 id="heading-multiplication-and">Multiplication and $</h3>
<p>We can generate multiple tags by multiplying (<code>*</code>) and number items in sequence using a dollar sign (<code>$</code>).</p>
<ul>
<li><p><code>ul&gt;li*5</code> —&gt; <code>&lt;ul&gt;&lt;li&gt;&lt;/li&gt;&lt;li&gt;&lt;/li&gt;&lt;li&gt;&lt;/li&gt;&lt;li&gt;&lt;/li&gt;&lt;li&gt;&lt;/li&gt;&lt;/ul&gt;</code></p>
</li>
<li><p><code>ul&gt;li{Item $}*3</code> —&gt; <code>&lt;ul&gt;&lt;li&gt;Item 1&lt;/li&gt;&lt;li&gt;Item 2&lt;/li&gt;&lt;li&gt;Item 3&lt;/li&gt;&lt;/ul&gt;</code></p>
</li>
</ul>
<p>You can even customize the numbering sequence by padding with zeros, starting with a specific number, and even reverse direction.</p>
<p>Pad with zeros: <code>ul&gt;li.item$$$*5</code></p>
<p>Result:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item001"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item002"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item003"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item004"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item005"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</code></pre>
<p>Start with a specific number: <code>ul&gt;li.item$@3*5</code></p>
<p>Result:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item3"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item4"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item5"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item6"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item7"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</code></pre>
<p>Reverse direction: <code>ul&gt;li.item$@-*5</code></p>
<p>Result:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item5"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item4"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item3"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item2"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item1"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</code></pre>
<p>Reverse direction from a specific number: <code>ul&gt;li.item$@-3*5</code></p>
<p>Result:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item7"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item6"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item5"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item4"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item3"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</code></pre>
<h3 id="heading-implicit-tag-names">Implicit Tag Names</h3>
<p>There are certain tags that do not need to be typed and can be implied.</p>
<ul>
<li><p>A class defined initially with no tag will be implied as a <code>&lt;div&gt;</code>.<br>  <code>.wrapper</code> —&gt; <code>&lt;div class="wrapper"&gt;&lt;/div&gt;</code></p>
</li>
<li><p>A class defined within an emphasis tag will be implied as a <code>&lt;span&gt;</code>.<br>  <code>em&gt;.emphasis</code> —&gt; <code>&lt;em&gt;&lt;span class="emphasis"&gt;&lt;/span&gt;&lt;/em&gt;</code></p>
</li>
<li><p>A class defined within a list will be implied as a list item.<br>  <code>ul&gt;.item</code> —&gt; <code>&lt;ul&gt;&lt;li class="item"&gt;&lt;/li&gt;&lt;/ul&gt;</code></p>
</li>
<li><p>A class defined within a table will be implied as a <code>&lt;tr&gt;</code> and within a row would be a <code>&lt;td&gt;</code>.<br>  <code>table&gt;.row&gt;.col</code> —&gt; <code>&lt;table&gt;&lt;tr class="row"&gt;&lt;td class="col"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</code></p>
</li>
</ul>
<h3 id="heading-wrap-with-tags">Wrap with Tags</h3>
<p>There will be times when you have existing code that you want to wrap with a tag. We can do with easily with Emmet.</p>
<p>Just highlight the code that you want to wrap and open the command pallet (<code>F1</code>). Then search for <code>Emmet: Wrap with Abbreviation</code>. You'll then be presented with a dialog box where you can type in the element.</p>
<p><code>test</code> —&gt; <code>&lt;div&gt;test&lt;/div&gt;</code></p>
<p>You can also use standard Emmet syntax in this dialog. Try wrapping some text with <code>span.wrapper</code>.</p>
<p>By default, this functionality is not assigned to a keyboard shortcut. So if you find yourself using it often, you may want to add a custom shortcut for it.</p>
<h3 id="heading-lorem-ipsum">Lorem Ipsum</h3>
<p>"Lorem Ipsum" is dummy text used by developers to represent data on a page. Just type <code>lorem</code> and hit <code>Enter</code>. Emmet will generate 30 words of fake text that you can use as a filler in your project.</p>
<p>The amount of words generated can be defined as well.</p>
<ul>
<li><code>lorem10</code> will give you 10 words of random text.</li>
</ul>
<h3 id="heading-putting-it-all-together">Putting It All Together</h3>
<p>Let's use several things that we've learned so far. Give this a try:</p>
<p><code>ul.my-list&gt;lorem10.item-$*5</code></p>
<p>Result:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"my-list"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-1"</span>&gt;</span>Lorem ipsum dolor sit amet.<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-2"</span>&gt;</span>Numquam repudiandae fuga porro consequatur?<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-3"</span>&gt;</span>Culpa, est. Tenetur, deleniti nihil?<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item-4"</span>&gt;</span>Numquam architecto corrupti quam repudiandae.<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</code></pre>
<h2 id="heading-css">CSS</h2>
<p>In CSS, Emmet has an abbreviation for every property. I'm not going to list all of them, but I will point out my most used ones. To see the full list, refer to the Emmet <a target="_blank" href="https://docs.emmet.io/cheat-sheet/">cheat-sheet</a>.</p>
<h3 id="heading-position">Position</h3>
<ul>
<li><p><code>pos</code> —&gt; <code>position:relative;</code> (defaults to relative)</p>
</li>
<li><p><code>pos:s</code> —&gt; <code>position:static;</code></p>
</li>
<li><p><code>pos:a</code> —&gt; <code>position:absolute;</code></p>
</li>
<li><p><code>pos:r</code> —&gt; <code>position:relative;</code></p>
</li>
<li><p><code>pos:f</code> —&gt; <code>position:fixed;</code></p>
</li>
</ul>
<h3 id="heading-display">Display</h3>
<ul>
<li><p><code>d</code> —&gt; <code>display:block;</code> (defaults to block)</p>
</li>
<li><p><code>d:n</code> —&gt; <code>display:none;</code></p>
</li>
<li><p><code>d:b</code> —&gt; <code>display:block;</code></p>
</li>
<li><p><code>d:f</code> —&gt; <code>display:flex;</code></p>
</li>
<li><p><code>d:if</code> —&gt; <code>display:inline-flex;</code></p>
</li>
<li><p><code>d:i</code> —&gt; <code>display:inline;</code></p>
</li>
<li><p><code>d:ib</code> —&gt; <code>display:inline-block;</code></p>
</li>
</ul>
<h3 id="heading-cursor">Cursor</h3>
<ul>
<li><code>cur</code> —&gt; <code>cursor:pointer;</code></li>
</ul>
<h3 id="heading-color">Color</h3>
<ul>
<li><p><code>c</code> —&gt; <code>color:#000;</code></p>
</li>
<li><p><code>c:r</code> —&gt; <code>color:rgb(0, 0, 0);</code></p>
</li>
<li><p><code>c:ra</code> —&gt; <code>color:rgba(0, 0, 0, .5);</code></p>
</li>
<li><p><code>op</code> —&gt; <code>opacity: ;</code></p>
</li>
</ul>
<h3 id="heading-margin-amp-padding">Margin &amp; Padding</h3>
<ul>
<li><p><code>m</code> —&gt; <code>margin: ;</code></p>
</li>
<li><p><code>m:a</code> —&gt; <code>margin:auto;</code></p>
</li>
<li><p><code>mt</code> —&gt; <code>margin-top: ;</code></p>
</li>
<li><p><code>mr</code> —&gt; <code>margin-right: ;</code></p>
</li>
<li><p><code>mb</code> —&gt; <code>margin-bottom: ;</code></p>
</li>
<li><p><code>ml</code> —&gt; <code>margin-left: ;</code></p>
</li>
<li><p><code>p</code> —&gt; <code>padding: ;</code></p>
</li>
<li><p><code>pt</code> —&gt; <code>padding-top: ;</code></p>
</li>
<li><p><code>pr</code> —&gt; <code>padding-right: ;</code></p>
</li>
<li><p><code>pb</code> —&gt; <code>padding-bottom: ;</code></p>
</li>
<li><p><code>pl</code> —&gt; <code>padding-left: ;</code></p>
</li>
</ul>
<h3 id="heading-box-sizing">Box Sizing</h3>
<ul>
<li><code>bxz</code> —&gt; <code>box-sizing:border-box;</code></li>
</ul>
<h3 id="heading-width">Width</h3>
<ul>
<li><p><code>w</code> —&gt; <code>width: ;</code></p>
</li>
<li><p><code>h</code> —&gt; <code>height: ;</code></p>
</li>
<li><p><code>maw</code> —&gt; <code>max-width: ;</code></p>
</li>
<li><p><code>mah</code> —&gt; <code>max-height: ;</code></p>
</li>
<li><p><code>miw</code> —&gt; <code>min-width: ;</code></p>
</li>
<li><p><code>mih</code> —&gt; <code>min-height: ;</code></p>
</li>
</ul>
<h3 id="heading-border">Border</h3>
<ul>
<li><p><code>bd</code> —&gt; <code>border: ;</code></p>
</li>
<li><p><code>bd+</code> —&gt; <code>border:1px solid #000;</code></p>
</li>
<li><p><code>bd:n</code> —&gt; <code>border:none;</code></p>
</li>
</ul>
<h3 id="heading-emmet-is-awesome">Emmet Is Awesome!</h3>
<p>With Emmet, you can create a really complex HTML structure with one line. It’s really awesome. And, it also works with CSS.</p>
<p>You can see how Emmet can drastically increase your efficiency and speed when writing HTML and CSS.</p>
<p>If you want to further increase your efficiency and speed while using VS Code, check out my course <a target="_blank" href="https://courses.codestackr.com/vs-code-superhero?coupon=LAUNCH"><strong>Become A VS Code SuperHero</strong></a><strong>.</strong></p>
<p>The course dives much deeper into these concepts and helps you to become a fast, efficient superhero developer :)</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/footer-banner-1.png" alt="Jesse Hall (codeSTACKr)" width="600" height="400" loading="lazy"></p>
<p>I'm Jesse from Texas. Check out my other content and let me know how I can help you on your journey to becoming a web developer.</p>
<ul>
<li><p><a target="_blank" href="https://youtube.com/codeSTACKr">Subscribe To My YouTube</a></p>
</li>
<li><p>Say Hello! <a target="_blank" href="https://instagram.com/codeSTACKr">Instagram</a> | <a target="_blank" href="https://twitter.com/codeSTACKr">Twitter</a></p>
</li>
<li><p><a target="_blank" href="https://codestackr.com/">Sign Up For My Newsletter</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ JavaScript Console.log() Example – How to Print to the Console in JS ]]>
                </title>
                <description>
                    <![CDATA[ Logging messages to the console is a very basic way to diagnose and troubleshoot minor issues in your code. But, did you know that there is more to console than just log? In this article, I'll show you how to print to the console in JS, as well as al... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/javascript-console-log-example-how-to-print-to-the-console-in-js/</link>
                <guid isPermaLink="false">66d45f668812486a37369cdf</guid>
                
                    <category>
                        <![CDATA[ console ]]>
                    </category>
                
                    <category>
                        <![CDATA[ debugging ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Jesse Hall ]]>
                </dc:creator>
                <pubDate>Wed, 09 Sep 2020 21:01:11 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/09/fCC_-Console.log.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Logging messages to the console is a very basic way to diagnose and troubleshoot minor issues in your code.</p>
<p>But, did you know that there is more to <code>console</code> than just <code>log</code>? In this article, I'll show you how to print to the console in JS, as well as all of the things you didn't know <code>console</code> could do.</p>
<h2 id="heading-firefox-multi-line-editor-console">Firefox Multi-line Editor Console</h2>
<p>If you've never used the multi-line editor mode in Firefox, you should give it a try right now!</p>
<p>Just open the console, <code>Ctrl+Shift+K</code> or <code>F12</code>, and in the top right you will see a button that says "Switch to multi-line editor mode". Alternatively, you can press <code>Ctrl+B</code>.</p>
<p>This gives you a multi-line code editor right inside Firefox.</p>
<h2 id="heading-consolelog">console.log</h2>
<p>Let's start with a very basic log example.</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> x = <span class="hljs-number">1</span>
<span class="hljs-built_in">console</span>.log(x)
</code></pre>
<p>Type that into the Firefox console and run the code. You can click the "Run" button or press <code>Ctrl+Enter</code>.</p>
<p>In this example, we should see "1" in the console. Pretty straightforward, right?</p>
<h2 id="heading-multiple-values">Multiple Values</h2>
<p>Did you know that you can include multiple values? Add a string to the beginning to easily identify what it is you are logging.</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> x = <span class="hljs-number">1</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"x:"</span>, x)
</code></pre>
<p>But what if we have multiple values that we want to log?</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> x = <span class="hljs-number">1</span>
<span class="hljs-keyword">let</span> y = <span class="hljs-number">2</span>
<span class="hljs-keyword">let</span> z = <span class="hljs-number">3</span>
</code></pre>
<p>Instead of typing <code>console.log()</code> three times we can include them all. And we can add a string before each of them if we wanted, too.</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> x = <span class="hljs-number">1</span>
<span class="hljs-keyword">let</span> y = <span class="hljs-number">2</span>
<span class="hljs-keyword">let</span> z = <span class="hljs-number">3</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"x:"</span>, x, <span class="hljs-string">"y:"</span>, y, <span class="hljs-string">"z:"</span>, z)
</code></pre>
<p>But that's too much work. Just wrap them with curly braces! Now you get an object with the named values.</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> x = <span class="hljs-number">1</span>
<span class="hljs-keyword">let</span> y = <span class="hljs-number">2</span>
<span class="hljs-keyword">let</span> z = <span class="hljs-number">3</span>
<span class="hljs-built_in">console</span>.log( {x, y, z} )
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/image-34.png" alt="Console Output" width="600" height="400" loading="lazy"></p>
<p><em>Console Output</em></p>
<p>You can do the same thing with an object.</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> user = {
  <span class="hljs-attr">name</span>: <span class="hljs-string">'Jesse'</span>,
  <span class="hljs-attr">contact</span>: {
    <span class="hljs-attr">email</span>: <span class="hljs-string">'codestackr@gmail.com'</span>
  }
}
<span class="hljs-built_in">console</span>.log(user)
<span class="hljs-built_in">console</span>.log({user})
</code></pre>
<p>The first log will print the properties within the user object. The second will identify the object as "user" and print the properties within it.</p>
<p>If you are logging many things to the console, this can help you to identify each log.</p>
<h2 id="heading-variables-within-the-log">Variables within the log</h2>
<p>Did you know that you can use portions of your log as variables?</p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.log(<span class="hljs-string">"%s is %d years old."</span>, <span class="hljs-string">"John"</span>, <span class="hljs-number">29</span>)
</code></pre>
<p>In this example, <code>%s</code> refers to a string option included after the initial value. This would refer to "John".</p>
<p>The <code>%d</code> refers to a digit option included after the initial value. This would refer to 29.</p>
<p>The output of this statement would be: "John is 29 years old.".</p>
<h2 id="heading-variations-of-logs">Variations of logs</h2>
<p>There are a few variations of logs. There is the most widely used <code>console.log()</code>. But there is also:</p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Console Log'</span>)
<span class="hljs-built_in">console</span>.info(<span class="hljs-string">'Console Info'</span>)
<span class="hljs-built_in">console</span>.debug(<span class="hljs-string">'Console Debug'</span>)
<span class="hljs-built_in">console</span>.warn(<span class="hljs-string">'Console Warn'</span>)
<span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Console Error'</span>)
</code></pre>
<p>These variations add styling to our logs in the console. For instance, the <code>warn</code> will be colored yellow, and the <code>error</code> will be colored red.</p>
<p>Note: The styles vary from browser to browser.</p>
<h2 id="heading-optional-logs">Optional Logs</h2>
<p>We can print messages to the console conditionally with <code>console.assert()</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> isItWorking = <span class="hljs-literal">false</span>
<span class="hljs-built_in">console</span>.assert(isItWorking, <span class="hljs-string">"this is the reason why"</span>)
</code></pre>
<p>If the first argument is false, then the message will be logged.</p>
<p>If we were to change <code>isItWorking</code> to <code>true</code>, then the message will not be logged.</p>
<h2 id="heading-counting">Counting</h2>
<p>Did you know that you can count with console?</p>
<pre><code class="lang-js"><span class="hljs-keyword">for</span>(i=<span class="hljs-number">0</span>; i&lt;<span class="hljs-number">10</span>; i++){
  <span class="hljs-built_in">console</span>.count()
}
</code></pre>
<p>Each iteration of this loop will print a count to the console. You will see "default: 1, default: 2", and so on until it reaches 10.</p>
<p>If you run this same loop again you will see that the count picks up where it left off; 11 - 20.</p>
<p>To reset the counter we can use <code>console.countReset()</code>.</p>
<p>And, if you want to name the counter to something other than "default", you can!</p>
<pre><code class="lang-js"><span class="hljs-keyword">for</span>(i=<span class="hljs-number">0</span>; i&lt;<span class="hljs-number">10</span>; i++){
  <span class="hljs-built_in">console</span>.count(<span class="hljs-string">'Counter 1'</span>)
}
<span class="hljs-built_in">console</span>.countReset(<span class="hljs-string">'Counter 1'</span>)
</code></pre>
<p>Now that we have added a label, you will see "Counter 1, Counter 2", and so on.</p>
<p>And to reset this counter, we have to pass the name into <code>countReset</code>. This way you can have several counters running at the same time and only reset specific ones.</p>
<h2 id="heading-track-time">Track Time</h2>
<p>Besides counting, you can also time something like a stopwatch.</p>
<p>To start a timer we can use <code>console.time()</code>. This will not do anything by itself. So, in this example, we will use <code>setTimeout()</code> to emulate code running. Then, within the timeout, we will stop our timer using <code>console.timeEnd()</code>.</p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.time()
<span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.timeEnd()
}, <span class="hljs-number">5000</span>)
</code></pre>
<p>As you would expect, after 5 seconds, we will have a timer end log of 5 seconds.</p>
<p>We can also log the current time of our timer while it's running, without stopping it. We do this by using <code>console.timeLog()</code>.</p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.time()

<span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.timeEnd()
}, <span class="hljs-number">5000</span>)

<span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.timeLog()
}, <span class="hljs-number">2000</span>)
</code></pre>
<p>In this example, we will get our 2 second <code>timeLog</code> first, then our 5 second <code>timeEnd</code>.</p>
<p>Just the same as the counter, we can label timers and have multiple running at the same time.</p>
<h2 id="heading-groups">Groups</h2>
<p>Another thing that you can do with <code>log</code> is group them. ?</p>
<p>We start a group by using <code>console.group()</code>. And we end a group with <code>console.groupEnd()</code>.</p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.log(<span class="hljs-string">'I am not in a group'</span>)

<span class="hljs-built_in">console</span>.group()
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'I am in a group'</span>)
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'I am also in a group'</span>)
<span class="hljs-built_in">console</span>.groupEnd()

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'I am not in a group'</span>)
</code></pre>
<p>This group of logs will be collapsible. This makes it easy to identify sets of logs.</p>
<p>By default, the group is not collapsed. You can set it to collapsed by using <code>console.groupCollapsed()</code> in place of <code>console.group()</code>.</p>
<p>Labels can also be passed into the <code>group()</code> to better identify them.</p>
<h2 id="heading-stack-trace">Stack Trace</h2>
<p>You can also do a stack trace with <code>console</code>. Just add it into a function.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">one</span>(<span class="hljs-params"></span>) </span>{
  two()
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">two</span>(<span class="hljs-params"></span>) </span>{
  three()
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">three</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.trace()
}
one()
</code></pre>
<p>In this example, we have very simple functions that just call each other. Then, in the last function, we call <code>console.trace()</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/image-35.png" alt="Console Output" width="600" height="400" loading="lazy"></p>
<p><em>Console Output</em></p>
<h2 id="heading-tables">Tables</h2>
<p>Here's one of the most mind-blowing uses for console: <code>console.table()</code>.</p>
<p>So let's set up some data to log:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> devices = [
  {
    <span class="hljs-attr">name</span>: <span class="hljs-string">'iPhone'</span>,
    <span class="hljs-attr">brand</span>: <span class="hljs-string">'Apple'</span>
  },
  {
    <span class="hljs-attr">name</span>: <span class="hljs-string">'Galaxy'</span>,
    <span class="hljs-attr">brand</span>: <span class="hljs-string">'Samsung'</span>
  }
]
</code></pre>
<p>Now we'll log this data using <code>console.table(devices)</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/image-36.png" alt="Console Output" width="600" height="400" loading="lazy"></p>
<p><em>Console Output</em></p>
<p>But wait – it gets better!</p>
<p>If we only want the brands, just <code>console.table(devices, ['brand'])</code>!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/image-37.png" alt="Console Output" width="600" height="400" loading="lazy"></p>
<p><em>Console Output</em></p>
<p>How about a more complex example? In this example, we'll use jsonplaceholder.</p>
<pre><code class="lang-js"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getUsers</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">let</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'https://jsonplaceholder.typicode.com/users'</span>)
  <span class="hljs-keyword">let</span> data = <span class="hljs-keyword">await</span> response.json()

  <span class="hljs-built_in">console</span>.table(data, [<span class="hljs-string">'name'</span>, <span class="hljs-string">'email'</span>])
}

getUsers()
</code></pre>
<p>Here we are just printing the "name" and "email". If you <code>console.log</code> all of the data, you will see that there are many more properties for each user.</p>
<h2 id="heading-style">Style ?</h2>
<p>Did you know that you can use CSS properties to style your logs?</p>
<p>To do this, we use <code>%c</code> to specify that we have styles to add. The styles get passed into the second argument of the <code>log</code>.</p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.log(<span class="hljs-string">"%c This is yellow text on a blue background."</span>, <span class="hljs-string">"color:yellow; background-color:blue"</span>)
</code></pre>
<p>You can use this to make your logs stand out.</p>
<h2 id="heading-clear">Clear</h2>
<p>If you are trying to troubleshoot an issue using logs, you may be refreshing a lot and your console may get cluttered.</p>
<p>Just add <code>console.clear()</code> to the top of your code and you'll have a fresh console every time you refresh. ?</p>
<p>Just don't add it to the bottom of your code, lol.</p>
<h2 id="heading-thanks-for-reading">Thanks for Reading!</h2>
<p>If you want to revisit the concepts in this article via video, you can check out this <a target="_blank" href="https://youtu.be/_-bHhEGcDiQ">video-version I made here</a>.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/_-bHhEGcDiQ" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/footer-banner-1.png" alt="Jesse Hall (codeSTACKr)" width="600" height="400" loading="lazy"></p>
<p>I'm Jesse from Texas. Check out my other content and let me know how I can help you on your journey to becoming a web developer.</p>
<ul>
<li><p><a target="_blank" href="https://youtube.com/codeSTACKr">Subscribe To My YouTube</a></p>
</li>
<li><p>Say Hello! <a target="_blank" href="https://instagram.com/codeSTACKr">Instagram</a> | <a target="_blank" href="https://twitter.com/codeSTACKr">Twitter</a></p>
</li>
<li><p><a target="_blank" href="https://codestackr.com/">Sign Up For My Newsletter</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How I Went From 0 to 70k Subscribers on YouTube in 1 Year – And How Much Money I Made ]]>
                </title>
                <description>
                    <![CDATA[ It's hard to believe that it has already been 1 year since I started my YouTube channel, codeSTACKr. In this article, I want to be open and transparent about everything that has gotten me to where I am now, the good decisions as well as bad. And I ho... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-grow-your-youtube-channel/</link>
                <guid isPermaLink="false">66d45f6533b83c4378a517e4</guid>
                
                    <category>
                        <![CDATA[ self-improvement  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ side project ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Jesse Hall ]]>
                </dc:creator>
                <pubDate>Thu, 20 Aug 2020 17:37:36 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/08/fCC_-70k-2-2.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>It's hard to believe that it has already been 1 year since I started my YouTube channel, <a target="_blank" href="https://youtube.com/codestackr">codeSTACKr</a>.</p>
<p>In this article, I want to be open and transparent about everything that has gotten me to where I am now, the good decisions as well as bad. And I hope that you can take this information and apply it to your circumstances.</p>
<p>I believe that no matter what category or niche you may be in, this information can help you to grow your channel as well.</p>
<p>This post is not meant to brag. Rather, it’s meant to provide insight into how I quickly grew my YouTube channel.</p>
<p>I hope that this post will help you in some way, but what worked for me is not guaranteed to work for you. So adapt my methods to meet your needs.</p>
<p>All of these strategies and tricks can also apply to blogs and any other social media platforms.</p>
<p>Let me get started by giving you a little background on myself and why I started a YouTube channel.</p>
<h2 id="heading-how-it-all-started">How It All Started</h2>
<p>There are many reasons that people start a YouTube channel. It could be for fame and notoriety, to make money, to help people, or maybe just as a hobby. Well, I started my channel to prove a point.</p>
<p>You see, I have 2 teenagers, and they are typical teenagers. I wanted to challenge them to come up with a business idea. You know, instead of playing video games, watching Netflix, or chatting with their friends all day.</p>
<p>As you can expect, there were not many ideas being passed around. So I thought, maybe they could start YouTube channels and make content about things they enjoy doing. My son could start a gaming channel and my daughter could start a hair-styling channel.</p>
<p>They seemed to think it was an okay idea. My son downloaded a screen recorder and was going to create some videos. I helped my daughter set up a tripod and camera so she could record some fancy hair braids.</p>
<p>And that's about as far as they got. No videos ever got posted.</p>
<p>That's when I came up with the idea to start my own channel. I wanted to prove a point: <strong>you can make something successful if you put in the effort</strong>.</p>
<p>I decided that I was not going to tell anyone, not even my wife, that I started the channel until I had proof that it was successful. I thought, "if I can get 300 subscribers I'll tell them".</p>
<p>Choosing a topic for your channel is, in my mind, the most important decision. You want to pick something that is not too broad, but also not too narrow. You want to appeal to a specific, targeted audience.</p>
<p>The topic of my channel was a no-brainer. I've been coding since I was 12 and it's a topic that I'm passionate about. So talking about web development made sense.</p>
<p>I had been watching other channels like <a target="_blank" href="https://www.youtube.com/TraversyMedia/">Brad Traversy</a>, <a target="_blank" href="https://www.youtube.com/Academind/">Academind</a>, and <a target="_blank" href="https://www.youtube.com/TheNetNinja">The Net Ninja</a> for years. So I started with a tutorial on VS Code.</p>
<p>We'll get to more about my channel and videos later. For now, let's talk about motivation and expectations for starting a channel.</p>
<h2 id="heading-motivation-amp-expectations">Motivation &amp; Expectations</h2>
<p>When starting a YouTube channel, a blog, or any social media account, you need to understand what your motivation is and what you expect to get out of it.</p>
<p>For me, I wanted to prove something to my kids. Are you trying to become famous? Do you want to make money? Do you want to help people in some way?</p>
<p>Whatever your answer is, you need to understand that you will not see results overnight. It could take months, even years to even see any results.</p>
<p>This is where expectations come into play. If you can manage your expectations, then you will be able to withstand the ups and downs that are sure to come.</p>
<p>When choosing the topic of your channel, make sure that it is something that you are passionate about. If not, you'll be setting yourself up for failure. It will only be a matter of time before you get bored and give up.</p>
<h2 id="heading-getting-started">Getting Started</h2>
<p>The first thing that I did was pick a channel name. Honestly, I don't remember why or how I landed on codeSTACKr.</p>
<p>I went to <a target="_blank" href="http://namecheap.com">namecheap.com</a> and was looking for domains. I was looking for combinations of "code", "full", "developer", "stack", etc. I remember that codestack was taken, so I added an "r" to the end ?.</p>
<p>The next step was to record the video. I decided that I was not going to spend a dime on this channel to start with. If I made any money from it, then I would invest that money back into the channel.</p>
<p>Since I would be sharing my screen, I didn't need a camera. I could just use a screen recorder. I used <a target="_blank" href="https://obsproject.com/">OBS</a> for that, and I still do.</p>
<p>If you will be starting a channel that requires a camera, start with the webcam on your laptop or your phone. Most phones have great cameras.</p>
<p>If you are going to spend any money, the first area I would recommend would be on audio. Audio is by far the most important asset to any video. It will make or break your channel in my opinion.</p>
<p>When I watch a video and the audio quality is not there, I will most likely move on to another video.</p>
<p>For my first several videos, I just used a headset mic. Like one that you would use for gaming or even earbuds from your phone.</p>
<p>Once I got everything recorded, then I needed to edit the video. There are a few options for this. If you have a Mac, then iMovie is a great option. I have a Windows computer, so I use <a target="_blank" href="https://www.blackmagicdesign.com/products/davinciresolve/">Davinci Resolve</a>. It is free and is very robust. It is also available on Mac and Linux.</p>
<p>Now it's time to post the video. This is where some get hung up.</p>
<p>I know it's nerve-wracking to upload the first video, and you want it to be perfect. But don't obsess over this. It will never be perfect, no matter how much time you spend on it. Just upload it!</p>
<p>That is exactly what I did and it was not perfect. I had a blaring misspelling in my video that I still get comments on to this day. ?</p>
<h2 id="heading-results-from-the-first-video">Results From The First Video</h2>
<p>Before I posted my video I did some research. I wanted to find places to promote the video. I had zero following on any other social platform. So, I started looking at Reddit and found a subreddit where I could post the link to my video.</p>
<p>I know that self-promotion on Reddit is frowned upon. So be very careful there. I found a subreddit that allowed this type of posting, and I made sure that I was not breaking any rules.</p>
<p>I also researched SEO for the video. I made sure that the title, description, and tags were optimal for the video. That in itself is an entire article.</p>
<p>Now it was time to post. I nervously clicked the button. Then hit refresh frantically for several minutes to see if there would be any views. Nope, no views. So I posted the video link on the subreddit. That worked! I started to get a few views.</p>
<p>The day after I posted the video, we left for vacation. I took every chance I could get to inconspicuously check my YouTube analytics while we were gone. It's hard not to get caught up on the numbers, but try not to. And we'll talk more about that in a bit.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/08/VS-Code-Jun-5---11.jpg" alt="The first week's analytics of my first video." width="600" height="400" loading="lazy"></p>
<p><em>The first week's analytics of my first video.</em></p>
<p>On the first day, I got 111 views and 8 subscribers. The next day was 231 views and 14 subscribers. Then the views dropped down to 23 and 2 subscribers. These mostly came from the Reddit post. On that first Reddit post, I got 88 up-votes. That's pretty good for Reddit.</p>
<p>You'll find that this is a typical graph for most videos. You will get a spike in initial views, then they level off. At some point, you hope that the YouTube algorithm will pick it up. We'll talk about that in a bit.</p>
<p>So how did I go from getting a few views per day to thousands per day? That's coming up next.</p>
<h2 id="heading-consistency">Consistency</h2>
<p>The number one thing that will help you grow your channel, which I'm sure you've heard before, is posting consistently.</p>
<p>Come up with a plan that works for you. If you can post once a week, once every two weeks, or once a month, stick to it! You will not get subscribers if you are not consistent.</p>
<p>For me, I have a full-time day job. So after we got back from vacation, I decided that I could find the time to post once a week. So I stuck to that. I posted consistently, at least once per week. Every post bumped up my average views.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/08/June-2019-Subs.jpg" alt="June 2019 Subscribers Gained." width="600" height="400" loading="lazy"></p>
<p><em>June 2019 Subscribers Gained.</em></p>
<p>You can see from this graph that in June, 2019 I posted three videos. You can also see the gap where I was on vacation. Each post gave me a bump in views and subscribers, not only for the video being released, but also for the previous videos.</p>
<p>You'll find that some videos get more views than others. You will have videos that do great and others that flop. Use these insights to hone in on what your viewers want to see. If a video does well, then make another video on the same or similar topic.</p>
<p>Consistency is what got me to my 300 subscriber goal after about 10 videos and 2 months.</p>
<h2 id="heading-revealing-my-secret">Revealing My Secret ?</h2>
<p>So I sat my family down to tell them the good news. Imagine, a 39-year-old father and husband sitting his wife and 2 teenagers down to tell them that he has created a YouTube channel and has 300 subscribers. ?</p>
<p>After the chuckles were over I proceeded to inform them of my plans to continue growing the channel and see where it could go.</p>
<h2 id="heading-avoid-burnout">Avoid Burnout</h2>
<p>Understanding that consistency is a marathon and not a sprint is very important. During January 2020 I decided that I was going to post a short video every day. I wanted to create short videos that explained small parts of JavaScript. I called it <a target="_blank" href="https://www.youtube.com/playlist?list=PLkwxH9e_vrALlH7D0XLDn2td-uoHqHFxq">#JavaScriptJanuary</a>.</p>
<p>These were about 90 second videos. You might think that short videos would be easier to make. And in theory, they should be.</p>
<p>But I tend to overdo things. I made sure that these videos were packed full of info. They had animations and were very engaging. On average, they each took 3 hours to make. ?</p>
<p>That was a bad decision. Don't get me wrong, I am proud of the videos that I created. I have gotten many compliments on them and thankful viewers who love them and want more.</p>
<p>But it was very hard to keep up with the schedule. I did manage to get a video out every day, but I will never do that again.</p>
<p>What did I learn from my mistake? Even though I posted a video every day, I did not see a significant increase in views or subscribers. In fact, I lost some subscribers because they did not like me flooding their home page with new videos every day.</p>
<p>When you first start your channel you will be very excited to get going and want to work all of the time. Be very careful, pace yourself, and don't sign yourself up for more than you can handle, or more than your audience can handle.</p>
<h2 id="heading-be-active-in-the-community">Be Active In The Community</h2>
<p>To engage with my viewers, I responded to every comment on every video. Your viewers want to know that they are being heard.</p>
<p>This has been one of my keys to success. By engaging with the viewers I have been able to adjust my content strategy to include topics that they are interested in watching.</p>
<p>You may think that you know what your audience wants, but you really don't until you ask them what they want.</p>
<p>Market and community research is critical to growing your brand. You need to understand who the big players are and try to interact with them as well, as much as possible.</p>
<p>Now, if you are just starting, you wouldn't want to bug a large channel asking for things. You want to engage with the community and bring value.</p>
<p>One of the first real engagements that I had was with <a target="_blank" href="http://freecodecamp.org">freeCodeCamp.org</a>. I was able to create a 2 hour long tutorial on <a target="_blank" href="https://youtu.be/_a5j7KoflTs">Sass</a> for them to post on their YouTube <a target="_blank" href="https://www.youtube.com/channel/UC8butISFwT-Wl7EV0hUK0BQ">channel</a>. At the time, their channel had around 1 MILLION subscribers!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/08/fcc-bump.jpg" alt="My subscriber bump from the freeCodeCamp video." width="600" height="400" loading="lazy"></p>
<p><em>My subscriber bump from the freeCodeCamp video.</em></p>
<p>In this graph, you can see the spike in subscribers that I got from posting my video on the <a target="_blank" href="http://freecodecamp.org">freeCodeCamp.org</a>'s YouTube <a target="_blank" href="https://www.youtube.com/channel/UC8butISFwT-Wl7EV0hUK0BQ">channel</a>.</p>
<p>By this time I had acquired around 500 subscribers. Then I got over 300 in one day! I was shocked and amazed. Of course, it leveled back off eventually. But notice that with every bump, the average increases. Each one takes you to the next level.</p>
<p>Another thing that has helped me is getting to know others in my community. You would think that other YouTubers that post videos on the same topic would be competition. But that is not true at all.</p>
<p>I was able to collaborate and share insights with many in my community that post about the same things as I do. Even though we may post about the same subject, we all have different methods of teaching and different viewpoints. So it's not a big deal.</p>
<p>Bottom line: you need to network and get to know others that are in the same niche as you.</p>
<h2 id="heading-the-elusive-algorithm">The Elusive Algorithm</h2>
<p>The YouTube algorithm is an enigma. Don't try to understand it. Just know that when it finds you, you will know it!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/08/social-blade-weekly.jpg" alt="Social Blade graph of my weekly views and subscribers gained over the past year." width="600" height="400" loading="lazy"></p>
<p><em>Social Blade graph of my weekly views and subscribers gained over the past year.</em></p>
<p>Notice in the graph the large spike around December, 2019. That is when the mighty algorithm decided to push one of my videos to tens of thousands of viewers.</p>
<p>I was averaging 1,000 views a day at that time. Then, all of a sudden, I was getting 12,000 views in one day. That then took me to the next level. I didn't do anything different. I was consistently posting one video per week.</p>
<p>You can see in the next graph the trajectory change around December, 2019.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/08/social-blade-monthly.jpg" alt="Social Blade graph of my monthly views and subscribers gained over the past year." width="600" height="400" loading="lazy"></p>
<p><em>Social Blade graph of my monthly views and subscribers gained over the past year.</em></p>
<p>Since then, the algorithm has picked up several of my videos. By staying consistent, listening to my audience, and interacting with my community, I was able to gain 70,000 subscribers and almost 2 million views in a year. Craziness!</p>
<h2 id="heading-dont-get-stuck-on-the-numbers">Don't Get Stuck On The Numbers</h2>
<p>I initially set the goal of getting 300 subscribers. For me, at the time, that was the number that would mean I was successful and that my strategies were working.</p>
<p>That was another mistake. Try your hardest not to focus on numbers. <strong>Your number of subscribers or followers does not define your success.</strong> <strong>The quality and value of your content is what defines your success.</strong> If you have quality and valuable content, they will come.</p>
<p>And... Do not compare yourself with others. Every journey is different. Focus on your circumstances, remain consistent, and produce quality content.</p>
<h2 id="heading-highs-amp-lows">Highs &amp; Lows</h2>
<p>Looking back at some of the graphs you will see peaks and valleys. That is totally normal. Don't get scared when your views start to drop. It's the natural cycle of YouTube. They will pick back up as long as you stay consistent.</p>
<h2 id="heading-monetization">Monetization</h2>
<p>On YouTube, you are required to have 1,000 subscribers and 4,000 watch hours to be monetized. That's 240,000 minutes of watch time!</p>
<p>I hit 1,000 subscribers after 3 months, in September of 2019. But I didn't hit 4,000 watch hours until November of 2019. That's 5 months after starting my channel.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/08/monthly-revenue.jpg" alt="Monthly ad revenue" width="600" height="400" loading="lazy"></p>
<p><em>Monthly ad revenue</em></p>
<p>In November I made <strong>$197</strong>. ? I could not believe that I was making money uploading videos to YouTube! In December I made $545. Then in January, which was right after the algorithm picked up one of my videos, I made $830!</p>
<p>After that, the revenue drops off but has leveled off and has recently begun to increase. After 8 months of monetization, I made just over $5,000.</p>
<p>That's not enough for me to quit my day job, but I am still amazed that I have been able to create side-income so quickly.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/08/CPM.jpg" alt="Weekly ad revenue graph with CPM" width="600" height="400" loading="lazy"></p>
<p><em>Weekly ad revenue graph with CPM</em></p>
<p>In this graph, you will see the weekly ad revenue breakdown. The other two stats are part of what the revenue is based on.</p>
<p>CPM is "Cost per Mille", or simply the price that an advertiser pays per 1,000 views of a video. My average CPM here is $10.20. So advertisers paid $10.20 per every 1,000 monetized views of my videos.</p>
<p>RPM is "Revenue per Mille", or simply the revenue that <strong>you</strong> earn per 1,000 views of a video.</p>
<p>Since YouTube is facilitating these views, they take a cut, and I'm OK with that. They own the platform, they maintain it, they send viewers to my channel, they do most of the heavy lifting. Plus they provide many great tools for content creators and are constantly adding and improving on these. So, $3.03 is what I made per 1,000 monetized video views.</p>
<p>Now, not all views count. Notice that I said "monetized" views. Which means that the ad was seen. If the viewer is using an ad-blocker or they skip the ad, it will not count as a monetized view.</p>
<h2 id="heading-other-sources-of-revenue">Other Sources of Revenue</h2>
<p>Besides the ad revenue, I also made approximately $8,000 from sponsors in the past year. This is not something that comes right away. You have to build your brand and become known in the community.</p>
<p>I have not gotten a single sponsorship by reaching out and asking for sponsors. All of my sponsors have reached out to me first. So, again, it's a marathon. Don't expect things to happen overnight. Stay laser-focused and good things will come.</p>
<p>In any business, you want to diversify your income. YouTube ad revenue should never be your main source of income. What if YouTube accidentally deletes your account, or for some reason stops monetization? You have to diversify!</p>
<p>Besides YouTube ads revenue and sponsors, my goal was to create my own digital products.</p>
<p>This is an example of another mistake that I made. The mistake was not the decision to make my own products, but my delay in making them. In fact, to this day, I still have not released any products.</p>
<p>I planned to release 3 premium courses in 2020. We are over halfway through the year and I have not released 1.</p>
<p>I got caught up in other side projects and did not focus on my own projects. These other side projects brought in subscribers and money for me but they should not have been my main focus.</p>
<p>Your main revenue stream should be your personal products. That is what you control. Everything else could one day disappear. Stay focused!</p>
<h2 id="heading-tips-for-success">Tips For Success</h2>
<p>The biggest tip for success that I could give you is to focus. It is so easy to get distracted by all of the things that you "could" do to increase your reach.</p>
<p>Focus on making quality videos. Try to stay organized. Create a list of content that you want to create. Every time you think of a new idea, add it to the list.</p>
<p>But, focus on one topic at a time. Create the content for that video, then move on to the next topic.</p>
<p>Earlier I said that when I started my channel that I did not have a presence on any other social platforms.</p>
<p>If you already have a following somewhere else, then you should use that to your advantage to bring viewers to your channel. But if you don't have a following elsewhere, don't try to grow multiple platforms at the same time. Stay focused on whatever platform is working for you.</p>
<p>After I got my YouTube routine down, which was after about 6 months, I started an Instagram, Facebook, LinkedIn, and Twitter account. I have slowly grown on these platforms as well, some better than others. (I have no idea how Facebook works ?.)</p>
<p>After several months on these platforms, they have had a very minimal impact on my YouTube growth. I think that, for my niche, Twitter and Instagram have been the most effective. Twitter especially for networking. But the impact from these on my channel has not been significant.</p>
<p>Depending on your niche, you may find that your audience may be more receptive on specific platforms. Use these for brand building once your channel gets a bit of traction.</p>
<p>If you want to revisit the concepts in this article via video, you can check out this <a target="_blank" href="https://www.youtube.com/watch?v=oNGZ7h5LR-o&amp;feature=youtu.be">video-version I made here</a>.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/oNGZ7h5LR-o" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In conclusion, I just want to say that anyone can do anything. If you have (1) the proper motivation, (2) realistic expectations, and (3) you don't overwork yourself, you can be successful.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/footer-banner-1.png" alt="Jesse Hall (codeSTACKr)" width="600" height="400" loading="lazy"></p>
<p>I'm Jesse from Texas. Check out my other content and let me know how I can help you on your journey to becoming a web developer.</p>
<ul>
<li><p><a target="_blank" href="https://youtube.com/codeSTACKr">Subscribe To My YouTube</a></p>
</li>
<li><p>Say Hello! <a target="_blank" href="https://instagram.com/codeSTACKr">Instagram</a> | <a target="_blank" href="https://twitter.com/codeSTACKr">Twitter</a></p>
</li>
<li><p><a target="_blank" href="https://codestackr.com/">Sign Up For My Newsletter</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ CSS Before and CSS After – How to Use the Content Property ]]>
                </title>
                <description>
                    <![CDATA[ The content property in CSS defines the content of an element. You may have heard that this property only applies to the ::before and ::after pseudo-elements. In this article, we'll explore various use cases for the content property, including outsid... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/css-before-and-after-how-to-use-the-content-property/</link>
                <guid isPermaLink="false">66d45f62a3a4f04fb2dd2e5d</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Jesse Hall ]]>
                </dc:creator>
                <pubDate>Fri, 26 Jun 2020 23:42:55 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/06/fCC_-Content-Property-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The <code>content</code> property in CSS defines the content of an element. You may have heard that this property only applies to the <code>::before</code> and <code>::after</code> pseudo-elements. In this article, we'll explore various use cases for the <code>content</code> property, including outside of pseudo-elements.</p>
<h2 id="heading-prerequisite">Prerequisite</h2>
<p>Since the majority of the use cases for the <code>content</code> property involve pseudo-elements, I would suggest that you be familiar with how the <code>::before</code> and <code>::after</code> pseudo-elements work. Here is a great article to get you up to speed:</p>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/css-pseudo-elements-before-and-after-selectors-explained/">CSS Pseudo-Elements - Before and After Selectors Explained</a></li>
</ul>
<h2 id="heading-accepted-values">Accepted Values</h2>
<p>First, let's take a look at all of the accepted values of the <code>content</code> property.</p>
<ul>
<li><p><code>normal</code>: This is the default value. Computes to <code>none</code> when used with pseudo-elements.</p>
</li>
<li><p><code>none</code>: A pseudo-element will not be generated.</p>
</li>
<li><p><code>&lt;string&gt;</code>: Sets the content to the string specified. This string can contain Unicode escape sequences. For example, the copyright symbol: <code>\\000A9</code>.</p>
</li>
<li><p><code>&lt;image&gt;</code>: Sets the content to an image or gradient using <code>url()</code> or <code>linear-gradient()</code>.</p>
</li>
<li><p><code>open-quote</code> | <code>close-quote</code>: Sets the content to the appropriate quote character referenced from the <code>quotes</code> property.</p>
</li>
<li><p><code>no-open-quote</code> | <code>no-close-quote</code>: Removes a quote from the selected element, but still increments or decrements the nesting level referenced from the <code>quotes</code> property.</p>
</li>
<li><p><code>attr(*attribute*)</code>: Sets the content as the string value of the selected elements selected attribute.</p>
</li>
<li><p><code>counter()</code>: Sets the content as the value of a <code>counter</code>, usually a number.</p>
</li>
</ul>
<h2 id="heading-string">String</h2>
<p>One of the most basic examples would be the use of adding <em>string</em> content before or after an element. In this example, we'll add a link symbol before a link and add the URL for the link after it.</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">a</span><span class="hljs-selector-pseudo">::before</span> {
    <span class="hljs-attribute">content</span>: <span class="hljs-string">"\\1F517 "</span>;
}
<span class="hljs-selector-tag">a</span><span class="hljs-selector-pseudo">::after</span> {
    <span class="hljs-attribute">content</span>: <span class="hljs-string">" ("</span> <span class="hljs-built_in">attr</span>(href) <span class="hljs-string">")"</span>;
}
</code></pre>
<p>Notice the space after the Unicode character in the <code>::before</code> pseudo-element and the before the first parenthesis in the <code>::after</code> pseudo-element. This will create space between these and the parent element.</p>
<p>Alternatively, you could add <code>padding</code> or <code>margin</code> to the pseudo-elements to add separation.</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/codeSTACKr/embed/OJMjpvL?editors=1100" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p> </p>
<h2 id="heading-basic-quotes">Basic Quotes</h2>
<p>With the <code>content</code> property, you can add quotes before and/or after elements. Now, in HTML we do have the <code>&lt;q&gt;</code> tag. This will also add quotes around its content. However, with the <code>content</code> property, we can have more control over the implementation.</p>
<p>Here is the most basic example of adding quotes:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/codeSTACKr/embed/NWxvpXq" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p> </p>
<p>You can accomplish this as well by using the HTML tag <code>&lt;q&gt;</code>. But maybe we want to style the quote differently. So let's only add the opening quote and not the ending quote. And let's also style the opening quote.</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">p</span> {
  <span class="hljs-attribute">position</span>: relative;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">3rem</span>;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">4rem</span>;
}
<span class="hljs-selector-tag">p</span><span class="hljs-selector-pseudo">::before</span> {
  <span class="hljs-attribute">content</span>: open-quote;
  <span class="hljs-attribute">position</span>: absolute;
  <span class="hljs-attribute">left</span>: -<span class="hljs-number">3.5rem</span>;
  <span class="hljs-attribute">top</span>: -<span class="hljs-number">2rem</span>;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">8rem</span>;
  <span class="hljs-attribute">color</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.5</span>)
}
</code></pre>
<p>The result:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/quote2.jpg" alt="Image showing a single styled quote on the top left of the paragraph" width="600" height="400" loading="lazy"></p>
<h2 id="heading-advanced-quotes">Advanced Quotes</h2>
<p>We can also specify where we do <em>not</em> want quotes. For example, you may be quoting someone who is quoting another person. So you would have quotes within quotes, which can get confusing to the reader.</p>
<p>In the CodePen below, we are using HTML <code>&lt;q&gt;</code> tags, then specifying which tags should not display the quotes.</p>
<p>At first glance, you might think that we should just remove the <code>&lt;q&gt;</code> tag where needed. But by specifying where a quote should not be still increments or decrements the nesting level referenced from the <code>quotes</code> property.</p>
<p>To explain this, we need to understand the <code>quotes</code> property. This is simply an "array" of characters that should be used when quoting. Here is an example:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">q</span> {
  <span class="hljs-attribute">quotes</span>: <span class="hljs-string">'“'</span> <span class="hljs-string">'”'</span> <span class="hljs-string">'‘'</span> <span class="hljs-string">'’'</span> <span class="hljs-string">'“'</span> <span class="hljs-string">'”'</span>;
}
</code></pre>
<p>These are sets of quotes. The first set will be used for the top level of quotes. The second set will be used for the first nested quote. And the third set will be used for the second nested quote. And so on, if there were more sets included.</p>
<p>Now that we understand the <code>quotes</code> property, I can explain how the <code>no-open-quote</code> and <code>no-close-quote</code> properties work.</p>
<p>For each level of quotes, we can assign different sets of characters to use for the quotes. By specifying where a quote should not be still increments or decrements the nesting level referenced from the <code>quotes</code> property.</p>
<p>Take a look at the example below. You will see that the second level of quotes is skipped.</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/codeSTACKr/embed/NWxvbLw" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p> </p>
<h2 id="heading-attributes">Attributes</h2>
<p>Attributes can be used to pass content from HTML into the CSS <code>content</code> property. We actually used this already in the link example where we used the <code>href</code> attribute to include the URL string as part of our content.</p>
<p>A perfect use case for this is a tooltip. You can add a <code>title</code> attribute to an element in HTML to have a simple, built-in tooltip on hover. But to customize this, we can use a data attribute on our HTML tag and then use the <code>content</code> property to add a tooltip.</p>
<p>In this example, we use the attribute <code>data-tooltip</code> from our HTML element to pass the value into our tooltip. For the pointer of the tooltip, we set the <code>content</code> to <code>""</code>, as <code>content</code> is required to render a <code>::before</code> or <code>::after</code> pseudo-element.</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/codeSTACKr/embed/WNrEopO" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p> </p>
<h2 id="heading-counters">Counters</h2>
<p>The <code>counter()</code> CSS function returns a string representing the current value of the named counter. In the following example we have an ordered list that we will add content using a <code>counter</code>.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">ol</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ol</span>&gt;</span>
</code></pre>
<pre><code class="lang-css"><span class="hljs-selector-tag">ol</span> {
  <span class="hljs-attribute">counter-reset</span>: exampleCounter;
}
<span class="hljs-selector-tag">li</span> {
  <span class="hljs-attribute">counter-increment</span>: exampleCounter;
}
<span class="hljs-selector-tag">li</span><span class="hljs-selector-pseudo">::after</span> {
  <span class="hljs-attribute">content</span>: <span class="hljs-string">"["</span> <span class="hljs-built_in">counter</span>(exampleCounter) <span class="hljs-string">"] == ["</span>
               <span class="hljs-built_in">counter</span>(exampleCounter, upper-roman) <span class="hljs-string">"]"</span>;
}
</code></pre>
<p>Without getting too in-depth on the <code>counter</code> function, we have to first initiate the counter on the <code>ol</code> element. We can name this whatever we would like. Then we tell the counter to increment on each <code>li</code> element. And lastly, we set the <code>content</code> of the <code>li::after</code>.</p>
<p>Here's the result:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/counter.jpg" alt="Ordered List" width="600" height="400" loading="lazy"></p>
<p>You could use this to customize content within each list item that needs a corresponding number. Or you could use this to customize the list item itself. For instance, you could remove the default numbering and implement a custom-styled numbering system.</p>
<h2 id="heading-images">Images</h2>
<p>Images and gradients can be used with the <code>content</code> property. This is fairly straight-forward. Here is an example that uses both:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/codeSTACKr/embed/WNrEpre" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p> </p>
<p>For accessibility, there is also an option to add alternate text for the image. This feature is not fully supported though.</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">content</span>: <span class="hljs-selector-tag">url</span>(//<span class="hljs-selector-tag">unsplash</span><span class="hljs-selector-class">.it</span>/200/200) / "<span class="hljs-selector-tag">Alternative</span> <span class="hljs-selector-tag">Text</span> <span class="hljs-selector-tag">Here</span>";
</code></pre>
<blockquote>
<p>Note: This is unsupported in Firefox, IE, and Safari. Also, the gradient does not work in Firefox.</p>
</blockquote>
<h2 id="heading-outside-of-pseudo-elements">Outside of Pseudo Elements</h2>
<p>That's right! You can use the <code>content</code> property outside of the pseudo-elements <code>::before</code> and <code>::after</code>. Although, its use is limited and not fully compatible in all browsers.</p>
<p>The most compatible use case would be replacement of an element.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">'replace'</span>&gt;</span>
  codeSTACKr
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-css"><span class="hljs-selector-id">#replace</span> {
  <span class="hljs-attribute">content</span>: <span class="hljs-built_in">url</span>(<span class="hljs-string">"&lt;https://www.codestackr.com/logo_twoline_light.svg&gt;"</span>);
  <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
}
</code></pre>
<blockquote>
<p>Note: Replacement is not supported in IE.</p>
</blockquote>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Most times you will see <code>content: ""</code> found in the <code>::before</code> and <code>::after</code> pseudo-elements. But the <code>content</code> property has many useful applications.</p>
<p>The best use in my opinion is to use it for updating bulk elements. If you want to add an icon before every link on your site, it would be much easier to add it through the <code>content</code> property than to add it to every element in the HTML document.</p>
<h2 id="heading-thanks-for-reading"><strong>Thanks for reading!</strong></h2>
<p>Thank you for reading this article. Hopefully, it has helped you to better understand how the <code>content</code> property works in CSS.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/footer-banner-1.png" alt="Jesse Hall (codeSTACKr)" width="600" height="400" loading="lazy"></p>
<p>I'm Jesse from Texas. Check out my other content and let me know how I can help you on your journey to becoming a web developer.</p>
<ul>
<li><p><a target="_blank" href="https://youtube.com/codeSTACKr">Subscribe To My YouTube</a></p>
</li>
<li><p>Say Hello! <a target="_blank" href="https://instagram.com/codeSTACKr">Instagram</a> | <a target="_blank" href="https://twitter.com/codeSTACKr">Twitter</a></p>
</li>
<li><p><a target="_blank" href="https://codeSTACKr.com">Sign Up For My Newsletter</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
