Styling and Interactions

Perserve your design system’s appearance and behavior in your app

This guide will help you understand how DevLink preserves the styles of your design system and the interactions of your Webflow components in your app.

Styles

Add your global styles to your application to ensure that your Webflow components are styled consistently across your app.

1// layout.tsx
2import '@/devlink/global.css';

DevLink uses a combination of CSS Modules and global styles to maintain the look and feel of your Webflow components:

Each component exported through DevLink gets its own CSS Module file with component-specific styles that:

  • Isolate component styles to prevent global CSS conflicts
  • Preserve Webflow styling details including media queries
  • Maintain responsive behavior
  • Support special selectors like :global() for Webflow classes
navbar.module.css
1.navbar-component {
2 display: flex;
3 min-height: 80px;
4 padding-right: 2rem;
5 padding-left: 2rem;
6 align-items: center;
7 background-color: transparent;
8}
9
10.navbar-container {
11 display: flex;
12 width: 96%;
13 height: 80px;
14 max-width: 1280px;
15 margin-right: auto;
16 margin-left: auto;
17 justify-content: space-between;
18 align-items: center;
19}

When working with custom HTML IDs in components, see the Custom IDs and selectors section below.

The global.css file contains styles that apply across all components:

  • Normalize.css resets for browser consistency
  • Webflow’s base styles (e.g. .w-slider and .w-nav-link)
  • Font imports from your Webflow project
  • CSS Variables for colors and other properties
  • Default element styling and form element resets
  • Custom CSS tag selectors from your site (e.g. “All Links” or “Body (All Pages)” style selectors)

For global styling that should affect all components, use the “Body (all pages)” tag selector in Webflow rather than setting classes directly on the body element, as the latter won’t be included in global.css.

global.css
1/* 1. Font imports from Webflow */
2@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap');
3
4/* 2. Normalize.css resets - browser consistency */
5html {line-height:1.15;-webkit-text-size-adjust:100%} body {margin:0}
6/* More normalize.css rules... */
7
8/* 3. Color swatches as CSS variables */
9:root {
10 --primary-color: hsla(210, 100%, 56%, 1.00);
11 --secondary-color: hsla(258, 100%, 56%, 1.00);
12 /* More color variables from your Webflow project */
13}
14
15/* 4. Webflow-specific classes for components */
16.w-slider { position: relative; }
17.w-nav-link { position: relative; display: inline-block; }
18/* More Webflow component classes... */
19
20/* 5. Default element styling */
21body {
22 font-family: 'Inter', sans-serif;
23 color: #333;
24 margin: 0;
25 padding: 0;
26}
27
28a {
29 font-weight: 700;
30 text-decoration: underline;
31}

Advanced configuration

If you need to customize the styles of your Webflow components, you can configure the following options:

  1. CSS modules
    By default, DevLink uses CSS modules to isolate component styles. If needed, you can disable this with:

    .webflowrc.js
    1module.exports = {
    2 cssModules: false
    3}
  2. Tag selectors
    To minimize global styling and only include the bare essentials:

    .webflowrc.js
    1module.exports = {
    2 skipTagSelectors: true
    3}

    When using skipTagSelectors: true, ensure parent elements of DevLink components have defined heights/widths, or set height: 100% on your HTML and body elements to allow proper rendering of navigation components.

Interactions

Webflow interactions are JavaScript-powered animations and transitions. DevLink preserves these interactions by wrapping them in a special provider component:

1// layout.tsx
2import { DevLinkProvider } from '@/devlink/DevLinkProvider';
3import '@/devlink/global.css';
4
5export default function RootLayout({
6 children,
7}: {
8 children: React.ReactNode;
9}) {
10 return (
11 <html lang="en">
12 <body>
13 <DevLinkProvider>
14 {children}
15 </DevLinkProvider>
16 </body>
17 </html>
18 );
19}

The DevLinkProvider must wrap your application for Webflow interactions to work. Webflow Cloud apps can handle this automatically if you set provider: true in your DevLink configuration.

Page interactions

Webflow components support page triggers with a limitation: DevLink only exports the first page interaction. If a component uses multiple page interactions across different pages, DevLink will only export the first one.

Advanced styling

Custom IDs and selectors

When you add custom HTML IDs to your Webflow components, DevLink automatically transforms them using CSS Modules. This transformation helps keep your component styles organized and prevents any conflicts between different parts of your application. The transformed IDs follow a specific pattern that combines your component name with your custom ID:

<ComponentName>_<custom-id>__<unique-identifier>

For example, if you add a custom ID to a Grid element within a Hero component named featured-section, DevLink will transform it into a unique identifier like Hero_featured-section__abc123 in the generated code.

To target these elements with CSS, use wildcard selectors that match the component name and custom ID pattern:

1[id*="Hero_featured-section__"] {
2 /* your styles */
3}
Custom ID
Custom ID

Dynamic IDs and styling hooks

Some Webflow elements use HTML IDs as styling hooks, including Grid and Quick Stack components. These IDs are visually indicated by pink markers in the Style Panel.

When attempting to make these IDs dynamic using component properties, you’ll encounter a technical limitation. DevLink can’t simultaneously preserve the required CSS styling references while supporting dynamic ID values. Here’s why:

1// ❌ Problematic approach - will break styling
2import { Grid } from '@/devlink/components/grid';
3
4function DynamicSection({ sectionId }) {
5 return (
6 <Grid id={sectionId}/>
7 );
8}

The issue arises because Webflow generates CSS that directly references these IDs:

1/* Generated Webflow CSS */
2#grid-123 {
3 display: grid;
4 grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
5 /* Other grid styles... */
6}

When you make the ID dynamic, the CSS selector no longer matches, breaking the styling.

Recommended solution: Custom attributes

Instead of modifying IDs, use custom attributes for dynamic values. This preserves Webflow’s styling while allowing for dynamic identification:

1// ✅ Recommended approach
2import { Grid } from '@/devlink/components/grid';
3
4function DynamicSection({ sectionId }) {
5 return (
6 <Grid
7 data-section-id={sectionId}
8 // Original Webflow ID remains unchanged
9 id="grid-wrapper-123"
10 />
11 );
12}
Built with