Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
370 views
in Technique[技术] by (71.8m points)

javascript - 看看我关于具有实体和状态的新一代CSS预处理器的想法。 你怎么看? [关闭](Check out my idea for a new generation CSS preprocessor with entities and states. What do you think? [closed])

I think creating responsive CSS using current technology is very inconvenient.

(我认为使用当前技术创建响应式CSS非常不便。)

I came up with the idea of ??a CSS preprocessor with entities (they are called "Features") and states for these entities.

(我想到了一个带有实体的CSS预处理器(它们称为``功能'')和这些实体的状态的想法。)

I called this CSS preprocessor "Features CSS."

(我将此CSS预处理器称为“功能CSS”。)

See how convenient it is to create responsive CSS using "Features CSS":

(看看使用“功能CSS”创建响应式CSS有多么方便:)

"Features CSS" description(“功能CSS”说明)

For example, we need to create a toggleable sidebar.

(例如,我们需要创建一个可切换的侧边栏。)

See how “Features CSS” allows you to conveniently create the CSS:

(请参阅“功能CSS”如何方便地创建CSS:)

  //=======================================
  // $app-feature: This is global app feature
  //=======================================

  $app-feature: @feature(
    parent: null,
    states: (

      //
      // This window width states can be used as app global responsive breakpoints (as in Bootstrap).
      // You can also add other parallel group of window width states.
      // You can also add other parallel group of window width states from any other feature and
      // register this group of states in this feature.
      // States in any feature can be published in any other feature.
      // You can access feature states from any other feature.
      //

      extra-small: 500px,   // window width in range [0; 500px]
      small: 767px,         // window width in range [501px, 767px]
      medium: 1024px,       // window width in range [768px, 1024px]
      large: 1200px,        // window width in range [1025px, 1200px]

      // Last element must be null (i.e. max-width is infinity)
      extra-large: null,    // window width in range [1201px, Infinity)
    ),

    // "states" this is shortcut for "states-ex.win-width".
    // "states-ex.win-width" this is states based on window width.
    // Instead of "states" you can write:
    //   states-ex: {
    //     win-width: (
    //       ...
    //     ),
    //   }
  );

  //=======================================
  // $side-menu-feature: This is side menu feature
  //=======================================

  $side-menu-feature: @feature(
    parent: $app-feature,
    states-ex: (

      //
      // "win-width" is system states group based on window width
      //

      win-width: (
        toggleable: $app-feature{medium} (    // i.e. {extra-small}, {small} and {medium}
          vars: (
            side-width: 80%,
          ),
        ),

        fixed-small: $app-feature{large} (    // i.e. {large}
          vars: (
            side-width: 300px,
          ),
        ),

        // Last breakpoint must be null (i.e. max-width is infinity)
        // You can write also:
        //   fixed-large: $app-feature{extra-large}
        // because $app-feature{extra-large} also is last breakpoint and therefore it also equals to null
        fixed-large: null (    // i.e. {extra-large}
          vars: (
            side-width: 400px,
          ),
        ),
      ),

      //
      // Create custom state group #opening
      // Name of custom states group must starts with #
      //

      #opening: @selector-state( // States
        opened: body.side-menu--opened,

        closed: body:not(.side-menu--opened),
      ) ( // Options
        // Publish this state in $app-feature
        publish: $app-feature{#side-menu-opening},
            // And now you can access this state from $app-feature in your any CSS file:
            //   @state $app-feature{#side-menu-opening.opened} {
            //     .my-item {
            //       font-weight: bold;
            //     }
            //   }
      ),

    ),
  ) {
    .side-menu {
      background-color: #fff;
    }

    .side-menu-overlay {
      position: relative;
      opacity: 0.5;
      color: #444;
    }

    // Same as: @state win-width.toggleable
    @state .toggleable {
      @state #opening.opened {
        .side-menu {
          width: @var [side-width];
            // Same as: @var win-width[side-width]
            // It takes "width" variable from current win-width state (win-width.toggleable)
            // You can take variable from other current state: @var #opening[my-var]
            // Or from other not current but explicit state: @var #opening.closed[my-var]
        }

        .side-menu-overlay {
          z-index: 100;
        }

        .main-content {
          margin-left: @var [side-width];
          width: 100%;
        }
      }

      @state #opening.closed {
        .side-menu,
        .side-menu-overlay {
          display: none;
        }

        .side-menu-overlay {
          z-index: -100;
        }
      }
    }

    // Same as: @state @up win-width.small
    // Same as: @state win-width(fixed-small, fixed-large)
    // Same as: @state .(fixed-small, fixed-large)
    @state @up .fixed-small {
      .side-menu {
        position: fixed;
        left: 0;
        width: @var [side-width]; // side-width equals to 300px for fixed-small and 400px for fixed-large
        top: 0;
        bottom: 0;
      }

      .main-content {
        margin-left: @var [side-width];
        width: calc(100% - @var [side-width]);
      }
    }
  }

  //=======================================
  // $side-menu-item-feature
  //=======================================

  $side-menu-item-feature: @feature(
    parent: $side-menu-feature,
    states: (
      toggleable: @parent{toggleable} => item-large,
      fixed-small: @parent{fixed-small} => item-small,
      fixed-large: @parent{fixed-large} => item-large,
        // You can use readble state names "item-small" or "item-large" instead of unreadble
        // global app states $app-feature{extra-small}, $app-feature{small}.
        // $app-feature{...} states unreadble in context of side-menu-item
        // because $app-feature{...} states based on the browser width
        // and therefore $app-feature{...} state names semantic based on browser width
        // and therefore $app-feature{...} state names is unreadble in context of side-menu-item

      //
      // or
      //

      // If toggleable side-menu has width in percentage of screen
      // and therefore side-menu width is proportional to the browser window width
      // then we can do the following:
      toggleable-small: @parent{{toggleable, 720px}} => item-small,
        // @parent{{toggleable, 720px}} takes 720px and ensures
        // that 720px is in "toggleable" window width range.
        // Otherwise compilation error occured.
      toggleable-large: @parent{toggleable} => item-large,
        // or:
        //   toggleable-small: @parent{{toggleable, 70%}} => item-small,
        //   toggleable-large: @parent{toggleable} => item-large,
        //
        // @parent{toggleable} (@side-menu-feature{toggleable}) has such rule:
        //   browser-width in range [0px, 1024px]
        //
        // Since the width of the side-menu is proportional to the width of the browser window,
        // we know that for small browser widths the menu is narrow (therefore menu item is small),
        // and for large browser widths the menu is wide (therefore menu item is large).
        //
        // But also we can implement "side-menu-item" state depends not from browser width value,
        // but depends from "side-menu-item" element width value using "Features CSS JS Ext"
        //

      fixed-small: @parent{fixed-small} => item-small,
      fixed-large: @parent{fixed-large} => item-large,
    ),
  ) {
    // This causes compilation error.
    // Use {item-small} or {item-large} states.
    @state .toggleable {}

    // This is works
    @state .item-small {
    }
    @state .item-large {
    }
  }

  //=======================================
  // $side-menu-item-sub-element-feature
  //=======================================

  $side-menu-item-sub-element-feature: @feature(
    parent: $side-menu-item-feature,
    states: @parent.states,
  ) {
    @state .item-small {
      ...
    }

    @state .item-large {
      ...
    }
  }

Additional examples for "Features CSS"(“功能CSS”的其他示例)

  //=======================================
  // Applying of feature
  //=======================================

  $my-feature: @feature(
    parent: null,
    states: (
      small: 1024px,
      large: null,
    ),
  ) {
    // Same as: @state @up win-width.small
    @state @up .small {
      .test-class { font-weight: bold; }
    }
  }

  // You can also apply feature in any your CSS file

  @apply $my-feature {
    @state @up .small {
      .test-class { font-weight: bold; }
    }
  }

  // Or use $my-feature states explicitly

  // Same as: @state @up $my-feature{win-width.small} {
  @state @up $my-feature{.small} {
    .test-class { font-weight: bold; }
  }

  //=======================================
  // Parallel states example
  //=======================================

  $my-feature: @feature(
    parent: null,
    states-ex: (
      win-width: (
        small: 1024px,
        large: null,
      ),

      //
      // Custom state based on window width
      //

      #right-bar: @win-width-state(
        hide-right-bar: 1200px,
        show-right-bar: null,
      )

      // Both "win-width" and "#right-bar" states based on window width.
 

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...