<div class="subscribe-widget mb-1">
<?php
$form = ActiveForm::begin([
    'id' => 'form-subscribe-widget',
    'action' => ['site/subscribe'],
    'method' => 'post',
    'enableAjaxValidation' => true,
    'options' => [
        'class' => 'd-flex flex-column flex-sm-row align-items-start align-items-sm-center',
    ],
]);
?>

    <div class="flex-grow-1 me-0 me-sm-2 mb-2 mb-sm-0 w-100 w-sm-75 w-md-50">
        <?= $form->field($model, 'email', [
            'options' => ['class' => 'mb-0'],
            'template' => "{input}\n{error}",
            'errorOptions' => ['class' => 'text-danger', 'style' => 'font-size: small;'],
        ])->textInput([
            'class' => 'form-control square',
            'placeholder' => \Yii::t('app', 'Enter email'),
        ]) ?>
    </div>

    <div>
        <?= Html::submitButton(\Yii::t('app', 'subscribe'), [
            'class' => 'btn btn-primary square',
            'name' => 'subscribe-button',
        ]) ?>
    </div>

<?php ActiveForm::end(); ?>
</div>

I dont see why we can do the submit button at w-100 without adding extra css styles

Great question!

The short answer is: you can make the submit button w-100 on mobile by adding the Bootstrap class w-100 to it, but just adding w-100 to the button alone is often not enough if the button’s container does not allow it to grow.
Why can’t the button fill width on mobile without extra styles or wrappers?

    The form container has d-flex flex-column flex-sm-row, so on mobile (xs), the children stack vertically, which is good.

    However, the button's immediate container (the <div> wrapping the button) by default is a block element but its width depends on its content unless you specify otherwise.

    If the container's parent or itself does not stretch to full width, the button inside with w-100 will expand to the container’s width, which might be narrow if not full width.

What does just w-100 on <button> do?

    w-100 means width: 100% relative to its parent container.
    So the button fills the container horizontally.
    But if the container (like that <div>) only takes as much width as its content (i.e., the button), then the button won’t actually expand much.

How to fix it?

You want the container wrapping the button to:

    Be block-level with width: 100% on mobile (to have full width)
    Shrink to content width when horizontal on sm+ (optional)

Common Bootstrap patterns:

    Wrap the button in a container div with these classes (on the container):

<div class="d-grid d-sm-block">
    <button class="btn btn-primary w-100 w-sm-auto">Subscribe</button>
</div>

    d-grid: On mobile, forces container to full width and acts like a grid container, making the button inside fill the width.
    d-sm-block: On sm+ screens, container behaves like normal block, allowing the button to shrink to its content width.
    Button classes:
        w-100 on mobile → full width
        w-sm-auto on sm+ → width auto (fitting content)

Without this container, adding only w-100 on the button often results in:

    Button width constrained by its direct parent (<div>)
    Which might not be full width by default

Hence the button looks "small" even with w-100.
Why your current markup buttons are not full width on mobile:

<div>
    <button class="btn btn-primary square">Subscribe</button>
</div>

    The outer <div> has no width constraints — it shrinks to fit content.
    The button’s w-100 will fill this narrow container — almost looks like auto width.

Simple fix:

Add d-grid w-100 d-sm-block to the wrapping div:

<div class="d-grid w-100 d-sm-block">
    <?= Html::submitButton(\Yii::t('app', 'subscribe'), [
        'class' => 'btn btn-primary square w-100 w-sm-auto',
        'name' => 'subscribe-button',
    ]) ?>
</div>

Summary

    Bootstrap button w-100 fills its container width
    The container needs to have full width on mobile (d-grid w-100) to let the button grow
    The wrapper div pattern (d-grid d-sm-block) is a Bootstrap recommended approach for responsive buttons full width on mobiles and auto width on desktops
    Without the wrapper div, the container often shrinks and prevents the button from filling width

If your current HTML markup uses just a plain div without extra classes, your button won’t be full width on mobile just by adding w-100 — you need to make sure the container’s width is full as well. That's the missing piece.

Let me know if you want me to help update your code with this fix!

ok can do you do this?