Why Jeet’s Ratio‑Based Mixins Keep Markup Semantic and Layout Flexible
Jeet uses Stylus mixins to calculate fluid grid widths at compile time, letting developers keep HTML semantic while still achieving flexible layouts. This blog explains how the ratio‑driven system works, walks through a concrete example, and weighs its pros and cons against modern CSS Grid.
28 Oct 2025, 06:40 UTC

The Problem: Presentational Classes vs. Semantic Markup
When designers use a utility‑heavy framework like Bootstrap, the HTML often becomes a collection of presentational classes such as col-md-4. While this makes the layout obvious to a developer, it clutters the markup and can hide the content’s real meaning. Semantic HTML—using article, section, aside, etc.—is easier to read, maintain, and accessible. The challenge is to keep the two worlds separate: semantic markup on the one hand, flexible, fluid grids on the other.
Jeet’s Core Design Decision
Jeet solves this by moving all layout logic into Stylus mixins. Instead of sprinkling class names into the markup, developers write column(1/3) or span(1/4) inside their stylesheet. These mixins calculate the percentage width, gutters, and clear behavior at compile time. The resulting CSS is minimal, specific to the rules you actually use, and free of the generic utility classes that often cause specificity wars.
Why Ratio‑Based Mixins?
- Fluidity: The mixin receives a fraction (e.g.,
1/3) and generates awidthin percentages that adapts to any container width. - Gutter Consistency: Gutters are expressed as a ratio of the container, so nested grids automatically inherit the correct spacing without extra markup.
- Compile‑Time Calculation: All arithmetic happens when Stylus compiles, keeping the runtime CSS lean and predictable.
How Jeet Computes Widths
Below is a simplified representation of the column() mixin logic. The actual implementation in Jeet is more robust, but the core idea is the same.
// Simplified column mixin
column(fraction, options = {})
// fraction is a string like "1/3"
[numerator, denominator] = fraction.split('/')
widthPercent = (numerator / denominator) * 100
gutterPercent = options.gutter or 2 // default gutter 2%
// Apply float and negative margins for the gutter
float: left
width: widthPercent - gutterPercent
margin-right: gutterPercent
// Clear after a set number of columns if $cycle provided
if options.cycle
&:nth-child(options.cyclen) { clear: both }
Key points:
- The mixin outputs a
float: leftrule, which was the standard before Flexbox and Grid were widely supported. - Negative margins are used to compensate for the gutter, ensuring the total width of a row equals 100%.
- The
$cycleoption clears floats after a specified number of columns, allowing the layout to wrap without extra wrapper elements.
Worked Example: Three‑Column Card Layout
Let’s build a simple card component that displays three cards per row, with a gutter that scales with the container. Using Jeet, the stylesheet might look like this:
// card.styl
.card
column(1/3, $cycle: 3)
background: #f9f9f9
padding: 1rem
box-sizing: border-box
// Optional: reset margin on the last column
&:nth-child(3n) { margin-right: 0 }
When compiled, Jeet generates CSS similar to:
.card {
float: left;
width: 32.6667%; /* 33.3333% minus 2% gutter */
margin-right: 2%;
background: #f9f9f9;
padding: 1rem;
box-sizing: border-box;
}
.card:nth-child(3n) {
margin-right: 0;
}
Notice that the markup remains clean: <div class="card"> only indicates a logical block, not a layout class. The fluid width adapts to the container’s width, and the gutter stays proportional. If you need to change the number of columns, you only modify the Stylus file and recompile; no HTML changes are required.
Trade‑offs of a Preprocessor Grid
- Recompilation Required: Altering the layout (e.g., switching from three to four columns) forces a stylesheet rebuild. In rapid prototyping, this can be slower than toggling a class.
- Float‑Based Output: Jeet’s core uses floats and negative margins. While this works in all browsers, it can lead to subtle differences compared to Flexbox or CSS Grid, especially with source order, equal‑height columns, and right‑to‑left (RTL) layouts.
- Maintenance: The Jeet package has seen little recent activity. If you rely on a library that may not receive updates for new CSS features, you risk missing out on native optimizations.
- Learning Curve: Developers must understand Stylus syntax and the mixin API, which is an extra step compared to using plain CSS classes.
When to Use Jeet Today
Jeet shines in environments where:
- Design systems dictate a strict, semantic markup structure.
- Teams prefer to keep all layout logic in stylesheets to avoid cluttering HTML.
- Legacy projects still rely on float‑based layouts and need a predictable, maintainable fallback.
For new projects, consider native CSS Grid or Flexbox first. They offer similar flexibility without the need for a preprocessor, and they handle nested grids, equal‑height columns, and RTL more naturally. However, if your workflow already uses Stylus and you value semantic markup, Jeet can still be a viable choice—just verify the package’s maintenance status and test the compiled output in your target browsers.
Actionable Checklist
- Install a recent Jeet version via
npm install jeetand confirm the last publish date. - Create a minimal Stylus file that uses
column()and compile it. - Inspect the generated CSS for correct width, gutter, and clear rules.
- Render the compiled markup in Chrome, Firefox, and Safari at various viewport widths.
- Compare the visual result with a native Grid implementation:
display: grid; grid-template-columns: repeat(3, 1fr);. - If the float‑based layout meets your needs and you prefer semantic markup, integrate Jeet into your build pipeline.
- If you encounter rounding gaps or RTL issues, consider switching to native Grid or adding custom overrides.
By following this process, you can decide whether Jeet’s ratio‑based mixins are the right fit for your project’s architecture and design goals.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.