Now.js Framework Documentation

Now.js Framework Documentation

data-style

EN 15 Apr 2026 12:31

data-style

Overview

data-style binds data values to inline CSS styles. It supports both object and string syntax.

When to use:

  • Set dynamic inline styles
  • Apply computed styles from data
  • Control style properties reactively

Why use it:

  • ✅ Object and string syntax support
  • ✅ Built-in sanitization for security
  • ✅ Reactive updates when data changes
  • ✅ Supports CSS property interpolation
  • ✅ Works with loop-local values from data-for
  • ✅ Supports grouped ternary expressions and unit concatenation in object syntax

Basic Usage

String Syntax

<div data-style="color:textColor; font-size:fontSize"></div>

With data:

{
  textColor: "red",
  fontSize: "16px"
}

Output:

<div style="color: red; font-size: 16px;"></div>

Object Syntax

<div data-style="{ color: textColor, fontSize: fontSize }"></div>

Syntax

String Syntax

<element data-style="cssProperty:expression; cssProperty2:expression2">

Object Syntax

<element data-style="{ cssProperty: expression, cssProperty2: expression2 }">

With Interpolation

<element data-style="width: {{ width }}px; height: {{ height }}px">

Features

1. Simple Style Binding

<div data-style="background-color:bgColor"></div>

With data:

{ bgColor: "#3498db" }

2. Multiple Styles

<div data-style="
  color: textColor;
  background: bgColor;
  padding: padding;
  border-radius: borderRadius
"></div>

3. Object Syntax

<div data-style="{
  backgroundColor: cardBg,
  boxShadow: hasShadow ? '0 2px 8px rgba(0,0,0,0.1)' : 'none'
}"></div>

4. Template Interpolation

<div data-style="
  width: {{ progress }}%;
  transform: translateX({{ offset }}px)
"></div>

5. Computed Values

<div data-style="{
  width: width + 'px',
  opacity: isVisible ? 1 : 0
}"></div>

6. Loop-bound Computed Styles

<div data-for="item in rows">
  <template>
    <div class="meter-fill"
         data-style="{ width: ((item.used_days > item.quota_days ? 100 : (item.quota_days ? (item.used_days * 100 / item.quota_days) : 0))) + '%', backgroundColor: item.color }">
    </div>
  </template>
</div>

This works inside data-for because data-style now evaluates against the stored loop binding context during re-renders. Presentation-only values such as widths can stay in the template instead of being precomputed in the API payload.

Advanced Examples

Progress Bar

<div class="progress-bar">
  <div class="progress-fill"
       data-style="width: {{ progress }}%; background-color: {{ progressColor }}">
  </div>
</div>

<style>
.progress-bar { width: 100%; background: #eee; height: 20px; }
.progress-fill { height: 100%; transition: width 0.3s; }
</style>

With data:

{
  progress: 75,
  progressColor: "#27ae60"
}

Dynamic Positioning

<div class="tooltip"
     data-style="{
       top: position.y + 'px',
       left: position.x + 'px',
       opacity: isVisible ? 1 : 0
     }">
  <span data-text="tooltipText"></span>
</div>

Avatar with Size

<img class="avatar"
     data-attr="src:user.avatar"
     data-style="width: {{ avatarSize }}px; height: {{ avatarSize }}px">

Grid Layout

<div class="grid"
     data-style="
       grid-template-columns: repeat({{ columns }}, 1fr);
       gap: {{ gap }}px
     ">
  <div data-for="item in items">
    <template>
      <div class="grid-item" data-text="item.name"></div>
    </template>
  </div>
</div>

Theme Colors

<div class="card"
     data-style="{
       backgroundColor: theme.cardBg,
       color: theme.textColor,
       borderColor: theme.borderColor
     }">
  <h3 data-text="title"></h3>
</div>

Animated Element

<div class="animated-box"
     data-style="{
       transform: 'rotate(' + rotation + 'deg) scale(' + scale + ')',
       transition: 'transform 0.3s ease'
     }">
</div>

Statistics Meter With Grouped Ternary

<span class="leave-statistics-meter-fill"
  data-style="{ width: ((item.used_days > item.quota_days ? 100 : (item.quota_days ? (item.used_days * 100 / item.quota_days) : 0))) + '%', backgroundColor: item.color }">
</span>

Grouped ternary expressions plus string concatenation are supported in object syntax, so widths like 30% can be produced inside the template engine without moving that presentation concern into backend data.

API Reference

Supported CSS Properties

All standard CSS properties are supported. Use either:

  • kebab-case: background-color, font-size
  • camelCase (in object syntax): backgroundColor, fontSize

Security Sanitization

Dangerous values are sanitized:

Safe Blocked
#fff, rgb(...) javascript:...
url(/image.jpg) data:text/html,...
10px, 50% expression(...)
data:image/png,... url(javascript:...)

Allowed URL Protocols

Protocol Allowed
http://
https://
Relative paths
data:image/*
javascript:
data:text/html

Common Pitfalls

⚠️ 1. Missing Units

<!-- ❌ Wrong - missing unit -->
<div data-style="width: {{ width }}"></div>  <!-- width = 100 -->

<!-- ✅ Correct - include unit -->
<div data-style="width: {{ width }}px"></div>
<div data-style="width: {{ width }}%"></div>

⚠️ 2. Invalid Property Names

<!-- ❌ Wrong in object syntax -->
<div data-style="{ font-size: size }"></div>

<!-- ✅ Correct - use camelCase -->
<div data-style="{ fontSize: size }"></div>

<!-- ✅ Or use string syntax -->
<div data-style="font-size: {{ size }}"></div>

⚠️ 3. Security Blocks

// ❌ Will be blocked
{ bgUrl: "javascript:alert('xss')" }

// ✅ Use safe URLs
{ bgUrl: "/images/background.jpg" }

⚠️ 4. Overusing Inline Styles

<!-- ❌ Too many inline styles - hard to maintain -->
<div data-style="
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 20px;
  margin: 10px;
  background: white;
"></div>

<!-- ✅ Use CSS classes for static styles -->
<div class="centered-card" data-style="background: {{ dynamicBg }}"></div>

⚠️ 5. Pick the Syntax That Fits the Value

<!-- ✅ Object syntax is ideal for computed values and loop-local data -->
<div data-style="{ width: progress + '%', backgroundColor: color }"></div>

<!-- ✅ String syntax is still fine when you already have a literal CSS string -->
<div data-style="width: {{ progress }}%; background-color: {{ color }}"></div>

Use object syntax when you want the template engine to compute values such as percentages, pixel sizes, or conditional colors. Use string syntax when the CSS string itself is already the clearest representation.

Comparison: data-style vs CSS Classes

Use Case Recommendation
Static styles CSS classes
Toggle styles data-class + CSS
Dynamic values (colors, sizes) data-style
Computed positions data-style
Theme colors data-style with CSS variables