InnerBLOCKS打破FlexBox和CSS网格样式

时间:2021-06-17 作者:Cameron

当使用InnerBlocks以便嵌套父/子块时,最终会使用额外的HTML(在编辑器中)包装子元素,如下所示:

<div class="PARENT">
   <div class="block-editor-inner-blocks">
      <div class="block-editor-block-list__layout">
         <div class="block-editor-block-list__block wp-block is-selected">
            <div class="CHILD"></div>
         </div>
      </div>
   </div>
</div>
如果在父元素上使用flexbox或grid之类的东西,这会造成一点混乱,因为这意味着样式将应用于.block-editor-inner-blocks 相反

e、 g。

.PARENT {
   display: grid;
   grid-template-columns: repeat(3, minmax(0, 33%));
}
为了解决这个问题,我发现自己必须进行黑客重写或编写两组不同的CSS来处理额外的HTML,这些HTML在编辑器中包装块:

.PARENT,
.PARENT .block-editor-block-list__layout {
   display: grid;
   grid-template-columns: repeat(3, minmax(0, 33%));
}
.editor-styles-wrapper .PARENT {
   display: block; /* remove grid in editor */
}
有没有办法避免这种情况?或者在编辑器中查看时,您是否被两组CSS或覆盖所困扰?

1 个回复
最合适的回答,由SO网友:Tom J Nowell 整理而成

You can eliminate the wrapping containers abandoning InnerBlocks and instead using the useInnerBlocksProps hook which is how the blocks that come with core do it. This will allow your block markup to match the frontend without the editor wrapping things in additional tags.

If we look at the official buttons block:

import {
    BlockControls,
    useBlockProps,
    __experimentalUseInnerBlocksProps as useInnerBlocksProps,
    JustifyContentControl,
} from \'@wordpress/block-editor\';
...

function ButtonsEdit( {
    attributes: { contentJustification, orientation },
    setAttributes,
} ) {
    const blockProps = useBlockProps( {
        className: classnames( {
            [ `is-content-justification-${ contentJustification }` ]: contentJustification,
            \'is-vertical\': orientation === \'vertical\',
        } ),
    } );
    const innerBlocksProps = useInnerBlocksProps( blockProps, {
        allowedBlocks: ALLOWED_BLOCKS,
        template: BUTTONS_TEMPLATE,
        orientation,
        __experimentalLayout: LAYOUT,
        templateInsertUpdatesSelection: true,
    } );
...
    return (
        <>
...
            <div { ...innerBlocksProps } />
        </>
    );
}

https://github.com/WordPress/gutenberg/blob/trunk/packages/block-library/src/buttons/edit.js

The blocks edit component eliminates the tags that surround the buttons block using useBlockProps, then passes the result to useInnerBlocksProps to do the same for its children. It also passes the parameters that it would have given to the InnerBlocks component as a second parameter.

This way it has full control over the markup of the block while still giving the editor the opportunity to add event handlers and other things.

Not that to use this, you must declare you use the v2 API when registering the block. If you don\'t then useBlockProps won\'t work

"apiVersion": 2,

A more minimal example:

import {
    useBlockProps,
    __experimentalUseInnerBlocksProps as useInnerBlocksProps,
} from \'@wordpress/block-editor\';

const Edit = ( props ) => {
    const blockProps = useBlockProps( {} );
    const innerBlocksProps = useInnerBlocksProps( blockProps, {} );
    return <div { ...innerBlocksProps } />;
};

This also has the benefit of avoiding a common bug in block validation where the innerblocks component shares a tag with another element, and the whitespace generation causes validation to fail, which isn\'t possible here

相关推荐