Skip to content

Instantly share code, notes, and snippets.

@elliottmangham
Last active February 21, 2025 14:13
Show Gist options
  • Save elliottmangham/a3ebedbe8c9ad6444811a23e6cfd7a1a to your computer and use it in GitHub Desktop.
Save elliottmangham/a3ebedbe8c9ad6444811a23e6cfd7a1a to your computer and use it in GitHub Desktop.
WordPress Block Development - Rules for AI

When writing PHP code for WordPress blocks:

  1. Start with standard block header comment and settings:

    • Use /** Block: Name */ format
    • Define any required settings ($js, etc.) at the top
  2. Follow a top-down logic flow:

    • Process all data/logic at the top of the file
    • Build HTML string variables progressively
    • Use heredoc syntax for final HTML assembly
    • Echo the final HTML at the bottom
    • Never include logic operations, functions, or method calls within heredoc syntax
    • Process all variables and concatenations before the heredoc
    • Heredoc should only contain simple variable insertions with curly braces
  3. Use consistent helper functions:

    • safe_field() for checking array values
    • create_tag() for HTML element creation
    • get_responsive_text() for responsive typography
    • tag() for tag name validation
    • create_button() for button elements
    • add_block_padding() for padding attributes
    • Modules\Elements::get() for media handling:
      $media = Modules\Elements::get(
          'media',
          array(
              'acf'      => $media_array,
              'classes'  => array('media_class'),
              'settings' => array(
                  'media_class' => 'media_element',
                  'lazyload'    => true,
                  'image_sizes' => array(
                      'landscape' => 'large',
                      'portrait'  => 'medium_large',
                  ),
              ),
          ),
          true
      );
      This handles:
      • Image and video types
      • Lazy loading
      • Responsive image sizes
      • Media overlays
      • Consistent class naming
  4. Handle text content:

    • Use wp_kses_post() on individual text inputs
    • Remove paragraph tags with preg_replace when needed
    • Process headings with proper font sizing and responsive text
    • Use utility classes for typography (u-wysiwyg-text--)
  5. Structure HTML with BEM-style classes:

    • Use component prefix (c_) for main wrappers
    • Use block-specific prefixes for elements (row_, media_)
    • Add utility classes (u-container, u-wysiwyg-text)
    • Use modifiers with hyphen prefix (-bg-color--)
  6. Media handling:

    • Support both image and video types
    • Use wp_get_attachment_image() for images
    • Include proper video attributes and classes
    • Handle media overlays with color and blend modes
  7. Container structure:

    • Wrap content in c_inner
    • Use utility classes for containers
    • Include proper padding and width modifiers
  8. Background and padding:

    • Process background colors into both style and class
    • Handle responsive padding through helper function
    • Apply to main block attributes
  9. Variable building:

    • Initialize empty strings for major components
    • Build conditionally based on available data
    • Use meaningful variable names (_heading, _text, _button)
  10. Final assembly:

    • Use heredoc syntax (<<<HTML) for main template
    • Keep HTML indentation clean and consistent
    • Include all dynamic variables with curly braces
    • Echo without additional escaping if content is pre-escaped

When writing CSS for WordPress blocks:

  1. File Structure:

    • Name files as block-name.css
    • Start with component wrapper: .c-block-name[data-cid]
    • Use container queries over media queries where possible
    • Group related styles using PostCSS nesting
  2. Class Naming Convention:

    • Component prefix: c- (e.g., c-accordions)
    • Element prefix: component_ (e.g., accordions_accord)
    • Modifier prefix: - (e.g., -bg-color--1)
    • State classes: is- (e.g., is-open)
    • Utility classes: u- (e.g., u-container)
    • JavaScript hooks: js- (e.g., js-accord)
  3. Property Organization:

    • Order properties alphabetically
    • Group related properties using PostCSS Short syntax:
      .element {
        position: absolute 10px 10px * *;
        size: 44px;
      }
  4. Units and Values:

    • Use pixel units (px) for all measurements
    • Never use rem or em units directly
    • For typography, use the responsive syntax:
      .element {
        font-size: responsive 16px 24px / 1.5;  /* min max / line-height */
      }
  5. Nesting Structure:

    • Maximum nesting depth of 3 levels
    • Avoid using the & operator for nesting
    • Structure example:
      .c-block[data-cid] {
        .block_element {
          .element_child {
            property: value;
          }
        }
      }
  6. Custom Properties:

    • Define block-specific variables at component root
    • Use semantic naming: --component-property
    • Reference global theme variables when needed
    .c-block[data-cid] {
      --background-color: var(--color--3);
      --text-color: var(--color--1);
    }
  7. Container Queries:

    @container (min-width: 1025px) {
      .block_element {
        property: value;
      }
    }
  8. State Management:

    .block_element {
      &.is-open {
        property: value;
      }
    }
  9. PostCSS Features Usage:

    • Use size: for width/height
    • Use position: with directional values
    • Use fluid-range: and fluid-unit: for custom responsive values
    • Leverage @extend for shared styles
    • Use @for loops for generating repetitive classes
  10. Common Patterns:

    • Wrap content in c_inner
    • Use utility classes for containers (u-container)
    • Include proper padding modifiers
    • Handle background colors with both style and class
    • Use BEM-style class hierarchy
  11. Media Query Usage:

    • Use standard media query values
    • Prefer container queries where possible
    • Available breakpoints:
    /* Larger than (min-width) */
    @media (min-width: 481px) { } /* xs+ */
    @media (min-width: 641px) { } /* sm+ */
    @media (min-width: 769px) { } /* md+ */
    @media (min-width: 1025px) { } /* lg+ */
    @media (min-width: 1281px) { } /* xl+ */
    @media (min-width: 1537px) { } /* 2xl+ */
    @media (min-width: 1681px) { } /* 3xl+ */
    
    /* Smaller than (max-width) */
    @media (max-width: 480px) { } /* -xs */
    @media (max-width: 640px) { } /* -sm */
    @media (max-width: 768px) { } /* -md */
    @media (max-width: 1024px) { } /* -lg */
    @media (max-width: 1280px) { } /* -xl */
    @media (max-width: 1536px) { } /* -2xl */
    @media (max-width: 1680px) { } /* -3xl */
    
    /* Between ranges */
    @media (min-width: 481px) and (max-width: 640px) { } /* xs-sm */
    @media (min-width: 641px) and (max-width: 768px) { } /* sm-md */
    @media (min-width: 769px) and (max-width: 1024px) { } /* md-lg */
    /* ... additional ranges available */
    
    /* States */
    @media (hover: hover) { }

    Example usage:

    .block_element {
      display: none;
    
      @media (min-width: 769px) {
        display: block;
      }
    
      @media (hover: hover) {
        &:hover {
          opacity: 0.8;
        }
      }
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment