Why to use [attributes] when adding class to a button inside my hook function I request somebody to please explain why I have to use ['#attributes'] when adding one or a combination of CSS class-es to the Submit button inside a search-block-form but when changing just the Text, ['#attributes'] is not required?

To change default text of the button I am writing:

function ezone_form_search_block_form_alter($&amp;form, &amp;$form_state, $form_id){
    $form['actions']['submit']['#value'] = t('Search now');
}


But when adding a CSS class to the same button I have to write this:

function ezone_form_search_block_form_alter(&amp;$form, &amp;$form_state, $form_id){
    $form['actions']['submit']['#attributes']['class'][] = 'btn btn-primary';
}


Why although value and class both are attributes of a button element, I have to do them differently? If I take out the ['#attributes'] part ($form['actions']['submit']['#class'][] = 'btn btn-primary';) button classes don't not render.

I Googled but could not find anything specific about it! It would be great if someone can put lights on this. I am a new comer at Drupal platform!
This more a theoretical question. You can see in the documentation or example code how to use the render element.

The technical background is, that each render element defines variables which you can use when building the render array. The variables of a render element are placed on the top level of the render array and prefixed with '#'.

This is an excerpt of the code which prepares the render element for rendering:

  public static function preRenderButton($element) {
    $element['#attributes']['type'] = 'submit';
    Element::setAttributes($element, array('id', 'name', 'value'));


Here you can see that #id, #name and #value are placed in the attributes by the element itself.

If you want to set other attributes, you have to place them yourself in #attibutes.