en	Declarations in BEM

en	To list BEM entities needed to build a web page (effectively, ”an instance of a bundle../build/build.en.md#bundle“), you can use a declaration.

en	A declaration is a list of blocks../key-concepts/key-concepts.en.md#block, elements../key-concepts/key-concepts.en.md#element, and modifiers../key-concepts/key-concepts.en.md#modifier that are used on a page..

en	A build tool uses declaration data to narrow down a list of entities that end up in the final project.

en	Rather than include all the blocks of the project, you can pick only the necessary ones from the list.

en	The goal of a declaration is to define what and in what order should be included in the build.

en	In the BEM platform, a page description is created in BEMJSON format, and a page declaration is described in BEMDECL format, e.g.:

en	Ways of obtaining a declaration

en	You can form a declaration manually.

en	To do this, list all the BEM entities involved in the creation of the page.

en	A declaration can be built automatically:

en	From the page description#creating-a-declaration-from-the-page-description

en	Via an introspection of the file system#creating-a-declaration-via-an-introspection-of-the-file-system

en	Creating a declaration from the page description

en	A list of the entities to include in the build can be obtained using classes from the HTML file of the web page.

en	In a BEM project, the structure of a web page is described by means of a BEM tree../key-concepts/key-concepts.en.md#bem-tree..

en	The HTML code of a page contains classes with the names of all the blocks, elements, and modifiers used on the page.

en	The BEM tree can be built automatically from the HTML classes or created manually.

en	When the page get built, the declaration is formed automatically based on the BEM tree data:

en	All entities (blocks, elements, and modifiers) are included in the declaration in the order specified in the build configuration.

en	If the same entity is used twice on a page, it only occurs once in the declaration.

en	The nesting of blocks and elements is not shown in the declaration.

en	html2bemjsonhttps://github.com/bem-incubator/html2bemjson is one of the tools that builds a BEM tree out of the HTML structure of a page.

en	A way of creating a declarationdeclarations__html2decl.en.png

en	For an example of a project where a separate declaration is formed for each individual page, see Starting your own BEM projecthttps://en.bem.info/tutorials/start-with-project-stub/.

en	Creating a declaration via an introspection of the file system

en	Another source of information about the entities is the project file system.

en	The declaration will thus encompass all entities that are found in the file system of the project.

en	Although it ensures a guaranteed inclusion of all the necessary entities in the build, this method is lacking in precision: the build will cover all of the existing entities, not just the relevant ones.

en	On the contrary, the page description-based declaration ensures the building of the relevant BEM entities on a per-entity basis, but does not guarantee inclusion of all those entities that are not explicitly specified in the HTML file for the page.

en	A way of creating a declarationdeclarations__fs2decl.en.png

en	In bem-componentshttps://en.bem.info/libs/bem-components/, the method of creating a declaration via the introspection of a file system is used for the Disthttps://en.bem.info/libs/bem-components/-based library distribution.

en	Algebra of declarations

en	Declarations can help you manage the build process.

en	For instance, you can combine different page declarations into one and build the entire project at once instead of page by page.

en	In addition to combining declarations, you can reuse them, extract their common and different parts.

en	This kind of control enables you to assemble all pages into one bundle../build/build.en.md#bundle, load the necessary parts of a page on request or reuse already built common components on different pages.

en	Operations with declarations

en	Addition#adding-declarations — uniting sets of entities from different declarations into one.

en	Subtraction#subtracting-declarations — getting the difference between sets of entities from different declarations.

en	Intersection#intersecting-declarations — obtaining a declaration from the intersection of sets of entities from two other declarations.

en	Adding declarations

en	Used for creating common technology files (e.g., a common CSS and JavaScript file) for multiple pages.

en	Use it if you need to load all pages at once and save time loading each individual page when switching between the pages.

en	Declaration 1 Declaration 2 Declaration 3 [ [ [ 'header', 'header', 'header', 'input', 'input', 'input', 'button', 'button', 'button', 'link', 'link', 'attach', + = 'attach', 'menu', 'menu', 'image', 'image', 'checkbox', 'checkbox', 'popup' 'popup', 'textarea' 'textarea' ] ] ]

en	Subtracting declarations

en	One of the ways to use it is for building a page part that is loaded on request (e.g., in response to a user action).

en	Declaration 1 Declaration 2 Declaration 3 [ [ [ 'button', 'button', 'checkbox', 'checkbox', 'textarea', 'textarea', 'suggest' 'suggest' 'header', - 'input', = 'menu', 'image', 'popup' ] ] ]

en	Let's say you have a page that uses a virtual keyboard that is only made available to the user in response to a certain action.

en	Adding that block to the build for the entire page will only increase load time.

en	The keys of the keyboard may already be implemented on the page for different purposes.

en	The ability to subtract declarations allows you to create a separate bundle (files for a part of the page) for the missing implementation of the virtual keyboard and only connect it on request.

en	Intersecting declarations

en	Used for creating a declaration that describes common parts of different project pages.

en	This lets you build a common part for all the pages and connect it once to all the pages during the build process.

en	Declaration 1 Declaration 2 Declaration 3 [ [ [ 'header', 'header', 'header', 'input', 'menu', 'link', + 'button', = 'attach', 'input', 'checkbox', 'image', 'textarea', 'popup', 'footer' 'footer' 'footer' ] ] ]

en	For example, such a separation can be effective if every page of the project features a header and a footer.

en	The common part of the pages is described in a separate declaration.

en	During the build process each page is then built on the basis of two declarations: the common one (containing the header and the footer) and its own (describing the remaining part of the page).