Show WordPress users in grid with image and name

The first thing you have to do is create the shortcode you need:

function wpusers_shortcode( $atts ) {
    // Attributes
    $atts = shortcode_atts(
        array(
            'group' => 'logistics',
        ),
        $atts
    );
    // code here
}
add_shortcode( 'wpusers', 'wpusers_shortcode' );

Now you have a self-closing shortcode. Now it’s time to consult the database to get all registered users:

$args = array(
    'role'           => 'Subscriber',
    'order'          => 'ASC',
    'orderby'        => 'id',
    'fields'         => 'all_with_meta',
);

// The User Query
$users = new WP_User_Query( $args );

// The User Loop
if ( ! empty( $users->results ) ) {
    foreach ( $users->results as $user ) {
        // do something
    }
} else {
    // no users found
}

With this code you can get all users of type “Subscriber” that are registered. You can change the type of user (role) by the following: “Super Admin”, “Administrator”, “Editor”, “Author”, “Contributor”, “Subscriber” or even your own custom role: “teachers”.

Assuming you are using Bootstrap, the following structure is enough to make the column:

<div class="container">
   <div class="row users">
       <div class="col-xs-12 col-sm-4 col-md-3 user">
           <div class="user-photo">
               <img src="https://wordpress.stackexchange.com/questions/316450/..." width="" height="" />
           </div>
           <div class="user-info">
               <h6>User name</h6>
               <p>User job</p>
           </div>
       </div>
   </div>
</div>

If we put everything together it would look like this:

function wpusers_shortcode( $atts ) {

    // Attributes
    $atts = shortcode_atts(
        array(
            'group' => 'logistics',
        ),
        $atts
    );

    $args = array(
        'role'           => 'Subscriber',
        'order'          => 'ASC',
        'orderby'        => 'id',
        'meta_query'     => array(
                'relation' => 'AND',
                array(
                      'key'     => 'group', // custom field here
                      'value'   => $atts["group"],
                      'compare' => '=',
                      'type'    => 'CHAR',
                ),
        ),
        'fields'         => 'all_with_meta',
    );

    // The User Query
    $users = new WP_User_Query( $args );

    ob_start(); // Start buffer ?>

    <div class="container"> <?php
        if ( ! empty( $users->results ) ) { ?>
            <div class="row users"> <?php
                foreach ( $users->results as $user ) {
                    $user_photo = ...;
                    $user_name = ...;
                    $user_job = ...; ?>
                    <div class="col-xs-12 col-sm-4 col-md-3 user">
                        <div class="user-photo">
                            <img src="https://wordpress.stackexchange.com/questions/316450/<?= $user_photo["url"] ?>" width="https://wordpress.stackexchange.com/questions/316450/<?= $user_photo["width"] ?>" height="https://wordpress.stackexchange.com/questions/316450/<?= $user_photo["height"] ?>" />
                        </div>
                        <div class="user-info">
                            <h6><?= $user_name ?></h6>
                            <p><?= $user_job ?></p>
                        </div>
                    </div> <?php
                } ?>
            </div> <?php
        } else { ?>
            <div class="row user-no-result">
                <div class="col">
                    <div class="alert alert-warning">
                        <p><?= __("No users found.", "theme") ?></p>
                        <a class="btn btn-link"><?= __("Return to home", "theme") ?></a>
                    </div>
                </div>
            </div> <?php
        } ?>
    </div> <?php

    $output = ob_get_contents(); // Get buffer content
    ob_end_clean(); // Clear buffer
    return $output; // Return generated html
}
add_shortcode( 'wpusers', 'wpusers_shortcode' );

I hope you help, greetings!