The essential feature of microservices is independent deployment.
Microservices actually only serve to modularize software. But there are countless approaches to modularization: In the Java world, for example, classes, packages or JARs serve this purpose. Only in this way can large projects also be divided into small units and thus remain expandable and maintainable. But microservices are different: the essential characteristic of microservices is independent deployment. A microservice can be brought into production without having to re-deploy the other microservices as well.
In concrete terms, microservices can be implemented as individual docker containers, for example. Several such containers together then form an application. Each individual microservice can have a REST interface or generate the web interface as HTML pages for certain URLs.
Splitting microservices into several deployment units such as docker containers has several other consequences in addition to independent deployment: Each microservice can be implemented in a different programming language on a different platform. Finally, almost any infrastructure can run in a docker container. Likewise, each microservice can be scaled individually. This requires only one load balancer and several instances of the docker container. A microservice is also a unit in terms of robustness: If, for example, a microservice allocates too much memory or places a heavy load on the CPU, this only affects this one microservice. If the other microservices can even tolerate the failure of this microservice, the result is a very robust system.