DEV Community

Cover image for Understanding Galadriel CSS and Nenyr: A Comprehensive Guide to Declarative Styling
Patrick Gunnar
Patrick Gunnar

Posted on

Understanding Galadriel CSS and Nenyr: A Comprehensive Guide to Declarative Styling

In the fast-paced world of web development, creating maintainable, scalable, and optimized code is more important than ever. For developers who value modularity and clarity, Galadriel CSS presents a powerful solution. At the heart of Galadriel CSS lies Nenyr, a domain-specific language (DSL) designed to simplify the creation of styles in a declarative way. In this article, we will explore the core functionalities of both Galadriel CSS and Nenyr, diving into their unique design philosophies, the mechanisms that drive them, and how they work together to create efficient, utility-first CSS. We will also demonstrate how these tools interact by defining two basic Nenyr documents: one central and one module, each serving to highlight the key principles of Galadriel CSS.

Introduction to Galadriel CSS and Nenyr
Before delving into the specifics of how Galadriel CSS and Nenyr operate, it is crucial to understand the problem they aim to solve. In traditional CSS workflows, style definitions can become tangled and repetitive, making it difficult to manage large-scale projects efficiently. By introducing a modular and hierarchical approach, Galadriel CSS seeks to overcome these issues, leveraging the power of the Nenyr language to bring clarity and flexibility to web design.

What is Galadriel CSS?
Galadriel CSS is a framework designed to optimize the process of styling websites by creating a modular and scalable system for writing CSS. It breaks down the design process into distinct contexts—Central, Layout, and Module—each serving a specific purpose in managing style rules. This hierarchical system ensures that styles are applied consistently across various parts of the website, reducing the likelihood of conflicts and redundancies.

The core feature of Galadriel CSS is its Nenyr integration. Nenyr is used as the language to define styles declaratively, allowing developers to create clear and reusable code. Unlike traditional CSS, which requires imperative definitions of styles, Nenyr allows for the declaration of style properties in a way that mirrors the structure of the document itself.

What is Nenyr?
Nenyr is a domain-specific language that facilitates the creation of styles in a more intuitive and modular manner. Its primary goal is to provide a declarative syntax for defining styles that will later be parsed by Galadriel CSS and transformed into an optimized, utility-first CSS output. Nenyr documents contain classes, breakpoints, variables, aliases, themes and other definitions that define the rules for styling HTML elements, but instead of manually writing each rule in CSS, users define their styles in a structured and hierarchical format.

Nenyr simplifies the process of writing styles by enabling reuse of classes and reducing the complexity of traditional CSS. It works in tandem with Galadriel CSS to transform these high-level, declarative style definitions into a final CSS file that is both optimized and free of redundancies.

How Galadriel CSS and Nenyr Work Together
At the heart of Galadriel CSS lies a system that parses Nenyr documents, generates an abstract syntax tree (AST), and applies specific rules for inheritance, extension, and unicity. Let's break down this process in more detail.

Parsing Nenyr Documents: The Role of the Nenyr Parser
The first step in the Galadriel CSS workflow is parsing the Nenyr documents. When a Nenyr document is processed, it is fed into the Nenyr parser, which generates an abstract syntax tree (AST). This AST represents the structure and content of the Nenyr document, breaking it down into individual style rules that later will be transformed into utility CSS classes to be applied to HTML elements.

The Nenyr parser processes each document, extracting the class definitions, properties, and values. Once parsed, the resulting AST contains all the style information necessary for Galadriel CSS to proceed with the next steps. The key advantage here is that the Nenyr language allows developers to define styles in a declarative manner, leading to more efficient and readable code.

Applying Extension, Inheritance, Context-Aware, and Unicity Rules
Once the AST is generated, Galadriel CSS applies several important rules to ensure that the final CSS output is clean and efficient.

  • Extension Rules: These rules allow for the inheritance of styles from parent contexts. In Galadriel CSS, a style rule can extend other rules, ensuring that common styles are reused across different parts of the application. This reduces the need for repetitive code and keeps the style definitions DRY (Don't Repeat Yourself).
  • Inheritance Rules: Similar to extension, but focused to classes not context, inheritance allows a class to inherit styles from their ancestors. This makes it easier to manage styles at a higher level and propagate them to child elements.
  • Context-Aware Rules: Context-aware rules are designed to apply styles based on the closest context; if Galadriel CSS does not find a value inside the same context, it will look for it higher in the hierarchy until it finds the first value and will use it. This feature applies for variables, animations, aliases, and classes.
  • Unicity Rules: One of the most important aspects of Galadriel CSS is its ability to prevent redundancy. The system checks whether a style rule already exists in the global AST. If the style is already present, Galadriel CSS does not create a new rule. Instead, it simply links the existing rule to the Nenyr class, ensuring that the generated CSS is free of redundant styles. This mechanism contributes to the overall efficiency of Galadriel CSS by reducing the size of the final CSS file.

Generating the Final CSS
After applying the extension, inheritance, context-aware, and unicity rules, Galadriel CSS generates the final CSS output. This output is optimized for performance, ensuring that only the necessary style rules are included and that no redundancies are present. The resulting CSS file is utility-first, meaning it contains reusable, atomic classes that can be applied to various elements across the website.

Practical Example: Defining a Central and Module Documents in Nenyr
In this article, we'll walk through the process of setting up Galadriel CSS with Next.js and demonstrate how to create two simple Nenyr documents: one central document for global styles and one module document for a specific component. This basic setup will give you a comprehensive view of how Galadriel CSS works and how to use Nenyr for styling.

Setting Up the Environment
Before we start, ensure you have the Galadriel CSS development server installed and properly configured. You can refer to the https://galadrielcss-docs.vercel.app/docs/installation for detailed installation instructions. Here’s

Setting Up Galadriel CSS with Next.js
To get started, we need to configure the Galadriel CSS development server alongside the Next.js application. Since Galadriel CSS currently supports Webpack (with future plans for other bundlers like Vite, ESBuild, and Rollup), we will use Webpack in this example.

Start the Galadriel CSS Development Server: In a dedicated terminal window, run the following command to start the Galadriel CSS development server:

Image description

This command sets up the backend server that will process the Nenyr files and generate optimized CSS.

Start the Next.js Development Server: In a separate terminal window, navigate to your Next.js project directory and run:

Image description

This will start the development server for Next.js. Remember, Galadriel CSS should be started first; otherwise, the webpack integration client will attempt to connect to the Galadriel CSS backend and throw an error if it cannot find it.
Install Galadriel CSS Webpack Client: To integrate Galadriel CSS with Next.js, you must install the Galadriel CSS plugin for Webpack. For detailed instructions on how to install and configure the client, refer to the official documentation: https://galadrielcss-docs.vercel.app/docs/integrating-with-next-and-docusaurus.

Global CSS Configuration: In Next.js, the global styles are typically defined in the global.css file. To ensure Galadriel CSS styles are included, add the following directive at the top of your global.css:

Image description

This directive tells the Galadriel CSS integration client to inject the generated styles into your application.

Creating the Central Document
The central document in Galadriel CSS defines the global styles for the entire application. It is the foundation upon which other styles will build. For this example, we will create a file named central.nyr that defines a simple style for the <body> tag.

Folder Structure
For this tutorial, we are using the following folder structure for the Next.js app:

Image description

You can place the central.nyr file inside the src folder, but for this example, we’ll keep it in the root directory for clarity.

Writing the Central Nenyr Document
Inside the central.nyr file, we will define the Central context and create a Nenyr class to style the <body> element. This class will apply flexbox styling to center the contents of the body and set the body’s height and width to 100% of the viewport.

Image description

Explanation
Construct Central: This defines the central context where global styles are applied.
Declare Class("body"): This creates a Nenyr class named “body”, the styles of this class will later be applied to the body element.
Stylesheet: Inside the class, we use the Stylesheet method to define the Nenyr properties for the class. We are using flexbox to center the content both vertically and horizontally, setting the height and width to 100% of the viewport using 100vh and 100vw, respectively.

Once the central.nyr file is created, Galadriel CSS will automatically process it and generate the corresponding CSS.

Now let’s apply the "body" class from the central context to the body element, modify the layout.tsx file in your Next.js application:

Code for layout.tsx

Image description

Here, you must use the type “@class”, this markup indicates that the class we’re going to use to styles the <body> element is located inside the central context; and then we specify the name of the class residing in the central context. The final style application will look like this: className=“@class:body”. The Webpack integration client replaces this marker with the appropriate utility class names during the build process.

Defining the Module Document
In addition to the central context, Galadriel CSS also allows you to define module documents. These are used to define styles specific to certain components or parts of your application. For this example, we will create a module document to style a <div> element that displays the text "Styled With Galadriel CSS".

Writing the Module Nenyr Document
Create a file named page.nyr inside the src/app folder. In this file, define a module context and a class for the <div> tag:

Image description

Explanation
Construct Module: This defines the module context named “page” for the specific component styles.
Declare Class("box"): This creates a Nenyr class named “box”. The styles inside this class will later be applied to a div element.
Stylesheet: The Stylesheet method is used to define the styling properties. In this case, we add padding, set the background color, change the text color, and center the text within the element, etc.

With this page.nyr file in place, Galadriel CSS will generate the necessary styles for the “box” class. Now let’s apply the box class to the <div> element, let’s update the page.tsx file:

Code for page.tsx

Image description

Here, we must specify the location of the class in the Nenyr documents, in this case it is located inside a module context named “page”. Then, we need to use the “@module” type to indicate that it is located in the modules map, and then we must specify in what module the class is located, in this case, it is located in the “page” context, and finally specify the actual class we want to use, here is “box”. The final markup will be: className=“@module:page::box”. The integration client resolves this marker to the appropriate utility class names located at the modules map in the page node during the build process.

These examples demonstrate the simplicity and power of Galadriel CSS for modular and hierarchical styling. By separating global and component-specific styles into distinct Nenyr documents, you can achieve a clean and scalable codebase.
The integration client operates as the backbone of Galadriel CSS’s workflow. During development, it scans application components to identify Nenyr-specific placeholders, or "markups," such as “@class:body“ or “@module:page::box“. These placeholders indicate where styles, defined in Nenyr documents, should be applied. The integration client processes these markers and replaces them with utility class names dynamically generated by Galadriel CSS.

Each Nenyr class corresponds to a set of CSS utility class names, and each property-value within a Nenyr class represents a unique utility class. For example, a backgroundColor: “blue” property-value in a Nenyr class generates a corresponding CSS utility class for setting background color. The integration client links these utility classes to the specified elements in your components, ensuring that the right styles are applied without manual intervention.

The Process of Generating Optimized Styles
Galadriel CSS is designed with optimization at its core. When it creates CSS utility classes, it avoids duplication by checking whether a utility class already exists. If a utility class is already present, it merely establishes a reference between the existing CSS utility class and the Nenyr class that requires it. This approach eliminates redundancy and results in a lean, efficient global stylesheet.

At the end of the process, Galadriel CSS produces a map tracking all Nenyr classes and the utility class names they are linked to; that later will be used by the integration client to inject the necessary data into the output build of the application. This mapping not only enhances maintainability but also ensures that the final output contains only the necessary CSS rules. The result is a build output free of unused styles, pollution, or CSS bloat, leading to improved scalability and performance for your application.

Galadriel CSS: Revolutionizing Style Optimization and Development Workflow
When building modern web applications, developers often face challenges balancing clean, maintainable code during development with highly optimized output for production. Galadriel CSS, offers a groundbreaking solution to these challenges, delivering a streamlined development experience and ensuring peak performance in production builds.

Real-Time Development with Galadriel CSS
If you've started both the Galadriel CSS and Next.js development servers, you’ve likely noticed an impressive feature: real-time style updates. This seamless experience is central to the developer-centric philosophy of Galadriel CSS. Changes to your styles reflect instantly, empowering developers to iterate rapidly and focus on crafting stunning, advanced designs.

But the true magic happens when you transition from development to production. Running the Next.js build command, npm run build, triggers a sophisticated process orchestrated by the integration client provided by Galadriel CSS. This integration ensures that your application remains lightweight, performant, and devoid of unnecessary dependencies.

Understanding the Build Process
Executing the build command initiates Webpack, which, in turn, activates the Galadriel CSS integration client. The client performs the following key tasks:

  1. Dependency Management
  2. Style Application
  3. Clean-Up

Unlike traditional CSS frameworks that may include unnecessary overhead in the final build, Galadriel CSS produces a fully optimized and static output. This approach eliminates any dependency on the system during runtime, ensuring that the production environment is lean and efficient.

In development mode, Galadriel CSS operates without generating any dependency folders or creating additional dependencies. Instead, it utilizes the globally installed system on your machine for seamless functionality. In contrast, during build mode, the integration client automatically downloads the latest version of Galadriel CSS from GitHub Releases. This automation streamlines the build process, reducing manual intervention and simplifying workflows for developers. By handling complex processes behind the scenes, Galadriel CSS allows developers to focus on crafting advanced, visually stunning styles effortlessly using its intuitive Nenyr syntax.

Exploring the Build Output
Once the build process completes, the resulting code resides in the .next folder. This folder contains both the HTML and CSS files necessary for your application. To illustrate the transformation, consider the following:

Development Code Example

Image description

Here, the class attributes use Nenyr markups, a declarative syntax provided by Nenyr to define the application of styles to HTML elements. This clean and readable approach is invaluable during development, allowing developers to focus on structure and functionality without worrying about utility class clutter.

Output Build Code Example

Image description

These elements are the same as those created during development, but this version is part of the Next.js build output. Notably, the Nenyr markups, such as "@class:body" and "@module:page::box", are no longer present in the class attributes. Instead, the class attributes now contain the actual utility class names that style each element. This transformation is handled by the integration client, which replaces the Nenyr markups with the corresponding utility classes. The build components consist solely of static content, with no direct references to Galadriel CSS or Nenyr remaining in the final output. Each utility class applied to the body and div tags corresponds to a property-value pair defined in a Nenyr class. This streamlined and efficient system highlights the true power of Galadriel CSS: enabling clean, maintainable development code while producing optimized, performance-focused build output.

Generated CSS: The Power of Optimization
The CSS generated by Galadriel CSS during the build process exemplifies its commitment to efficiency. Below is an excerpt from the CSS file located in .next/static/css:

Image description

All the utility rules generated by Galadriel CSS are optimized, with no redundancies—only the necessary styles are included. For instance, in both the central document and the “page” module context, styles for display: flex, justifyContent: center, and alignItems: center were defined multiple times. However, Galadriel CSS efficiently generated a single utility class for each style, avoiding repetitive CSS rules. Furthermore, these utility classes were applied to both the body and div elements in the output, ensuring the styles were consistently applied without duplicating rules. This exemplifies the power of Galadriel CSS: it keeps the development code clean and free from the class-name clutter often seen with other frameworks, while the build output remains static, lightweight, and optimized for performance. By delivering clean development workflows and efficient build outputs, Galadriel CSS enhances maintainability, scalability, and overall application performance.

Benefits for Developers

1. Clean Development Workflow

Galadriel CSS leverages the declarative power of Nenyr, allowing developers to focus on creating modular and reusable styles without the distraction of utility class names. This simplifies the development process and improves collaboration across teams.

2. Scalable and Performant Production Builds

The optimized CSS generated during the build process ensures that applications are scalable and performant, with no unnecessary overhead. This is particularly beneficial for large-scale projects where every kilobyte counts.

3. Automation and Efficiency

By automating tasks such as dependency management, style injection, and clean-up, Galadriel CSS reduces manual effort and potential errors. This enables developers to dedicate more time to crafting user experiences.

4. Enhanced Maintainability

The separation of development and production concerns enhances maintainability. Nenyr markups clearly indicate the source of styles, making it easier to locate and update them when necessary.

Conclusion
Galadriel CSS, redefines the standard for style management in web development. By providing a clean development experience with declarative Nenyr markups and delivering highly optimized production builds, it empowers developers to create sophisticated applications with ease.

Galadriel CSS revolutionizes style management with its modular, context-centric approach, addressing maintainability, scalability, and performance in web development. Its innovative design organizes styles into Central, Layout, and Module contexts, ensuring isolation and precision while promoting reuse. By leveraging its custom Nenyr DSL, the framework minimizes CSS bloat and generates optimized utility-first styles, enabling clean, scalable applications that adapt seamlessly as they grow.

With Galadriel CSS, you can focus on what truly matters: designing beautiful, functional, and impactful web applications. Make it better. Make it different. Embrace the power of Galadriel CSS.


The repository of the testing-app example: https://github.com/patrickgunnar/galadrielcss-testing-app

For more about Galadriel CSS: https://galadrielcss-docs.vercel.app/docs

These are some apps built with Next.js and styled with Galadriel CSS:


Thank you for taking the time to learn about Galadriel CSS! I’d love to hear your thoughts and feedback—feel free to share them in the comments below.

Top comments (0)