Skip to main content
Glama
Luko248

@depthark/css-first

confirm_css_property_usage

Confirm user consent for CSS property usage and receive implementation guidance with fallback options when needed.

Instructions

Confirms user consent for using a specific CSS property and provides implementation guidance.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
css_propertyYesCSS property name user wants to use
user_consentYesUser consent to use this CSS property
fallback_neededNoWhether fallback solutions are needed

Implementation Reference

  • src/index.ts:290-351 (registration)
    Registration of the 'confirm_css_property_usage' tool, including input schema (Zod) and complete inline handler logic. Handles user consent, calls helpers for alternatives or guidance, and returns JSON response.
    server.tool(
      "confirm_css_property_usage",
      "Confirms user consent for using a specific CSS property and provides implementation guidance.",
      {
        css_property: z.string().describe("CSS property name user wants to use"),
        user_consent: z.boolean().describe("User consent to use this CSS property"),
        fallback_needed: z
          .boolean()
          .optional()
          .describe("Whether fallback solutions are needed"),
      },
      async (args: {
        css_property: string;
        user_consent: boolean;
        fallback_needed?: boolean;
      }) => {
        try {
          const { css_property, user_consent, fallback_needed = false } = args;
    
          const result = !user_consent
            ? {
                message: `User declined to use ${css_property}. Here are alternative CSS-ONLY solutions (JavaScript solutions are not provided by this tool).`,
                alternative_suggestions: await getAlternativeCSSProperties(
                  css_property
                ),
              }
            : {
                message: `User confirmed usage of ${css_property}. Here's the implementation guidance:`,
                implementation_guidance: await getImplementationGuidance(
                  css_property,
                  fallback_needed
                ),
                css_property: css_property,
                approved: true,
              };
    
          return {
            content: [
              {
                type: "text" as const,
                text: JSON.stringify(result, null, 2),
              },
            ],
          };
        } catch (error) {
          return {
            content: [
              {
                type: "text" as const,
                text: JSON.stringify(
                  {
                    error: error instanceof Error ? error.message : "Unknown error",
                  },
                  null,
                  2
                ),
              },
            ],
          };
        }
      }
    );
  • Helper function called when user declines consent, providing predefined alternative suggestions (mostly JS-based, but tool notes CSS-only).
    export async function getAlternativeCSSProperties(declinedProperty: string): Promise<string[]> {
      const alternatives: Record<string, string[]> = {
        'scroll-snap-type': ['overflow-x with JavaScript', 'transform with JavaScript', 'intersection observer'],
        'display: grid': ['display: flex', 'float-based layout', 'inline-block layout'],
        'container-type': ['media queries', 'viewport units', 'JavaScript resize observer'],
        'css-scroll-snap': ['JavaScript carousel library', 'touch event handling', 'transform animations']
      };
      
      return alternatives[declinedProperty] || ['JavaScript-based solution', 'Traditional CSS approach'];
    }
  • Helper function providing detailed ImplementationGuidance object with basic usage, best practices, fallbacks (if needed), and multi-line code examples for specific CSS properties used in the tool.
    export async function getImplementationGuidance(
      cssProperty: string,
      needsFallback: boolean = false
    ): Promise<ImplementationGuidance> {
      const guidance: Record<string, ImplementationGuidance> = {
        'padding-inline': {
          basic_usage: '.element { padding-inline: 1rem; }',
          best_practices: [
            'Use logical properties for international layouts',
            'Combine with rem units for scalable spacing',
            'Prefer over padding-left/right for better RTL support',
            'Use padding-inline-start/end for fine control'
          ],
          fallbacks: needsFallback ? [
            'Use padding-left/right for older browsers',
            'Provide CSS custom properties for direction-aware values',
            'Use Autoprefixer for automatic fallbacks'
          ] : [],
          example_code: `
    .card {
      padding-inline: 1.5rem;
      padding-block: 1rem;
      /* Fallback for older browsers */
      padding: 1rem 1.5rem;
    }
    
    /* RTL support automatically handled */
    [dir="rtl"] .card {
      /* No additional styles needed */
    }
    
    /* Fine-grained control */
    .asymmetric {
      padding-inline-start: 2rem;
      padding-inline-end: 1rem;
    }`
        },
        'margin-inline': {
          basic_usage: '.element { margin-inline: auto; }',
          best_practices: [
            'Use margin-inline: auto for centering',
            'Combine with modern units like rem, ch, or vi',
            'Prefer over margin-left/right for international layouts',
            'Use negative values for overlapping effects'
          ],
          fallbacks: needsFallback ? [
            'Use margin-left/right for older browsers',
            'Provide direction-specific fallbacks',
            'Use CSS custom properties for dynamic values'
          ] : [],
          example_code: `
    .centered {
      margin-inline: auto;
      max-width: 60ch;
      /* Fallback */
      margin-left: auto;
      margin-right: auto;
    }
    
    .offset {
      margin-inline-start: 2rem;
      margin-inline-end: 1rem;
    }`
        },
        'border-inline': {
          basic_usage: '.element { border-inline: 1px solid #ccc; }',
          best_practices: [
            'Use logical border properties for directional layouts',
            'Combine with CSS custom properties for theming',
            'Use border-inline-start/end for asymmetric borders',
            'Consider border-inline-width for responsive borders'
          ],
          fallbacks: needsFallback ? [
            'Use border-left/right for older browsers',
            'Provide direction-specific border styles',
            'Use CSS feature queries for progressive enhancement'
          ] : [],
          example_code: `
    .sidebar {
      border-inline-end: 1px solid var(--border-color);
      /* Fallback */
      border-right: 1px solid #ccc;
    }
    
    @supports (border-inline-end: 1px solid black) {
      .sidebar {
        border-right: none;
      }
    }
    
    /* Responsive borders */
    @media (min-width: 768px) {
      .content {
        border-inline: 1px solid #e0e0e0;
      }
    }`
        },
        'overflow-inline': {
          basic_usage: '.element { overflow-inline: scroll; }',
          best_practices: [
            'Use overflow-inline for horizontal scrolling',
            'Combine with scroll-snap for better UX',
            'Use overflow-block for vertical scrolling',
            'Consider overflow-clip-margin for precise control'
          ],
          fallbacks: needsFallback ? [
            'Use overflow-x/y for older browsers',
            'Provide JavaScript fallbacks for complex scrolling',
            'Use CSS feature queries for progressive enhancement'
          ] : [],
          example_code: `
    .horizontal-scroll {
      overflow-inline: scroll;
      overflow-block: hidden;
      scroll-snap-type: inline mandatory;
      /* Fallback */
      overflow-x: scroll;
      overflow-y: hidden;
    }
    
    .item {
      scroll-snap-align: start;
      flex: 0 0 auto;
      width: 80vi;
    }`
        },
        'overflow-x': {
          basic_usage: '.carousel { overflow-x: scroll; scroll-snap-type: x mandatory; }',
          best_practices: [
            'Hide scrollbars for better UX: scrollbar-width: none;',
            'Use scroll-behavior: smooth for better UX',
            'Ensure keyboard accessibility',
            'Add touch-action: pan-x for mobile'
          ],
          fallbacks: needsFallback ? [
            'Use JavaScript for browsers without scroll-snap support',
            'Provide navigation arrows for non-touch devices',
            'Add swipe gesture support with touch events'
          ] : [],
          example_code: `
    <div class="carousel">
      <div class="carousel-item">Item 1</div>
      <div class="carousel-item">Item 2</div>
      <div class="carousel-item">Item 3</div>
    </div>
    
    <style>
    .carousel {
      display: flex;
      overflow-x: scroll;
      scroll-snap-type: x mandatory;
      scroll-behavior: smooth;
      -webkit-overflow-scrolling: touch;
      scrollbar-width: none;
      -ms-overflow-style: none;
    }
    
    .carousel::-webkit-scrollbar {
      display: none;
    }
    
    .carousel-item {
      flex: 0 0 100%;
      scroll-snap-align: start;
      scroll-snap-stop: always;
    }
    
    @media (max-width: 768px) {
      .carousel {
        scroll-snap-type: x proximity;
      }
    }
    </style>`
        },
        'scroll-snap-type': {
          basic_usage: '.container { scroll-snap-type: x mandatory; }',
          best_practices: [
            'Use "mandatory" for precise control, "proximity" for smoother scrolling',
            'Combine with scroll-snap-align on child elements',
            'Test on different devices and browsers',
            'Consider scroll-snap-stop for better control'
          ],
          fallbacks: needsFallback ? [
            'Polyfill for older browsers',
            'JavaScript-based snapping',
            'Touch event handling for mobile'
          ] : [],
          example_code: `
    .carousel {
      scroll-snap-type: x mandatory;
      overflow-x: scroll;
      display: flex;
    }
    
    .carousel-item {
      scroll-snap-align: center;
      scroll-snap-stop: always;
      flex: 0 0 auto;
      width: 100%;
    }
    
    /* Fallback for older browsers */
    @supports not (scroll-snap-type: x mandatory) {
      .carousel {
        /* JavaScript-based fallback */
      }
    }`
        },
        'display': {
          basic_usage: '.container { display: flex; }',
          best_practices: [
            'Use flex for one-dimensional layouts',
            'Use grid for two-dimensional layouts',
            'Consider browser support for newer display values',
            'Test with different content lengths'
          ],
          fallbacks: needsFallback ? [
            'Use float-based layouts for very old browsers',
            'Provide inline-block fallbacks',
            'Consider CSS Grid fallbacks'
          ] : [],
          example_code: `
    .carousel {
      display: flex;
      align-items: center;
      justify-content: flex-start;
      gap: 1rem;
    }
    
    .carousel-item {
      flex: 0 0 auto;
      min-width: 200px;
    }
    
    /* Fallback for older browsers */
    .no-flexbox .carousel {
      display: block;
      white-space: nowrap;
    }
    
    .no-flexbox .carousel-item {
      display: inline-block;
      vertical-align: top;
      white-space: normal;
    }`
        }
      };
      
      return guidance[cssProperty] || {
        basic_usage: `${cssProperty}: value;`,
        best_practices: ['Test across browsers', 'Consider accessibility', 'Optimize for performance'],
        fallbacks: needsFallback ? ['Provide JavaScript fallback', 'Use progressive enhancement'] : [],
        example_code: `
    .element {
      ${cssProperty}: value;
    }
    
    /* Add your specific implementation here */`
      };
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Luko248/css-first'

If you have feedback or need assistance with the MCP directory API, please join our Discord server