diff --git a/core/lib/Drupal/Core/Render/Element/FormElement.php b/core/lib/Drupal/Core/Render/Element/FormElement.php
index 173a55cb93f54906e2076a2cf29a9f32a5d4756a..6dd653b25a697ad6aa1259413f44a4934ba80c69 100644
--- a/core/lib/Drupal/Core/Render/Element/FormElement.php
+++ b/core/lib/Drupal/Core/Render/Element/FormElement.php
@@ -14,6 +14,72 @@
 /**
  * Provides a base class for form element plugins.
  *
+ * Form elements are a subset of render elements, representing elements for
+ * HTML forms, which can be referenced in form arrays. See the
+ * @link theme_render Render API topic @endlink for an overview of render
+ * arrays and render elements, and the @link form_api Form API topic @endlink
+ * for an overview of forms and form arrays.
+ *
+ * The elements of form arrays are divided up into properties (whose keys
+ * start with #) and children (whose keys do not start with #). The properties
+ * provide data or settings that are used in rendering and form processing.
+ * Some properties are specific to a particular type of form/render element,
+ * some are available for any render element, and some are available for any
+ * form input element. A list of the properties that are available for all form
+ * elements follows; see \Drupal\Core\Render\Element\RenderElement for some
+ * additional information, as well as a list of properties that are common to
+ * all render elements (including form elements). Properties specific to a
+ * particular element are documented on that element's class.
+
+ * Here is a list of properties that are used during the rendering and
+ * form processing of form elements:
+ * - #after_build: (array) Array of callables or function names, which are
+ *   called after the element is built. Arguments: $element, $form_state.
+ * - #ajax: (array) Array of elements to specify Ajax behavior. See
+ *   the @link ajax Ajax API topic @endlink for more information.
+ * - #array_parents: (string[], read-only) Array of names of all the element's
+ *   parents (including itself) in the render array. See also #parents, #tree.
+ * - #default_value: Default value for the element. See also #value.
+ * - #description: (string) Help or description text for the element. In an
+ *   ideal user interface, the #title should be enough to describe the element,
+ *   so most elements should not have a description; if you do need one, make
+ *   sure it is translated. If it is not already wrapped in a safe markup
+ *   object, it will be filtered for XSS safety.
+ * - #disabled: (bool) If TRUE, the element is shown but does not accept
+ *   user input.
+ * - #element_validate: (array) Array of callables or function names, which
+ *   are called to validate the input. Arguments: $element, $form_state, $form.
+ * - #field_prefix: (string) Prefix to display before the HTML input element.
+ *   Should be translated, normally. If it is not already wrapped in a safe
+ *   markup object, will be filtered for XSS safety.
+ * - #field_suffix: (string) Suffix to display after the HTML input element.
+ *   Should be translated, normally. If it is not already wrapped in a safe
+ *   markup object, will be filtered for XSS safety.
+ * - #input: (bool, internal) Whether or not the element accepts input.
+ * - #parents: (string[], read-only) Array of names of the element's parents
+ *   for purposes of getting values out of $form_state. See also
+ *   #array_parents, #tree.
+ * - #process: (array) Array of callables or function names, which are
+ *   called during form building. Arguments: $element, $form_state, $form.
+ * - #processed: (bool, internal) Set to TRUE when the element is processed.
+ * - #required: (bool) Whether or not input is required on the element.
+ * - #states: (array) Information about JavaScript states, such as when to
+ *   hide or show the element based on input on other elements.
+ *   See drupal_process_states() for documentation.
+ * - #title: (string) Title of the form element. Should be translated.
+ * - #title_display: (string) Where and how to display the #title. Possible
+ *   values:
+ *   - before: Label goes before the element (default for most elements).
+ *   - after: Label goes after the element (default for radio elements).
+ *   - invisible: Label is there but is made invisible using CSS.
+ *   - attribute: Make it the title attribute (hover tooltip).
+ * - #tree: (bool) TRUE if the values of this element and its children should
+ *   be hierarchical in $form_state; FALSE if the values should be flat.
+ *   See also #parents, #array_parents.
+ * - #value_callback: (callable) Callable or function name, which is called
+ *   to transform the raw user input to the element's value. Arguments:
+ *   $element, $input, $form_state.
+ *
  * @see \Drupal\Core\Render\Annotation\FormElement
  * @see \Drupal\Core\Render\Element\FormElementInterface
  * @see \Drupal\Core\Render\ElementInfoManager
diff --git a/core/lib/Drupal/Core/Render/Element/RenderElement.php b/core/lib/Drupal/Core/Render/Element/RenderElement.php
index 3a63f91559adbb594d142de65741e7aa60665858..47c84024c696e0e4685485ec94b6492c055cce08 100644
--- a/core/lib/Drupal/Core/Render/Element/RenderElement.php
+++ b/core/lib/Drupal/Core/Render/Element/RenderElement.php
@@ -17,6 +17,108 @@
 /**
  * Provides a base class for render element plugins.
  *
+ * Render elements are referenced in render arrays; see the
+ * @link theme_render Render API topic @endlink for an overview of render
+ * arrays and render elements.
+ *
+ * The elements of render arrays are divided up into properties (whose keys
+ * start with #) and children (whose keys do not start with #). The properties
+ * provide data or settings that are used in rendering. Some properties are
+ * specific to a particular type of render element, some are available for any
+ * render element, and some are available for any form input element. A list of
+ * the properties that are available for all render elements follows; the
+ * properties that are for all form elements are documented on
+ * \Drupal\Core\Render\Element\FormElement, and properties specific to a
+ * particular element are documented on that element's class. See the
+ * @link theme_render Render API topic @endlink for a list of the most
+ * commonly-used properties.
+ *
+ * Many of the properties are strings that are displayed to users. These
+ * strings, if they are literals provided by your module, should be
+ * internationalized and translated; see the
+ * @link i18n Internationalization topic @endlink for more information. Note
+ * that although in the properies list that follows, they are designated to be
+ * of type string, they would generally end up being
+ * \Drupal\Core\StringTranslation\TranslatableMarkup objects instead.
+ *
+ * Here is the list of the properties used during the rendering of all render
+ * elements:
+ * - #access: (bool) Whether the element is accessible or not. When FALSE,
+ *   the element is not rendered and user-submitted values are not taken
+ *   into consideration.
+ * - #access_callback: A callable or function name to call to check access.
+ *   Argument: element.
+ * - #allowed_tags: (array) Array of allowed HTML tags for XSS filtering of
+ *   #markup, #prefix, #suffix, etc.
+ * - #attached: (array) Array of attachments associated with the element.
+ *   See the "Attaching libraries in render arrays" section of the
+ *   @link theme_render Render API topic @endlink for an overview, and
+ *   \Drupal\Core\Render\AttachmentsResponseProcessorInterface::processAttachments
+ *   for a list of what this can contain. Besides this list, it may also contain
+ *   a 'placeholders' element; see the Placeholders section of the
+ *   @link theme_render Render API topic @endlink for an overview.
+ * - #attributes: (array) HTML attributes for the element. The first-level
+ *   keys are the attribute names, such as 'class', and the attributes are
+ *   usually given as an array of string values to apply to that attribute
+ *   (the rendering system will concatenate them together into a string in
+ *   the HTML output).
+ * - #cache: (array) Cache information. See the Caching section of the
+ *   @link theme_render Render API topic @endlink for more information.
+ * - #children: (array, internal) Array of child elements of this element.
+ *   Set and used during the rendering process.
+ * - #create_placeholder: (bool) TRUE if the element has placeholders that
+ *   are generated by #lazy_builder callbacks. Set internally during rendering
+ *   in some cases. See also #attached.
+ * - #defaults_loaded: (bool) Set to TRUE during rendering when the defaults
+ *   for the element #type have been added to the element.
+ * - #id: (string) The HTML ID on the element. This is automatically set for
+ *   form elements, but not for all render elements; you can override the
+ *   default value or add an ID by setting this property.
+ * - #lazy_builder: (array) Array whose first element is a lazy building
+ *   callback (callable), and whose second is an array of scalar arguments to
+ *   the callback. To use lazy building, the element array must be very
+ *   simple: no properties except #lazy_builder, #cache, #weight, and
+ *   #create_placeholder, and no children. A lazy builder callback typically
+ *   generates #markup and/or placeholders; see the Placeholders section of the
+ *   @link theme_render Render API topic @endlink for information about
+ *   placeholders.
+ * - #markup: (string) During rendering, this will be set to the HTML markup
+ *   output. It can also be set on input, as a fallback if there is no
+ *   theming for the element. This will be filtered for XSS problems during
+ *   rendering; see also #plain_text and #allowed_tags.
+ * - #plain_text: (string) Elements can set this instead of #markup. All HTML
+ *   tags will be escaped in this text, and if both #plain_text and #markup
+ *   are provided, #plain_text is used.
+ * - #post_render: (array) Array of callables or function names, which are
+ *   called after the element is rendered. Arguments: rendered element string,
+ *   children.
+ * - #pre_render: (array) Array of callables or function names, which are
+ *   called just before the element is rendered. Argument: $element.
+ *   Return value: an altered $element.
+ * - #prefix: (string) Text to render before the entire element output. See
+ *   also #suffix. If it is not already wrapped in a safe markup object, will
+ *   be filtered for XSS safety.
+ * - #printed: (bool, internal) Set to TRUE when an element and its children
+ *   have been rendered.
+ * - #render_children: (bool, internal) Set to FALSE by the rendering process
+ *   if the #theme call should be bypassed (normally, the theme is used to
+ *   render the children). Set to TRUE by the rendering process if the children
+ *   should be rendered by rendering each one separately and concatenating.
+ * - #suffix: (string) Text to render after the entire element output. See
+ *   also #prefix. If it is not already wrapped in a safe markup object, will
+ *   be filtered for XSS safety.
+ * - #theme: (string) Name of the theme hook to use to render the element.
+ *   A default is generally set for elements; users of the element can
+ *   override this (typically by adding __suggestion suffixes).
+ * - #theme_wrappers: (array) Array of theme hooks, which are invoked
+ *   after the element and children are rendered, and before #post_render
+ *   functions.
+ * - #type: (string) The machine name of the type of render/form element.
+ * - #weight: (float) The sort order for rendering, with lower numbers coming
+ *   before higher numbers. Default if not provided is zero; elements with
+ *   the same weight are rendered in the order they appear in the render
+ *   array.
+ *
  * @see \Drupal\Core\Render\Annotation\RenderElement
  * @see \Drupal\Core\Render\ElementInterface
  * @see \Drupal\Core\Render\ElementInfoManager
diff --git a/core/lib/Drupal/Core/Render/theme.api.php b/core/lib/Drupal/Core/Render/theme.api.php
index bf95672290f063991aafb7a49ceea296998107c7..aff8ab5f2a904bb17d4cd90ea3328f96114aeea1 100644
--- a/core/lib/Drupal/Core/Render/theme.api.php
+++ b/core/lib/Drupal/Core/Render/theme.api.php
@@ -404,7 +404,29 @@
  * See \Drupal\Core\Asset\LibraryDiscoveryParser::parseLibraryInfo() for more
  * information on how to define libraries.
  *
- * @section render_pipeline The Render Pipeline
+ * @section sec_placeholders Placeholders in render arrays
+ * Render arrays have a placeholder mechanism, which can be used to add data
+ * into the render array late in the rendering process. This works in a similar
+ * manner to \Drupal\Component\Render\FormattableMarkup::placeholderFormat(),
+ * with the text that ends up in the #markup property of the element at the
+ * end of the rendering process getting substitutions from placeholders that
+ * are stored in the 'placeholders' element of the #attached property.
+ *
+ * For example, after the rest of the rendering process was done, if your
+ * render array contained:
+ * @code
+ * $build['my_element'] = [
+ *   '#attached' => ['placeholders' => ['@foo' => 'replacement']],
+ *   '#markup' => ['Something about @foo'],
+ * ];
+ * @endcode
+ * then #markup would end up containing 'Something about replacement'.
+ *
+ * Note that each placeholder value can itself be a render array, which will be
+ * rendered, and any cache tags generated during rendering will be added to the
+ * cache tags for the markup.
+ *
+ * @section render_pipeline The render pipeline
  * The term "render pipeline" refers to the process Drupal uses to take
  * information provided by modules and render it into a response. For more
  * details on this process, see https://www.drupal.org/developing/api/8/render;