Skip to content

Instantly share code, notes, and snippets.

@tzmartin
Created February 26, 2025 04:42

Revisions

  1. tzmartin created this gist Feb 26, 2025.
    146 changes: 146 additions & 0 deletions vue-component-styling.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,146 @@
    ```
    <think>
    Let me reflect on the CSS styling and component issues we encountered and formulate a set of best practices for working with Vue components and CSS. This will help avoid similar issues in the future.
    Key issues we encountered:
    1. CSS variable syntax: Using parentheses `(--variable)` instead of the correct `var(--variable)` or `[--variable]` in Tailwind
    2. Class inheritance in Vue components: Vue doesn't automatically apply parent component classes to child components
    3. Component styling vs. functionality separation: Mixing component logic with styling created confusion
    4. Debugging complexity: Difficulty in tracing why styles weren't being applied
    5. Default vs. override styles: Challenges in determining which styles take precedence
    I'll formulate a comprehensive set of best practices focusing on:
    - Vue component styling patterns
    - CSS variable usage in Vue and Tailwind
    - Debugging styling issues
    - Separation of concerns
    - Component design principles
    </think>
    ```

    # Best Practices for Vue Component Styling: Lessons Learned

    Based on our experience with the `PromptInput` styling issue, here are some best practices to follow when working with Vue components and CSS, particularly in applications using Tailwind CSS:

    ## 1. Component Styling Patterns

    **Rule: Use Wrapper Elements for Component Styling**
    ```vue
    <!-- Recommended ✅ -->
    <div class="my-custom-styles">
    <MyComponent>
    <!-- Content -->
    </MyComponent>
    </div>
    <!-- Avoid ❌ -->
    <MyComponent class="my-custom-styles">
    <!-- Content -->
    </MyComponent>
    ```

    **Why**: Vue's class inheritance system can be unpredictable. Wrapper elements give you direct control over styling without relying on Vue's attribute inheritance.

    ## 2. CSS Variable Usage

    **Rule: Use Correct Syntax for CSS Variables**
    ```css
    /* In Tailwind classes */
    /* Correct ✅ */
    class="max-w-[var(--my-variable)]"
    /* or */
    class="max-w-[--my-variable]"

    /* Incorrect ❌ */
    class="max-w-(--my-variable)"
    ```

    **Why**: Tailwind arbitrary values require square brackets, not parentheses. When using `var()` syntax, it must be inside the square brackets.

    ## 3. Component Design

    **Rule: Separate Styling from Component Logic**
    ```vue
    <!-- Component (PromptInput.vue) -->
    <template>
    <div>
    <slot></slot>
    </div>
    </template>
    <!-- Usage -->
    <template>
    <div class="styling-container">
    <PromptInput />
    </div>
    </template>
    ```

    **Why**: Components should focus on functionality and structure, while styling should be applied at the implementation level. This improves reusability and maintainability.

    ## 4. CSS Variable Definition

    **Rule: Define CSS Variables at the Appropriate Scope**
    ```css
    /* Global variables in a main CSS file */
    :root {
    --primary-color: #3498db;
    --breakpoint-md: 768px;
    }

    /* Component-specific variables */
    .component-container {
    --component-spacing: 1rem;
    }
    ```

    **Why**: Properly scoped variables prevent conflicts and make it clear where values are defined.

    ## 5. Debugging Styling Issues

    **Rule: Use Temporary Visual Debugging Techniques**
    ```vue
    <!-- Add temporary debug visualization -->
    <pre v-if="debug" class="debug-info">
    Props: {{ JSON.stringify(props) }}
    Classes: {{ JSON.stringify($attrs.class) }}
    </pre>
    ```

    **Why**: Visualizing component props and attributes helps identify why styles aren't being applied as expected.

    ## 6. Class Overrides

    **Rule: Use the `!important` Flag Sparingly and Deliberately**
    ```html
    <!-- When necessary to override base styles -->
    <div class="base-styles !rounded-lg !p-4">
    <!-- Content -->
    </div>
    ```

    **Why**: Using `!important` (via Tailwind's `!` prefix) should be a deliberate choice, not a default approach to styling problems.

    ## 7. Component API Design

    **Rule: Keep Component Props Focused on Behavior, Not Styling**
    ```js
    // Good ✅
    defineProps({
    isLoading: Boolean,
    maxHeight: [Number, String]
    })

    // Avoid for styling ❌
    defineProps({
    className: String,
    color: String,
    rounded: Boolean
    })
    ```

    **Why**: Components with many style-related props become harder to maintain. Style customization is better handled via CSS classes at the implementation level.

    ---

    By following these practices, you'll create more maintainable, predictable, and reusable components while avoiding the common pitfalls we encountered with the `PromptInput` component styling.