Introduction

What is LayerCSS? LayerCSS is a design language based on CSS that introduces advanced features to facilitate the creation of modular, reusable, and maintainable styles. It is designed to overcome the limitations of traditional CSS by adding support for global and local variables, nested blocks, layers (@layer), and structured comments.

"Modularity: Divide your styles into logical sections.
Reusability: Define values once and use them in multiple places.
Ease of Maintenance: Change a value in one place and affect the entire project."

Creator: Sebastian (Balthier) Ordoñez Arias, an amateur programmer with basic knowledge in web design and application development. This project was born as a personal exploration to simplify CSS development and make it accessible to everyone.

What is .lyc?

The `.lyc` file format is the core of LayerCSS. It extends traditional CSS by introducing new syntax and features that make styling more intuitive and efficient. Here are some key aspects:

// Example of a .lyc file
@layer base {
  body {
    margin: 0;
    padding: 0;
    font-family: Arial, sans-serif;
  }
}
@layer components {
  button {
    background: var(--primary-color);
    border: none;
    padding: 10px 20px;
  }
}
      

Key Features

Detailed Example

Below is a basic example of a `.lyc` file with detailed comments explaining each part of the code. This file uses the fundamental features of LYC: global variables, `calc()`, mixins (`@mixin` and `@include`), and inheritance with `@extend`.

Comparison: .lyc vs .css

.lyc Code

/* 
  Global variables:
  - Defined at the top of the file.
  - Can be used anywhere in the file.
*/
--primary-color: #3498db; /* Light blue */
--secondary-color: #e74c3c; /* Red */
--font-size: 16px; /* Base font size */

/*
  Mixin for reusable buttons:
  - A mixin is a reusable block of styles.
  - Defined with @mixin and included with @include.
*/
@mixin button-style {
  background: var(--primary-color); /* Uses global variable --primary-color */
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 5px;
  cursor: pointer;
}

/*
  Base styles for the body:
  - General styles for the page.
  - Uses global variables for consistency.
*/
body {
  margin: 0;
  padding: 0;
  font-family: 'Arial', sans-serif;
  background: var(--secondary-color); /* Uses global variable --secondary-color */
  color: var(--primary-color); /* Uses global variable --primary-color */
  font-size: var(--font-size); /* Uses global variable --font-size */
}

/*
  Components:
  - Specific styles for components like buttons.
  - Uses @include to include the mixin button-style.
*/
.button {
  @include button-style; /* Includes styles defined in the mixin button-style */
  box-shadow: 0 0 calc(5px + 2px) rgba(0, 0, 0, 0.3); /* Uses calc() for shadow size */
}

.button:hover {
  transform: scale(calc(1 + 0.1)); /* Uses calc() to increase button size on hover */
  background: var(--secondary-color); /* Changes background color on hover */
}

/*
  Inheritance with @extend:
  - Shares styles between classes.
  - Here, .warning-message inherits styles from .error-message.
*/
.error-message {
  color: red;
  font-weight: bold;
}

.warning-message {
  @extend error-message to warning-message; /* Inherits styles from .error-message */
  color: orange; /* Overrides color to make it orange */
}
            

.css Output

body {
  margin: 0;
  padding: 0;
  font-family: 'Arial', sans-serif;
  background: #e74c3c;
  color: #3498db;
  font-size: 16px;
}

.button {
  background: #3498db;
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 5px;
  cursor: pointer;
  box-shadow: 0 0 7px rgba(0, 0, 0, 0.3);
}

.button:hover {
  transform: scale(1.1);
  background: #e74c3c;
}

.error-message {
  color: red;
  font-weight: bold;
}

.warning-message {
  color: orange;
  font-weight: bold;
}
            

Comparison: .lyc vs .css

Characteristic Variables Nested Blocks Layers Comments Animations Learning Curve
.lyc Native Support Native Support Native Support Structured Comments Native Support Easy
Sass Supported Supported Not Supported Standard CSS Comments Supported Moderate
Less Supported Supported Not Supported Standard CSS Comments Supported Easy
PostCSS Supported via plugins Supported via plugins Supported via plugins Standard CSS Comments Supported via plugins Moderate

LYC Code Example

Below is an example of LYC code that you can copy and paste into the compiler to test its features.

/* Global Variables */
--primary-color: #FF5733;
--secondary-color: #33FF57;
--font-size: 16px;

/* Mixin for reusable buttons */
@mixin button-style {
  background: var(--primary-color);
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 5px;
  cursor: pointer;
}

/* Base Styles */
body {
  margin: 0;
  padding: 0;
  font-family: 'Arial', sans-serif;
  background: var(--secondary-color);
  color: var(--primary-color);
  font-size: var(--font-size);
}

/* Components */
.button {
  @include button-style;
  box-shadow: 0 0 calc(5px + 2px) rgba(0, 0, 0, 0.3);
}

.button:hover {
  transform: scale(calc(1 + 0.1));
  background: var(--secondary-color);
}

/* Inheritance */
.error-message {
  color: red;
  font-weight: bold;
}

.warning-message {
  @extend error-message to warning-message;
  color: orange;
}
        

Compiler Space


      

Current and Future Process

Where We Are in the Process

So far, we have implemented a preprocessor or partial interpreter for the LYC language. This preprocessor performs the following tasks:

  • Variable replacement: Processes global and local variables (using var(--name)).
  • Mathematical expressions: Evaluates expressions within calc().
  • Mixins (@mixin and @include): Allows code reuse through mixins.
  • Inheritance with @extend: Reuses styles between selectors.
  • Dynamic structures: Uses malloc and realloc to dynamically manage variables, mixins, and other elements.
  • Local scopes: Local variables are stored in a stack and do not appear in the output file.

However, this is only a partial compiler, as there are still several important compilation stages that need to be implemented.

What Will Be Added

To transform our preprocessor into a full compiler, we need to add the following features:

A. Stages of a Full Compiler

  • Lexical analysis (Lexing): Converts source code into tokens (keywords, identifiers, operators, etc.).
  • Syntax analysis (Parsing): Builds an abstract syntax tree (AST) from the tokens generated by the lexer.
  • Semantic analysis: Verifies that the AST is valid according to the language rules.
  • Intermediate code generation: Translates the AST into an intermediate format that is easier to optimize or compile.
  • Optimization: Improves the intermediate code to make it more efficient.
  • Final code generation: Produces the output file in the desired format (in this case, CSS).

B. Additional Features That Can Be Added

In addition to the compiler stages, we can add the following specific features for LYC:

  • Support for advanced functions: Implement custom functions in LYC, such as darken(color, percentage) or lighten(color, percentage).
  • Advanced nested rules: Allow more complex nested CSS rules, similar to those found in SASS or LESS.
  • Strict mode: Add a strict mode that detects potential errors, such as unused variables or duplicate rules.
  • Compatibility with external tools: Integrate LYC with tools like PostCSS or Autoprefixer to enhance browser compatibility.
  • Automatic minification: Add an option to generate minified CSS automatically.
  • Debugging: Include comments in the generated CSS to facilitate debugging.
  • Documentation and examples: Create detailed documentation for LYC and provide usage examples.

Conclusion

LayerCSS simplifies CSS development with advanced features like variables, nested blocks, and layers. It's ideal for both small and large projects.

Note from the Creator: This project is in its early stages. Your contribution will be invaluable!