July 9, 2022

🚀 Style your Nette Framework website faster with Stylify CSS

Style your Nette Framework website faster and intuitively with Stylify.



Style your Nette Framework website faster with Stylify. Don’t study selectors and syntax. Use pure CSS syntax and get generated CSS with advanced optimization for production.

For the example below, you can check out the Nette Framework Integration Example.

🚀 Nette Introduction

Nette is a PHP framework made by David Grudl and it is a great alternative to Symfony and Laravel. It has an amazing templating system called Latte that uses a similar syntax to PHP and by default has context-sensitive escaping (which no other framework has). In my opinion, it is easier to learn, because it comes with a simple structure by default, it has no dependencies and fewer patterns to learn.

💎 Stylify CSS Introduction

Stylify is a library that uses CSS-like selectors to generate optimized utility-first CSS based on what you write.

  • ✅ CSS-like selectors
  • ✅ No framework to study
  • ✅ Less time spent in docs
  • ✅ Mangled & Extremely small CSS
  • ✅ No CSS purge needed
  • ✅ Components, Variables, Custom selectors
  • ✅ It can generate multiple CSS bundles

Also we have a page about what problems Stylify CSS solves and why you should give it a try!

Nette installation

The easiest way to start with Nette is to use Composer following this guide:

  • Run composer create-project nette/web-project nette-blog
  • Go to the project dir cd nette-blog
  • To start the web run php -S 0.0.0.0:80 -t www
  • The web should be available at http://localhost

Stylify CSS setup

Because Nette doesn’t come with any bundler nor with any javascript package by default, we are going to use the Stylify CSS Bundler.

Install the bundler yarn add -D @stylify/bundler. Create the bundles.js file in the project root with the following content:

const { nativePreset } = require('@stylify/stylify');
const { Bundler } = require('@stylify/bundler');

// Detect watch mode
const watchFiles = process.argv[process.argv.length - 1] === '--w';
const bundler = new Bundler({
	compiler: {
		// Mangle selectors for production
		mangleSelectors: !watchFiles,
		// Match n:class attributes
		selectorsAreas: [
			'(?:^|\\s+)n:class="([^"]+)"',
			'(?:^|\\s+)n:class=\'([^\']+)\''
		]
	},
	watchFiles: watchFiles
});

bundler.bundle([
	{
		files: ['./app/Presenters/templates/@layout.latte'],
		outputFile: './www/static/css/layout.css'
	},
	{
		files: ['./app/Presenters/templates/Homepage/default.latte'],
		outputFile: './www/static/css/homepage.css'
	}
]);

This config above will generate two bundles:

  • Layout - used globally
  • Homepage - only for the homepage

We could of course generate CSS for the whole project into one file. But it would make the CSS unnecessary larger.

Now open the package.json file and add the following scripts:

"scripts": {
	"build": "node bundles.js",
	"watch": "node bundles.js --w"
}

The last step is to edit the templates. Open the App/Presenters/Templates/@layout.latte and add the link to the layout CSS file:

<link rel="stylesheet" href="/static/css/layout.css">

In the App/Presenters/Templates/Homepage/default.latte add the following:

{block content}
<link rel="stylesheet" href="/static/css/homepage.css">
<div class="font-size:48px text-align:center">
	Hello World!🎉
</div>

If you run the yarn watch, Stylify CSS will generate CSS and will watch any file for change.

Components

To avoid bloated templates with utilities, you can configure components directly in files, where they are used using content options (expects javascript object without brackets) or in the compiler config.

First, let’s add the global container component. Open the bundles.js, and the following:

const compilerConfig = {
	components: {
		container: 'max-width:1024px margin:0_auto'
	}
}

const bundler = new Bundler({ /*...*/ });

Now we can use it in the whole project. In our case, we add it to the layout:

<main class="container">{include content}</main>

On the homepage, we can add a local component for the title using content options:

{*
	stylify-components
		title: 'font-size:48px text-align:center'
	/stylify-components
*}

{block content}
<link rel="stylesheet" href="/static/css/homepage.css">
<div class="title">Hello World!🎉</div>

Variables

It’s always a good idea to have clean and flexible code without hardcoded values. Variables can be defined in the same way as components. Let’s modify the title component:

{*
	stylify-variables
		titleFontSize: '48px'
	/stylify-variables

	stylify-components
		title: 'font-size:$titleFontSize text-align:center'
	/stylify-components
*}

{block content}
{* ... *}

Mapping files

When a template includes a component or a nested template part, we can add it to the bundle using stylify-files option.

Let’s create the _content.latte template part next to the default.latte with the following content:

{*
	stylify-components
		title: 'font-size:$titleFontSize text-align:center'
	/stylify-components
*}
<div class="title">Hello World!🎉</div>

The Homepage/default.latte then informs the bundler about external paths using stylify-files option that expects paths separated by a space or a new line:

{*
...
stylify-files
	./_content.latte
/stylify-files
*}

{block content}
{include './_content.latte'}

The content in the ./_content.latte is automatically processed by the bundler.

🔥 Production build:

If you run yarn build, the selectors will be shrunk and the CSS minified:

@layout.latte:

<main class="a">{include content}</main>

_content.latte:

<div class="d">Hello World!🎉</div>

layout.css:

.b,.a{max-width:1024px}
.c,.a{margin:0 auto}

homepage.css:

:root {--titleFontSize: 48px;}
.e,.d{font-size:48px}
.f,.d{text-align:center}

Configure anything you need

The examples above don’t include everything Stylify CSS can do:

Feel free to check out the docs to learn more 💎.

Give as Feedback!
Do you like Stylify CSS? Let us know by starring our repo!