# data[].attributes.attachment_link.description
Deep dives into powerful Figma features. Skip the basics and learn prototyping, auto-layout, systems, and illustration with your instructor, Pablo Stanley.

# data[].attributes.attachment_link.title
GitHub - trekhleb/javascript-algorithms: 📝 Algorithms and data structures implemented in JavaScript with explanations and links to further readings

# data[].attributes.attachment_link.description
This repository contains JavaScript based examples of many popular algorithms and data structures. Each algorithm and data structure has its own separate README with related explanations and links for further reading (including ones to YouTube videos). ☝ Note that this project is meant to be used for learning and researching purposes only, and it isnot meant to be used for production.

# data[].attributes.attachment_link.readable_text
Meet Laravel

Laravel is a web application framework with expressive, elegant syntax. A web framework provides a structure and starting point for creating your application, allowing you to focus on creating something amazing while we sweat the details.

Laravel strives to provide an amazing developer experience while providing powerful features such as thorough dependency injection, an expressive database abstraction layer, queues and scheduled jobs, unit and integration testing, and more.

Whether you are new to PHP or web frameworks or have years of experience, Laravel is a framework that can grow with you. We'll help you take your first steps as a web developer or give you a boost as you take your expertise to the next level. We can't wait to see what you build.

Why Laravel?

There are a variety of tools and frameworks available to you when building a web application. However, we believe Laravel is the best choice for building modern, full-stack web applications.

A Progressive Framework

We like to call Laravel a "progressive" framework. By that, we mean that Laravel grows with you. If you're just taking your first steps into web development, Laravel's vast library of documentation, guides, and video tutorials will help you learn the ropes without becoming overwhelmed.

If you're a senior developer, Laravel gives you robust tools for dependency injection, unit testing, queues, real-time events, and more. Laravel is fine-tuned for building professional web applications and ready to handle enterprise work loads.

A Scalable Framework

Laravel is incredibly scalable. Thanks to the scaling-friendly nature of PHP and Laravel's built-in support for fast, distributed cache systems like Redis, horizontal scaling with Laravel is a breeze. In fact, Laravel applications have been easily scaled to handle hundreds of millions of requests per month.

Need extreme scaling? Platforms like Laravel Vapor allow you to run your Laravel application at nearly limitless scale on AWS's latest serverless technology.

A Community Framework

Laravel combines the best packages in the PHP ecosystem to offer the most robust and developer friendly framework available. In addition, thousands of talented developers from around the world have contributed to the framework. Who knows, maybe you'll even become a Laravel contributor.

Your First Laravel Project

We want it to be as easy as possible to get started with Laravel. There are a variety of options for developing and running a Laravel project on your own computer. While you may wish to explore these options at a later time, Laravel provides Sail, a built-in solution for running your Laravel project using Docker.

Docker is a tool for running applications and services in small, light-weight "containers" which do not interfere with your local computer's installed software or configuration. This means you don't have to worry about configuring or setting up complicated development tools such as web servers and databases on your personal computer. To get started, you only need to install Docker Desktop.

Laravel Sail is a light-weight command-line interface for interacting with Laravel's default Docker configuration. Sail provides a great starting point for building a Laravel application using PHP, MySQL, and Redis without requiring prior Docker experience.

{tip} Already a Docker expert? Don't worry! Everything about Sail can be customized using the docker-compose.yml file included with Laravel.

Getting Started On macOS

If you're developing on a Mac and Docker Desktop is already installed, you can use a simple terminal command to create a new Laravel project. For example, to create a new Laravel application in a directory named "example-app", you may run the following command in your terminal:

curl -s "https://laravel.build/example-app" | bash

Of course, you can change "example-app" in this URL to anything you like. The Laravel application's directory will be created within the directory you execute the command from.

After the project has been created, you can navigate to the application directory and start Laravel Sail. Laravel Sail provides a simple command-line interface for interacting with Laravel's default Docker configuration:

cd example-app ./vendor/bin/sail up

The first time you run the Sail up command, Sail's application containers will be built on your machine. This could take several minutes. Don't worry, subsequent attempts to start Sail will be much faster.

Once the application's Docker containers have been started, you can access the application in your web browser at: http://localhost.

{tip} To continue learning more about Laravel Sail, review its complete documentation.

Getting Started On Windows

Before we create a new Laravel application on your Windows machine, make sure to install Docker Desktop. Next, you should ensure that Windows Subsystem for Linux 2 (WSL2) is installed and enabled. WSL allows you to run Linux binary executables natively on Windows 10. Information on how to install and enable WSL2 can be found within Microsoft's developer environment documentation.

{tip} After installing and enabling WSL2, you should ensure that Docker Desktop is configured to use the WSL2 backend.

Next, you are ready to create your first Laravel project. Launch Windows Terminal and begin a new terminal session for your WSL2 Linux operating system. Next, you can use a simple terminal command to create a new Laravel project. For example, to create a new Laravel application in a directory named "example-app", you may run the following command in your terminal:

curl -s https://laravel.build/example-app | bash

Of course, you can change "example-app" in this URL to anything you like. The Laravel application's directory will be created within the directory you execute the command from.

After the project has been created, you can navigate to the application directory and start Laravel Sail. Laravel Sail provides a simple command-line interface for interacting with Laravel's default Docker configuration:

cd example-app ./vendor/bin/sail up

The first time you run the Sail up command, Sail's application containers will be built on your machine. This could take several minutes. Don't worry, subsequent attempts to start Sail will be much faster.

Once the application's Docker containers have been started, you can access the application in your web browser at: http://localhost.

{tip} To continue learning more about Laravel Sail, review its complete documentation.

Developing Within WSL2

Of course, you will need to be able to modify the Laravel application files that were created within your WSL2 installation. To accomplish this, we recommend using Microsoft's Visual Studio Code editor and their first-party extension for Remote Development.

Once these tools are installed, you may open any Laravel project by executing the code . command from your application's root directory using Windows Terminal.

Getting Started On Linux

If you're developing on Linux and Docker is already installed, you can use a simple terminal command to create a new Laravel project. For example, to create a new Laravel application in a directory named "example-app", you may run the following command in your terminal:

curl -s https://laravel.build/example-app | bash

Of course, you can change "example-app" in this URL to anything you like. The Laravel application's directory will be created within the directory you execute the command from.

After the project has been created, you can navigate to the application directory and start Laravel Sail. Laravel Sail provides a simple command-line interface for interacting with Laravel's default Docker configuration:

cd example-app ./vendor/bin/sail up

The first time you run the Sail up command, Sail's application containers will be built on your machine. This could take several minutes. Don't worry, subsequent attempts to start Sail will be much faster.

Once the application's Docker containers have been started, you can access the application in your web browser at: http://localhost.

{tip} To continue learning more about Laravel Sail, review its complete documentation.

Choosing Your Sail Services

When creating a new Laravel application via Sail, you may use the with query string variable to choose which services should be configured in your new application's docker-compose.yml file. Available services include mysql, pgsql, mariadb, redis, memcached, meilisearch, selenium, and mailhog:

curl -s "https://laravel.build/example-app?with=mysql,redis" | bash

If you do not specify which services you would like configured, a default stack of mysql, redis, meilisearch, mailhog, and selenium will be configured.

Installation Via Composer

If your computer already has PHP and Composer installed, you may create a new Laravel project by using Composer directly. After the application has been created, you may start Laravel's local development server using the Artisan CLI's serve command:

composer create-project laravel/laravel example-app cd example-app php artisan serve

The Laravel Installer

Or, you may install the Laravel Installer as a global Composer dependency:

composer global require laravel/installer laravel new example-app cd example-app php artisan serve

Make sure to place Composer's system-wide vendor bin directory in your $PATH so the laravel executable can be located by your system. This directory exists in different locations based on your operating system; however, some common locations include:

macOS: $HOME/.composer/vendor/bin

Windows: %USERPROFILE%\AppData\Roaming\Composer\vendor\bin

GNU / Linux Distributions: $HOME/.config/composer/vendor/bin or $HOME/.composer/vendor/bin

For convenience, the Laravel installer can also create a Git repository for your new project. To indicate that you want a Git repository to be created, pass the --git flag when creating a new project:

laravel new example-app --git

This command will initialize a new Git repository for your project and automatically commit the base Laravel skeleton. The git flag assumes you have properly installed and configured Git. You can also use the --branch flag to set the initial branch name:

laravel new example-app --git --branch="main"

Instead of using the --git flag, you may also use the --github flag to create a Git repository and also create a corresponding private repository on GitHub:

laravel new example-app --github

The created repository will then be available at https://github.com/<your-account>/my-app.com. The github flag assumes you have properly installed the GitHub CLI and are authenticated with GitHub. Additionally, you should have git installed and properly configured. If needed, you can pass additional flags that supported by the GitHub CLI:

laravel new example-app --github="--public"

You may use the --organization flag to create the repository under a specific GitHub organization:

laravel new example-app --github="--public" --organization="laravel"

Initial Configuration

All of the configuration files for the Laravel framework are stored in the config directory. Each option is documented, so feel free to look through the files and get familiar with the options available to you.

Laravel needs almost no additional configuration out of the box. You are free to get started developing! However, you may wish to review the config/app.php file and its documentation. It contains several options such as timezone and locale that you may wish to change according to your application.

Environment Based Configuration

Since many of Laravel's configuration option values may vary depending on whether your application is running on your local computer or on a production web server, many important configuration values are defined using the .env file that exists at the root of your application.

Your .env file should not be committed to your application's source control, since each developer / server using your application could require a different environment configuration. Furthermore, this would be a security risk in the event an intruder gains access to your source control repository, since any sensitive credentials would get exposed.

{tip} For more information about the .env file and environment based configuration, check out the full configuration documentation.

Directory Configuration

Laravel should always be served out of the root of the "web directory" configured for your web server. You should not attempt to serve a Laravel application out of a subdirectory of the "web directory". Attempting to do so could expose sensitive files that exist within your application.

Next Steps

Now that you have created your Laravel project, you may be wondering what to learn next. First, we strongly recommend becoming familiar with how Laravel works by reading the following documentation:

How you want to use Laravel will also dictate the next steps on your journey. There are a variety of ways to use Laravel, and we'll explore two primary use cases for the framework below.

Laravel The Full Stack Framework

Laravel may serve as a full stack framework. By "full stack" framework we mean that you are going to use Laravel to route requests to your application and render your frontend via Blade templates or using a single-page application hybrid technology like Inertia.js. This is the most common way to use the Laravel framework.

If this is how you plan to use Laravel, you may want to check out our documentation on routing, views, or the Eloquent ORM. In addition, you might be interested in learning about community packages like Livewire and Inertia.js. These packages allow you to use Laravel as a full-stack framework while enjoying many of the UI benefits provided by single-page JavaScript applications.

If you are using Laravel as a full stack framework, we also strongly encourage you to learn how to compile your application's CSS and JavaScript using Laravel Mix.

{tip} If you want to get a head start building your application, check out one of our official application starter kits.

Laravel The API Backend

Laravel may also serve as an API backend to a JavaScript single-page application or mobile application. For example, you might use Laravel as an API backend for your Next.js application. In this context, you may use Laravel to provide authentication and data storage / retrieval for your application, while also taking advantage of Laravel's powerful services such as queues, emails, notifications, and more.

If this is how you plan to use Laravel, you may want to check out our documentation on routing, Laravel Sanctum, and the Eloquent ORM.

# data[].attributes.attachment_link.description
Laravel is a web application framework with expressive, elegant syntax. A web framework provides a structure and starting point for creating your application, allowing you to focus on creating something amazing while we sweat the details.

# data[].attributes.attachment_link.description
Learn from scratch, the basic concepts that you will need to build angular applications using the CLI. The Angular CLI is a tool to initialize, develop, scaffold...

# data[].attributes.attachment_link.readable_text
Devenir premium sur Grafikart, c'est soutenir la création de nouveaux contenus chaque semaine et accéder à du contenu exclusif pour apprendre et s'améliorer (comme le téléchargement des vidéos et des sources).

# data[].attributes.attachment_link.title
Tutoriels et Formations vidéos sur le développement web

# data[].attributes.attachment_link.description
Devenir premium sur Grafikart, c'est soutenir la création de nouveaux contenus chaque semaine et accéder à du contenu exclusif pour apprendre et s'améliorer (comme le téléchargement des vidéos et des sources).

# data[].attributes.attachment_link.title
Comprehensive JavaScript Tutorials and Video Workshops - @eggheadio

# data[].attributes.attachment_link.description
The absolute best JavaScript tutorials videos on the Internet. Start learning AngularJS and ReactJS Today!

# data[].attributes.attachment_link.readable_text
Beginners welcome

Start coding in seconds

Go ahead, give it a try. Our hands-on learning environment means you'll be writing real code from your very first lesson.

Not sure where to start? This short quiz will sort you out. Answer a few simple questions to get personal career advice and course recommendations. Take the quiz

Codecademy from Skillsoft

Level up your team's skills

Give your team the knowledge, experience, and confidence they need to tackle any problem.
Explore business plans

Start for free If you've made it this far, you must be at least a little curious. Sign up and take the first step toward your goals. Sign up

# data[].attributes.attachment_link.description
Beginners welcome Go ahead, give it a try. Our hands-on learning environment means you'll be writing real code from your very first lesson. Not sure where to start? This short quiz will sort you out. Answer a few simple questions to get personal career advice and course recommendations.

# data[].attributes.attachment_link.description
Explore our full catalog of programming courses, Skill Paths, and Career Paths for complete beginners, advanced learners, and everyone in between.

# data[].attributes.attachment_link.description
Putain de code ! est un site où vous pouvez lire (et publier) des bonnes pratiques de développement. Du contenu de qualité, revu et approuvé par la communauté.

# data[].attributes.attachment_link.readable_text
ang="en-us" xml:lang="en-us" xmlns="http://www.w3.org/1999/xhtml">

Learn X in Y Minutes: Scenic Programming Language Tours

Take a whirlwind tour of your next favorite language. Community-driven!

Want to add your favorite language to the list? Head on over to Github and send a pull request!

All articles © the original author and contributors, and licensed under a CC BY-SA 3.0 license.

Made by Adam Bard, handsome web developer

# data[].attributes.attachment_link.description
ang="en-us" xml:lang="en-us" xmlns="http://www.w3.org/1999/xhtml"> Learn X in Y Minutes: Scenic Programming Language Tours Take a whirlwind tour of your next favorite language. Community-driven! Want to add your favorite language to the list? Head on over to Github and send a pull request! All articles © the original author and contributors, and licensed under a CC BY-SA 3.0 license.

# data[].attributes.attachment_link.readable_text
Through contributions, donations, and sponsorship, you allow webpack to thrive. Your donations directly support office hours, continued enhancements, and most importantly, great documentation and learning material!

Latest Sponsors

Platinum Sponsors

Gold Sponsors

Silver Sponsors

Bronze Sponsors

Backers

# data[].attributes.attachment_link.description
webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

# data[].attributes.attachment_link.readable_text
Start with an HTML file. Add a <script> tag. Maybe some CSS. How about TypeScript? SASS? Images? No problem. Parcel works out of the box just as you'd expect.

Parcel supports many languages and file types out of the box, from web technologies like HTML, CSS, and JavaScript, to assets like images, fonts, videos, and more. And when you use a file type that isn't included by default, Parcel will automatically install all of the necessary plugins and dev dependencies for you!

Get started →

# data[].attributes.attachment_link.title
Parcel - The zero configuration build tool for the web.

# data[].attributes.attachment_link.description
Parcel combines a great out-of-the-box development experience with a scalable architecture that can take your project from just getting started to massive production application.

# data[].attributes.attachment_link.readable_text
Rejoignez une communauté bienveillante

Cela n'est pas toujours simple d'apprendre seul. La plateforme vous met à disposition un chat, directement intégré aux formations, sur lequel nos étudiants échangent quotidiennement. Vous pourrez ainsi poser toutes vos questions et partager votre code. Nous rejoindre

# data[].attributes.attachment_link.title
Dyma | Plateforme de formation aux technologies du Web

# data[].attributes.attachment_link.description
Cela n'est pas toujours simple d'apprendre seul. La plateforme vous met à disposition un chat, directement intégré aux formations, sur lequel nos étudiants échangent quotidiennement. Vous pourrez ainsi poser toutes vos questions et partager votre code. Nous rejoindre

# data[].attributes.attachment_link.description
Angular is a platform for building mobile and desktop web applications. Join the community of millions of developers who build compelling user interfaces with Angular.

# data[].attributes.attachment_link.readable_text
We're GitHub, the company behind the npm Registry and npm CLI. We offer those to the community for free, but our day job is building and selling useful tools for developers like you.

Take your JavaScript development up a notch

Get started today for free, or step up to npm Pro to enjoy a premium JavaScript development experience, with features like private packages.

Bring the best of open source to you, your team, and your company

Relied upon by more than 17 million developers worldwide, npm is committed to making JavaScript development elegant, productive, and safe. The free npm Registry has become the center of JavaScript code sharing, and with more than two million packages, the largest software registry in the world. Our other tools and services take the Registry, and the work you do around it, to the next level.

# data[].attributes.attachment_link.description
We're GitHub, the company behind the npm Registry and npm CLI. We offer those to the community for free, but our day job is building and selling useful tools for developers like you. Get started today for free, or step up to npm Pro to enjoy a premium JavaScript development experience, with features like private packages.

# data[].attributes.attachment_link.readable_text
A Global Open Source Community

Supported by Google, open to everyone

Collaborate on the open source framework, contribute to the package ecosystem on pub.dev, and find help when you need it.

# data[].attributes.attachment_link.description
Flutter transforms the entire app development process. Build, test, and deploy beautiful mobile, web, desktop, and embedded apps from a single codebase.

# data[].attributes.attachment_link.description
Dart is an approachable, portable, and productive language for high-quality apps on any platform.

# data[].attributes.attachment_link.readable_text
Docker est la plateforme de containers la plus populaire et la plus utilisée. Découvrez tout ce que vous devez savoir sur cette solution de containerisation : sa définition, son fonctionnement, ses avantages et inconvénients, ou encore quels sont ses principaux concurrents.
Les machines virtuelles (VM) sont de plus en plus utilisées par les entreprises. Une VM est un environnement de système d'exploitation ou d'application installé sur logiciel. Elle permet à l'utilisateur de profiter de la même expérience que sur une machine physique, avec plusieurs avantages.

Il est notamment possible de lancer plusieurs environnements d'OS sur la même machine, en les isolant les uns des autres. De même, la virtualisation permet de réduire les coûts au sein d'une entreprise en diminuant le nombre de machines virtuelles nécessaires. Les besoins en énergie s'en trouvent aussi atténués. Les backups et les restaurations s'en trouvent aussi simplifiés.

Cependant, les hyperviseurs de machines virtuelles reposent sur une émulation du hardware, et requièrent donc beaucoup de puissance de calcul. Pour remédier à ce problème, de nombreuses firmes se tournent vers les containers, et par extension vers Docker.

Qu'est-ce qu'un container ?

Les containers sont donc proches des machines virtuelles, mais présentent un avantage important. Alors que la virtualisation consiste à exécuter de nombreux systèmes d'exploitation sur un seul et même système, les containers se partagent le même noyau de système d'exploitation et isolent les processus de l'application du reste du système.

Docker : qu'est-ce que c'est ?

Il s'agit d'une plateforme logicielle open source permettant de créer, de déployer et de gérer des containers d'applications virtualisées sur un système d'exploitation. Les services ou fonctions de l'application et ses différentes bibliothèques, fichiers de configuration, dépendances et autres composants sont regroupés au sein du container. Chaque container exécuté partage les services du système d'exploitation.

Initialement créé pour fonctionner avec la plateforme Linux, Docker fonctionne désormais avec d'autres OS tels que Microsoft Windows ou Apple macOS. On compte également des versions de la plateforme conçues pour Amazon Web Services et Microsoft Azure.

Docker : quelles sont les fonctionnalités ?

La plateforme de conteneurisation repose sur sept composants principaux. Le Docker Engine est un outil client-serveur sur lequel repose la technologie de container pour prendre en charge les tâches de création d'applications basées container. Le moteur crée un processus daemon server-side permettant d'héberger les images, les containers, les réseaux et les volumes de stockage. Ce daemon fournit aussi une interface SLI client-side permettant aux utilisateurs d'interagir avec le daemon via l'API de la plateforme.

Les containers créés sont appelés Dockerfiles. Le composant Docker Compose permet de définir la composition des composants au sein d'un container dédié. Le Docker Hub est un outil SaaS permettant aux utilisateurs de publier et de partager des applications basées container via une bibliothèque commune.

Le mode Docker Swarm du Docker Engine prend en charge l'équilibrage des charges des clusters . Ainsi, les ressources de plusieurs hôtes peuvent être rassemblées pour agir comme une seul ensemble. Ainsi, les utilisateurs peuvent rapidement échelonner le déploiement de containers.

Docker : quels sont les avantages et les inconvénients ?

Par rapport aux machines virtuelles, Docker présente également plusieurs avantages. Elle permet de développer des applications de façon plus efficiente, en utilisant moins de ressources, et de déployer ces applications plus rapidement.

Cependant, elle présente aussi plusieurs inconvénients. Il peut être difficile de gérer de façon efficiente un grand nombre de containers simultanément. De plus, la sécurité être un problème. Les containers sont isolés, mais partagent le même système d'exploitation. De fait, une attaque ou une faille de sécurité sur l'OS peut compromettre tous les containers. Pour minimiser ce risque, certaines entreprises exécutent leurs containers au sein d'une machine virtuelle.

MAJ : Docker a rencontré une faille de sécurité qui a touché près de 5 % des utilisateurs. Près de 190 000 d'entre eux ont vu les données de leurs containers exposées après un accès non autoris à base de données Hub. L'organisation a demandé aux entreprises et aux personnes concernées de changer leur mot de passe.

Quelles sont les alternatives ?

On peut aussi évoquer l'écosystème d'outils qui fonctionnent avec la plateforme pour des tâches telles que le clustering ou la gestion de containers. On peut citer comme exemple Kubernetes, l'outil de Container Orchestration open source créé par Google.

Docker : les chiffres du succès

La version 1.0 de Docker fut lancée en juin 2014, dans le but de faciliter l'utilisation des containers. Très rapidement, la plateforme a rencontré un franc succès auprès de nombreuses entreprises. Aujourd'hui, selon les créateurs de Docker, plus de 3,5 millions d'applications ont été containerisées en utilisant cette technologie. L'on compte pas moins de 37 milliards d'applications containerisées téléchargées.

De même, d'après le système de monitoring cloud DataDog, 18,8% des utilisateurs avaient adopté la plateforme en 2017. De son côté, RightScale estime que l'adoption de la plateforme dans l'industrie du Cloud a augmenté de 35% en 2017 à 49% en 2018. Des géants comme Oracle et Microsoft l'ont adopté, au même titre que presque toutes les entreprises du Cloud.

Selon de 451 Research, l'essor de Docker n'est pas près de s'arrêter. Ces analystes estiment que le marché des containers va littéralement exploser d'ici 2021. Les entreprises vont multiplier les revenus par 4 avec un taux de croissance annuel de 35%, passant de 749 millions de dollars en 2016 à 3,4 milliards de dollars en 2021.

Docker Entreprise 3.0

Au cours de la DockerCon 2019 de mai dernier, Docker a officialisé la troisième version de sa plateforme Docker Entreprise. En version bêta, celle-ci profite d'un environnement de développement d'application containerisé directement embarqué au sein de la plateforme globale de l'entreprise. Les développeurs peuvent coder depuis leur ordinateur, puis déployer une solution en mode multi-cloud. Des fonctionnalités d'automatisation facilitent le déploiement des containers, tandis que Docker Application sert à déployer des applications multi-containers dans la plupart des infrastructures. Cette approche vise à rendre flexible leur installation et leur gestion.

Cloud Native Application Bundle passe en 1.0

Cloud Native Application Bundle ou CNAB est une spécification pour créer des applications multicontainers. Annoncée au mois de décembre dernier, cette fonctionnalité est désormais en version 1.0. Celle-ci consiste à définir comment différents composants d'applications basées sur le cloud sont rassemblés. Microsoft, Bitnami (racheté par VMware), HashiCorp, Intel, Pivotal et Datadog ont participé à ce projet.

Ainsi, les développeurs profitent d'une meilleure interaction entre les containers Docker et les outils comme Kubernetes YAML, Azure Resources Manager Template ou encore Helm charts. Ceux-ci forment un package possiblement protégé par une clé de chiffrement. Ce package devient alors un moyen standard de déployer des applications containerisées dans des environnements cloud ou sur site.

Attention aux malwares sur vos containers Docker !

Un malware de type crypto-jacking worm a été détecté dans les containers d'application Docker. C'est la division de cybersécurité de Palo Alto Network, Unit 42, qui a découvert ce logiciel malveillant la première.

Graboid a été identifié comme le premier crypto-jacking worm découvert sur Docker Hub. Plus précisément, il a été repéré sur l'édition communauté de Docker Engine. En revanche Docker Enterprise n'est pas concerné.

Comme tous les vers informatiques, ce worm est capable de se propager via les images mal sécurisées sur les serveurs. Or, sachant que les logiciels de cybersécurité n'inspectent généralement pas les données à l'intérieur des containers d'application, ce malgiciel s'avère particulièrement dangereux...

Les images corrompues ont été retirées de Docker Hub directement après avoir été signalées par Palo Alto Networks. Le directeur de la sécurité de Docker, Justin Cormack, invite les utilisateurs à ne pas modifier les paramètres par défaut du Docker Engine qui empêchent ce type d'attaque en refusant l'accès à distance.

Selon Unit 42, environ 2000 moteurs Docker non sécurisés ont été exposés sur le web. Une telle attaque, plus sophistiquée, pourrait avoir des conséquences encore plus désastreuses. Il est donc impératif pour les entreprises de bien sécuriser leurs hôtes Docker...

Des images Docker malveillantes utilisées pour le minage de Monero

En août 2021, l'entreprise de cybersécurité Aqua Security a fait une sinistre découverte. Une campagne de cryptomining utilisait des images Docker corrompues pour détourner les ressources informatiques des entreprises. L'objectif ? Miner des cryptomonnaies, et plus précisément du Monero.

Les images corrompues étaient téléchargées vers un dossier Docker Hub légitime. Au total, les chercheurs ont identifié cinq images de conteneur sur Docker Hub pouvant être utilisées dans le cadre d'une attaque ciblant les environnements Cloud-Native.

Selon Assaf Morag, Data Analyst en chef chez Aqua Security, les images malveillantes ont été découvertes par les chercheurs après une analyse manuelle classique des images de conteneur : " nous partageons régulièrement ce genre d'informations avec Docker Hub et d'autres registres ou dépôts publics comme GitHub et Bitbucket " .

Selon lui, " en se basant sur les informations que nous partageons avec Docker Hub, ils mènent leur enquête et décident s'il faut fermer ou non le namespace. Dans ce cas particulier, ils ont fermé leurs namespaces le jour où nous les avons contactés. Leur temps de réaction est absolument formidable " .

Les trois premiers conteneurs découverts par les chercheurs (thanhtudo, thieunutre et chanquaa) exécutent le script dao.py. Il s'agit d'un script Python, utilisé lors de plusieurs campagnes par le passé, exploitant le squatting de typo pour dissimuler des images de conteneurs malveillantes dans Docker Hub.

Les deux autres images de conteneurs sont appelées openjdk et golang. Pour l'heure, les chercheurs n'ont toutefois pas trouvé de preuve qu'elles ont été utilisées lors d'attaques. Leur objectif est de mettre en lumière ces images de conteneurs au nom trompeur, " de dire qu'elles contiennent un cryptominer exécuté dès que vous lancez le conteneur même si le namespace ne l'indique pas " .

Ces conteneurs malveillants sont conçus pour être facilement confondus avec des images de conteneur officielles, même si les comptes Docker Hub qui en sont responsables ne sont pas officiels. Selon les chercheurs, " une fois lancés, ils ressemblent à des conteneurs inoffensifs. Le xmrig binaire (MD5: 16572572588c2e241225ea2bf6807eff) est exécuté, et détourne les ressources pour le minage de cryptomonnaie " .

D'après Morag, des techniques d'ingénierie sociale peuvent être utilisées pour piéger une personne et l'inciter à utiliser ces images de conteneur : " je pense que vous ne vous connecterez jamais à une page web " mybunk . com " , mais si le hacker vous envoie un lien vers ce namespace, cela peut arriver " . En effet, ces images de conteneur ont accumulé chacun plus de 10 000 pulls.

Lorsqu'une personne exécute ces images de conteneur, un script charge la configuration de minage et exécute un binaire conçu pour communiquer avec le bassin de minage et exécuter le script de minage de crypto XMRIG.

Afin de limiter les risques, les chercheurs de Aqua Security recommandent aux entreprises d'améliorer leurs mesures défensives pour éviter d'être victimes de ce type d'attaques. Il faut prendre conscience que " l es hackers ciblent de plus en plus les chaînes logistiques logicielles des entreprises, et deviennent meilleurs pour dissimuler leurs attaques " .

Lorsque vous exécutez des conteneurs depuis un registre public, il est recommandé de " traiter le registre en tant que source avec un haut risque d'attaques sur la supply chain " . Les hackers tentent de piéger les développeurs pour le pulling d'images malveillantes en les déguisant en images populaires. Pour réduire le risque, " créez un registre interne tenu à jour pour les images de conteneur de base et limitez qui peut accéder aux registres publics " . Mettez aussi en place des règles pour s'assurer que les images de conteneur soient validées avant d'être intégrées au registre interne.

Bien souvent, les attaques sophistiquées sont en mesure d'éviter la détection lorsque les organisations utilisent un scanning statique ou basé sur des signatures ou des patterns. " Par exemple, les hackers peuvent échapper à la détection en intégrant du code aux images de conteneurs qui téléchargent des malwares uniquement pendant le runtime " .

Pour cette raison, " en plus du scanning de vulnérabilités sur les images de conteneurs externes, il est important d'utiliser des outils pour analyser dynamiquement le comportement du conteneur dans un bac à sable et d'identifier les vecteurs d'attaque qui ne seraient pas détectés avec un scanning de code statique " . Enfin, les chercheurs recommandent de signer numériquement les images de conteneur ou d'utiliser d'autres méthodes pour maintenir l'intégrité des images et s'assurer que les images de conteneur utilisées soient les mêmes que celles ayant été approuvées.

Docker et Kubernetes

Alors que Docker permet de créer des conteneurs, Kubernetes permet l'orchestration et la gestion de ces conteneurs. Il est possible d'utiliser Docker pour le packaging et le shipping d'une application, et Kubernetes pour le déploiement et le scaling de cette application.

Les startups et les petites entreprises avec peu de conteneurs peuvent généralement les gérer sans Kubernetes, mais cela devient beaucoup plus difficile lorsque le nombre de conteneurs augmente.

Ensemble, ces deux outils constituent une part essentielle de l'architecture Cloud moderne et de la transformation numérique. Ils sont désormais couramment utilisés conjointement pour accélérer le déploiement et la relaxe d'applications.

Docker revend sa division Entreprise à Mirantis, et se refocalise sur les outils de développement Cloud

En novembre 2019, Mirantis a acquis Docker Enterprise, sa Docker Enterprise Technology Platform et toute la propriété intellectuelle associée : le Docker Enterprise Engine, le Docker Trusted Registry, le Docker Unified Control Plane et le Docker CLI.

De même, 300 employés de Docker ont rejoint Mirantis qui récupère aussi 700 clients d'entreprise. L'objectif de la firme est de pouvoir rivaliser avec VMware ou IBM / Red Hat.

Suite à cette acquisition, Docker a levé 35 millions de dollars auprès de Benchmark Capital et Insight Partners. La firme a aussi nommé un nouveau CEO : Scott Johnston.

Docker a fait le choix de revenir à ses racines, en proposant des services Cloud permettant aux développeurs de découvrir rapidement de technologies de développement d'application, de partager leurs applications avec leurs équipes, et d'exécuter ces applications sur n'importe quel endpoint Kubernetes localement ou sur le Cloud.

Docker et le Cloud : les partenariats avec AWS et Microsoft Azure

Au fil des derniers mois, suite à l'acquisition de sa division d'entreprise par Mirantis, Docker a noué des partenariats avec les géants du Cloud. En mai 2020, un partenariat avec Microsoft a été annoncé pour simplifier l'exécution de conteneurs Docker sur le cloud Azure.

L'objectif est une meilleure intégration entre les Docker et les outils de développeur Azure tels que Visual Studio Code et Azure Container Instances (ACI). Cette intégration permettre d'inclure les conteneurs Docker plus rapidement, plus facilement et de façon plus efficace lors du développement d'applications avec les outils Microsoft.

En juillet 2020, un partenariat avec AWS a aussi été annoncé. Là encore, l'objectif est une meilleure intégration entre les outils Compose et Desktop de Docker et les services AWS ECS et ECS on AWS Fargate.

Auparavant, il était difficile d'exécuter des fichiers Compose sur ECS. Désormais, les deux entreprises ont simplifié le processus afin de permettre d'alterner facilement entre les conteneurs exécutés localement et sur ECS.

Là encore, l'objectif est de simplifier la construction et le déploiement d'applications conteneurisées sur AWS. Il est désormais plus facile de déployer les applications en conteneurs depuis un environnement Docker local vers Amazon ECS. Les développeurs peuvent ainsi déployer leurs applications plus rapidement et se focaliser sur le développement plutôt que sur le déploiement Cloud...

DockerCon Live 2021 : Docker se focalise sur la sécurité des conteneurs

En mai 2021, lors de l'évènement virtuel DockerCon Live 2021, Docker a présenté plusieurs nouvelles solutions. L'outil Docker Developments Environments permet aux développeurs de créer automatiquement une instance virtuelle de leur environnement de développement, pour pouvoir le partager avec les autres membres d'une équipe.

Le Docker Compose offre une meilleure intégration avec la ligne d'interface de commande (CLI) Docker afin d'accélérer le déploiement d'applications sur les services Cloud. En outre, les Scoped Personal Access Tokens permettent aux développeurs de définir différents types de tokens d'accès pour les images de conteneur pour chaque utilisateur.

Autre annonce marquante de cette conférence : Datadog, Red Hat et VMware ont joint le programme Docker Verified Publisher. Ce programme permet aux utilisateurs d'accéder à des conteneurs de vendeurs tiers. En outre, les Docker Official Images peuvent désormais être téléchargées via les registres Amazon Web Services (AWS) et Mirantis, en guise d'alternative au DockerHub.

Selon le CEO Scott Johnston, Docker Inc cherche à résoudre deux des principaux problèmes que rencontrent les entreprises lors de la création d'applications conteneurisées. Tout d'abord, le télétravail imposé par la crise du COVID-19 nuit à la collaboration entre les développeurs. Pour contribuer à résoudre ce problème, Docker automatise le processus de partage d'une instance virtuelle d'environnement de développement Docker entre les développeurs.

Toujours selon Johnston, le second problème principal de Docker concerne la sécurité des chaînes logistiques de logiciels. Les cybercriminels utilisent désormais fréquemment les conteneurs Docker pour distribuer des malwares. Le programme Docker Verified Publisher va permettre aux développeurs de s'assurer qu'ils n'utilisent pas de conteneurs contaminés par un malware.

Pour l'heure, seuls 160 fournisseurs de conteneurs ont accepté de participer à cette initiative. Toutefois, le CEO précise que 25% des conteneurs téléchargés via les registres de la firme proviennent de ces vendeurs.

Au total, selon Docker Inc, 13 milliards de pulls d'image sont effectués chaque mois à partir de 8 millions de dépôts résidant sur le Docker Hub et par plus de 13 millions de développeurs. Selon Johnston, dans un contexte où les fuites de données massives se succèdent, l'accent est mis plus que jamais sur la sécurité des applications.

# data[].attributes.attachment_link.title
Docker : tout savoir sur la plateforme de containérisation

# data[].attributes.attachment_link.description
Docker est la plateforme de containers la plus populaire et la plus utilisée. Découvrez tout ce que vous devez savoir sur cette solution de containerisation : sa définition, son fonctionnement, ses avantages et inconvénients, ou encore quels sont ses principaux concurrents. Les machines virtuelles (VM) sont de plus en plus utilisées par les entreprises.

# data[].attributes.attachment_link.title
Psg Messi Landing Page using Flutter (Web)

# data[].attributes.attachment_link.description
Psg Messi Landing Page using Flutter (Web)

# data[].attributes.attachment_link.description
A convenience widget that wraps a number of widgets that are commonly required for applications implementing Material Design.

# data[].attributes.attachment_link.description
An iOS-style full-screen modal route that opens when the child is long-pressed. Used to display relevant actions for your content.

# data[].attributes.attachment_link.readable_text
Now that you know about declarative UI programming and the difference between ephemeral and app state, you are ready to learn about simple app state management.

On this page, we are going to be using the provider package. If you are new to Flutter and you don't have a strong reason to choose another approach (Redux, Rx, hooks, etc.), this is probably the approach you should start with. The provider package is easy to understand and it doesn't use much code. It also uses concepts that are applicable in every other approach.

That said, if you have a strong background in state management from other reactive frameworks, you can find packages and tutorials listed on the options page.

Our example

For illustration, consider the following simple app.

The app has two separate screens: a catalog, and a cart (represented by the MyCatalog, and MyCart widgets, respectively). It could be a shopping app, but you can imagine the same structure in a simple social networking app (replace catalog for "wall" and cart for "favorites").

The catalog screen includes a custom app bar ( MyAppBar) and a scrolling view of many list items ( MyListItems).

Here's the app visualized as a widget tree.

So we have at least 5 subclasses of Widget. Many of them need access to state that "belongs" elsewhere. For example, each MyListItem needs to be able to add itself to the cart. It might also want to see whether the currently displayed item is already in the cart.

This takes us to our first question: where should we put the current state of the cart?

Lifting state up

In Flutter, it makes sense to keep the state above the widgets that use it.

Why? In declarative frameworks like Flutter, if you want to change the UI, you have to rebuild it. There is no easy way to have MyCart.updateWith(somethingNew). In other words, it's hard to imperatively change a widget from outside, by calling a method on it. And even if you could make this work, you would be fighting the framework instead of letting it help you.

Even if you get the above code to work, you would then have to deal with the following in the MyCart widget:

You would need to take into consideration the current state of the UI and apply the new data to it. It's hard to avoid bugs this way.

In Flutter, you construct a new widget every time its contents change. Instead of MyCart.updateWith(somethingNew) (a method call) you use MyCart(contents) (a constructor). Because you can only construct new widgets in the build methods of their parents, if you want to change contents, it needs to live in MyCart 's parent or above.

Now MyCart has only one code path for building any version of the UI.

In our example, contents needs to live in MyApp. Whenever it changes, it rebuilds MyCart from above (more on that later). Because of this, MyCart doesn't need to worry about lifecycle-it just declares what to show for any given contents. When that changes, the old MyCart widget disappears and is completely replaced by the new one.

This is what we mean when we say that widgets are immutable. They don't change-they get replaced.

Now that we know where to put the state of the cart, let's see how to access it.

Accessing the state

When a user clicks on one of the items in the catalog, it's added to the cart. But since the cart lives above MyListItem, how do we do that?

A simple option is to provide a callback that MyListItem can call when it is clicked. Dart's functions are first class objects, so you can pass them around any way you want. So, inside MyCatalog you can define the following:

This works okay, but for an app state that you need to modify from many different places, you'd have to pass around a lot of callbacks-which gets old pretty quickly.

Fortunately, Flutter has mechanisms for widgets to provide data and services to their descendants (in other words, not just their children, but any widgets below them). As you would expect from Flutter, where Everything is a Widget™, these mechanisms are just special kinds of widgets- InheritedWidget, InheritedNotifier, InheritedModel, and more. We won't be covering those here, because they are a bit low-level for what we're trying to do.

Instead, we are going to use a package that works with the low-level widgets but is simple to use. It's called provider.

Before working with provider, don't forget to add the dependency on it to your pubspec.yaml.

Now you can import 'package:provider/provider.dart'; and start building.

With provider, you don't need to worry about callbacks or InheritedWidgets. But you do need to understand 3 concepts:

ChangeNotifier

ChangeNotifierProvider

Consumer

ChangeNotifier

ChangeNotifier is a simple class included in the Flutter SDK which provides change notification to its listeners. In other words, if something is a ChangeNotifier, you can subscribe to its changes. (It is a form of Observable, for those familiar with the term.)

In provider, ChangeNotifier is one way to encapsulate your application state. For very simple apps, you get by with a single ChangeNotifier. In complex ones, you'll have several models, and therefore several ChangeNotifiers. (You don't need to use ChangeNotifier with provider at all, but it's an easy class to work with.)

In our shopping app example, we want to manage the state of the cart in a ChangeNotifier. We create a new class that extends it, like so:

The only code that is specific to ChangeNotifier is the call to notifyListeners(). Call this method any time the model changes in a way that might change your app's UI. Everything else in CartModel is the model itself and its business logic.

ChangeNotifier is part of flutter:foundation and doesn't depend on any higher-level classes in Flutter. It's easily testable (you don't even need to use widget testing for it). For example, here's a simple unit test of CartModel:

ChangeNotifierProvider

ChangeNotifierProvider is the widget that provides an instance of a ChangeNotifier to its descendants. It comes from the provider package.

We already know where to put ChangeNotifierProvider: above the widgets that need to access it. In the case of CartModel, that means somewhere above both MyCart and MyCatalog.

You don't want to place ChangeNotifierProvider higher than necessary (because you don't want to pollute the scope). But in our case, the only widget that is on top of both MyCart and MyCatalog is MyApp.

Note that we're defining a builder that creates a new instance of CartModel. ChangeNotifierProvider is smart enough not to rebuild CartModel unless absolutely necessary. It also automatically calls dispose() on CartModel when the instance is no longer needed.

If you want to provide more than one class, you can use MultiProvider:

Consumer

Now that CartModel is provided to widgets in our app through the ChangeNotifierProvider declaration at the top, we can start using it.

This is done through the Consumer widget.

We must specify the type of the model that we want to access. In this case, we want CartModel, so we write Consumer<CartModel>. If you don't specify the generic (<CartModel>), the provider package won't be able to help you. provider is based on types, and without the type, it doesn't know what you want.

The only required argument of the Consumer widget is the builder. Builder is a function that is called whenever the ChangeNotifier changes. (In other words, when you call notifyListeners() in your model, all the builder methods of all the corresponding Consumer widgets are called.)

The builder is called with three arguments. The first one is context, which you also get in every build method.

The second argument of the builder function is the instance of the ChangeNotifier. It's what we were asking for in the first place. You can use the data in the model to define what the UI should look like at any given point.

The third argument is child, which is there for optimization. If you have a large widget subtree under your Consumer that doesn't change when the model changes, you can construct it once and get it through the builder.

It is best practice to put your Consumer widgets as deep in the tree as possible. You don't want to rebuild large portions of the UI just because some detail somewhere changed.

Instead:

Provider.of

Sometimes, you don't really need the data in the model to change the UI but you still need to access it. For example, a ClearCart button wants to allow the user to remove everything from the cart. It doesn't need to display the contents of the cart, it just needs to call the clear() method.

We could use Consumer<CartModel> for this, but that would be wasteful. We'd be asking the framework to rebuild a widget that doesn't need to be rebuilt.

For this use case, we can use Provider.of, with the listen parameter set to false.

Using the above line in a build method won't cause this widget to rebuild when notifyListeners is called.

Putting it all together

You can check out the example covered in this article. If you want something simpler, see what the simple Counter app looks like when built with provider.

By following along with these articles, you've greatly improved your ability to create state-based applications. Try building an application with provider yourself to master these skills.

# data[].attributes.attachment_link.description
Now that you know about declarative UI programming and the difference between ephemeral and app state, you are ready to learn about simple app state management. On this page, we are going to be using the provider package.

# data[].attributes.attachment_link.readable_text
Build

Spin up new environments quickly

Develop your own unique applications with Docker images and create multiple containers using Docker Compose.

Integrate with your existing tools

Docker works with all development tools such as VS Code, CircleCI, and GitHub.

Containerize applications for consistency

Run in any environment consistently from on-premises Kubernetes to AWS ECS, Azure ACI, Google GKE, and more.

# data[].attributes.attachment_link.description
Docker is a platform designed to help developers build, share, and run container applications. We handle the tedious setup, so you can focus on the code.

# data[].attributes.attachment_link.readable_text
An approachable, performant and versatile framework for building web user interfaces.

Approachable

Builds on top of standard HTML, CSS and JavaScript with intuitive API and world-class documentation.

Performant

Truly reactive, compiler-optimized rendering system that rarely requires manual optimization.

Versatile

A rich, incrementally adoptable ecosystem that scales between a library and a full-featured framework.

# data[].attributes.attachment_link.title
Vue.js - The Progressive JavaScript Framework | Vue.js

# data[].attributes.attachment_link.description
Vue.js - The Progressive JavaScript Framework

# data[].attributes.attachment_link.title
Symfony, High Performance PHP Framework for Web Development

# data[].attributes.attachment_link.description
SymfonyWorld Online 2021 Winter Edition December 9 - 10, 2021 100% Online +20 talks and workshops

# data[].attributes.attachment_link.title
Gestion de projet informatique : méthodologie et techniques de conduite de projet

# data[].attributes.attachment_link.description
Gestion de projet informatique : découvrez les étapes à suivre pour gérer vos projets IT, nos conseils et des outils de planification du travail en équipe !

# data[].attributes.attachment_link.provider_name
Layout | Creative content for designers, developers, & marketers

# data[].attributes.attachment_link.readable_text
Thanks to Flexbox, a new layout mode in CSS3, we can get all of our cards in a row-literally. Card designs have grown in popularity over the past few years; as you've probably noticed, social media sites have really embraced cards. Pinterest and Dribbble use card layouts to feature information and visuals. And if you're into Material Design, Google's cards are well described in their pattern library.

I personally like card layouts for their readability and how scrollable they are. They present the perfect "burst" of information in a way that is easy to browse, scroll, and scan all at once.

How to create a card layout

If you've ever attempted rows of even-height content, you know that building them hasn't always been easy. You've probably had to do quite a bit of fiddling to get it to work in the past. Thanks to Flexbox, those days are pretty much behind you. Depending on the level of browser support you need to provide, you may have to include some fallbacks, but browser support for this feature is pretty reliable these days. To be safe, be sure to check out Flexbox on the trusty Can I use. And remember, you should never make changes on your live site. Try experimenting with Local instead, a free local WordPress development app.

The basic idea of Flexbox is that you can set a container's display property to flex, which will "flex" the size of all the containers within it. Equal-height columns and the scaling and contracting options will simplify how advanced layouts can be created. Starting with cards is like a Flexbox cheat sheet, but once you master the basics, you can create more complex layouts.

Flexbox and versatility

Cards are versatile, visually appealing, and easy to interact with on both large and small devices, which is perfect for responsive design. Each card acts as a content container that easily scales up or down. As screen sizes get smaller, they number of cards in the row typically decreases and they start to stack vertically. There is additional flexibility as they can be a fixed or variable height.

How to create the layout

We will create a Flexbox card layout that has a row of four horizontal containers on larger screens, two on medium, and single column for small devices.

Below is the code snippet to create a basic layout for showing four cards. I'm not including the inner card content (as that gets too long in the code samples), so be sure to put some starter content in there (and have the amount of content vary between the four cards). Also, there is one row of four cards shown here to start, but more can be added if you want to see behavior with multiple rows of content. All code can be found on Codepen.

To display our layout design in a grid pattern, we'll need to start on the outside and work our way in. It's important to make sure you reference the correct container, otherwise things will get a little messy.

The section with a class of .cards is what we will target first. The display property of the container is what we need to change to flex.

Here is the HTML you'll want to start with:

<div class="centered">

            <section class="cards">

                <article class="card">
                   <p>content for card one</p>
                </article><!-- /card-one -->

 	<article class="card">
                   <p>content for card two</p>
            </article><!-- /card-two -->

<article class="card">
                  <p>content for card three</p>
            </article><!-- /card-three -->

<article class="card">
                   <p>content for card four</p>
            </article><!-- /card-four -->

	</section>
</div>

Here is the CSS to start with:

.cards {
   display: flex;
   justify-content: space-between;
}

Flex property

Before getting in too deep, it's good to know the basics of the flex property. The flex property specifies the length of the item, relative to the rest of the flexible items inside the same container. The flex property is a shorthand for the flex-grow, flex-shrink, and the flex-basis properties. The default value is 0 1 auto;. In my opinion, the best way to fully understand Flexbox is to play around with the different values and see what happens.

The flex-grow property of a flex item specifies what amount of space inside the flex container the item should take up.

The flex-shrink property specifies how the item will shrink relative to the rest of the flexible items inside the same container.

The flex-basis property specifies the initial main size of a flex item. This property determines the size of the content-box, unless specified otherwise using box-sizing. Auto is the default when the width is defined by the content, which is similar to width: auto;. It will take up space defined by its own content. There can be a specified value which remains true as seen in the flex-basis: 15em;. If the value is 0, things are pretty set because the item will not expand to fill free space.

We started with display: flex; and justify-content: space-between; and at this point, things are a little unpredictable. Flexbox is being used, even though it isn't super obvious right now. With this declaration, each of the flex items have been placed next to one another in a horizontal row.

See this on Codepen.

You're probably wondering why each of these flex items has a different width. Flexbox is trying to figure out what the smallest default width is for each of these items. And because of various word lengths and other design elements, you end up with these different sized boxes. To achieve a consistent look, we'll need to do a little more work. Setting a wrap and determining the desired width will help make these into uniform cards.

.cards {
   display: flex;
   flex-wrap: wrap;
   justify-content: space-between;
}

By default, flex items will all try to fit onto one line. Adding the flex-wrap: wrap; makes the items wrap underneath one another because the default is full width.

See this on Codepen.

Full width is great for small devices, so let's keep this in mind as we plan for our larger screen before tackling various breakpoints. When we change the width, the cards start to look more even.

We need to add the .card class now to style our individual cards. This can go right under the .cards styles.

.cards {
   display: flex;
   flex-wrap: wrap;
   justify-content: space-between;
}

.card {
	flex: 0 1 24%;
}

Remember from before, the flex property is shorthand: flex-grow is 0, flex-shrink is 1, and the width is 24%. By adding a specified width, this gives us a row of four with some space between.

See this on Codepen.

We set the justify-content property for spacing purposes. The first item is displaying hard left, the second and third items display in the middle, and the fourth item is displaying hard right. Because the width of the card is 24%, there's some space left since our four columns at 24% do not total 100%. We have 4% remaining to be exact. This 4% is placed equally between each of the items. So we have roughly 1.33% of space between the cards.

See this on Codepen.

We can be more precise also by using calc. Changing the flex-basis value to use calc would look something like this:

.card {
	flex: 0 1 calc(25% - 1em);
}

The cool thing with this is that the browser will grab 25% of the space and remove 1em from it, which makes the cards slightly smaller.

It's a slick way to adjust the available space. The 1em is distributed evenly between the items and we end up with the perfect layout.

Up until now, we really haven't talked much about height. I've added another row of cards to demonstrate how the height works. It depends on which card has the most content - the height of the others will follow. Therefore, every row of content will have the same height.

This is a very "zoomed out" view, but you'll notice that the first row is quite tall because the second card has more text than the others in that row. The second row has less text, so overall it is shorter.

Cards for smaller devices

Currently we have four columns on all screens, which isn't really a best practice. If you make your browser window smaller, you'll see that the four cards just get more squished on smaller screens, which isn't ideal for readability. Luckily with media queries, things will start to look much better.

To begin solving the issue, specified breakpoints will ensure that content is displaying properly across all different screen types.

Here are the following breakpoints that will be used (feel free to use your own as well, the concepts still apply):

@media screen and (min-width: 40em) {
    .cards {
   }

    .card {
    }
}

@media screen and (min-width: 60em) {
    .cards {
   }

    .card {
     }
}


@media screen and (min-width: 52em) {
    .centered {

    }
}

It's been big thinking until now. Let's get into the mobile-first mindset and start with the min-width: 40em breakpoint.

@media screen and (min-width: 40em) {
    .cards {
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
    }

    .card {
        flex: 0 1 calc(25% - 1em);
    }
}

With these changes, cards will display at full-screen width and stack below each other on any screen smaller than about 640px wide. If you expand the browser window to anything above that, the column of four returns. This makes sense because there is a min-width of 40em and this is where we've created the row of four cards.

What is missing here is the middle ground. For the mid range, having two cards in a row is more readable, rather than the four squished cards. Before we figure out the row of two cards, another media query needs to be added to accommodate the largest screens, which will have the row of four cards.

@media screen and (min-width: 60em) {
    .card {
        flex: 0 1 calc(25% - 1em);
    }
}

The new media query with a min-width of 60em is where the four cards will be declared. The min-width of 40em is where the row of two cards will be declared. The magic is happening with the flex calc value of 50% - 1em.

@media screen and (min-width: 40em) {
    .cards {
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
    }

    .card {
        flex: 0 1 calc(50% - 1em);
    }
}

With that simple change, things are now working! Shrink and expand the browser window to ensure that everything looks correct.

See this on Codepen.

If your rows of cards look right, then you're good to go! If you're trying this tutorial and have an uneven last row, keep reading.

Dynamic content and last row of cards spacing

Depending on your number of cards, you may or may not have a goofy last row. If there is a full last row or only one extra card, there won't be an issue. Sometimes you'll have your content planned out in advance, but if the content is dynamic, the last row of cards may not behave as you intended. If there is more than one extra card and justify content is set, it will make the space between them even, and may not line up with the row(s) above.

To get this look, it requires a different way of thinking. I'd argue this isn't as efficient, but it is relatively simple.

The .cards and .card styling was done outside of a media query:

.cards {
    display: flex;
    flex-wrap: wrap;
 }

.card {
    flex: 1 0 500px;
    box-sizing: border-box;
    margin: 1rem .25em;
}

The media queries are where the number of cards is determined:

@media screen and (min-width: 40em) {
    .card {
       max-width: calc(50% -  1em);
    }
}

@media screen and (min-width: 60em) {
    .card {
        max-width: calc(25% - 1em);
    }
}

Take a look at Codepen to see the modified solution.

Hopefully this gives you a basic overview of Flexbox concepts that will get you started. Flexbox has pretty good browser support, and card layouts will continue to be utilized in website designs. And remember, card layouts are just the beginning of how you can utilize Flexbox.

Download the free guide here!

What else have you built using Flexbox? Share your projects in the comments!

# data[].attributes.attachment_link.title
How to use Flexbox to create a modern CSS card design layout

# data[].attributes.attachment_link.description
Thanks to Flexbox, a new layout mode in CSS3, we can get all of our cards in a row-literally. Card designs have grown in popularity over the past few years; as you've probably noticed, social media sites have really embraced cards. Pinterest and Dribbble use card layouts to feature information and visuals.

# data[].attributes.attachment_link.readable_text
Flexbox browser support

Three versions of the flexbox spec - each with different syntax - have been implemented in browsers.

The two 2012 specs are roughly equivilant in terms of features, differing mainly in syntax. The earlier 2009 spec is less comprehensive though covers a lot of the same ground.

More browser support info available on caniuse.com.

Known issues

Flexbox early 2012

Flexbox early 2012 (Internet Explorer 10)

Flexbox 2009

Box wrapping is not supported. box-lines is the property in this spec to achieve wrapping, though unfortunately no browser implemented it.

Ordering flex-items with box-ordinal-group requires a positive integer (the value 0 is also valid in Firefox but not in Webkit, so just use positive integers).

Flexbox 2009 (Firefox)

Firefox has a number of non-trivial issues with its 2009 implementation:

The setting display: box is treated as display: inline-box if there is no width set.

Percentage widths set on flex items are ignored.

The setting box-align: justify (equiv. justify-content: space-between) does not work.

Flexbox ignores overflow: hidden and expands the flexbox child when the content is larger than the child's width.

The outline on flexbox children is padded as if by a transparent border of the same width.

If you set box-flex to 0, Firefox forces the element to act like it's using the quirks-mode box model.

Further reading

Code and design by @pete_b. Prefixing and polyfills generated by CSS-Crush

# data[].attributes.attachment_link.title
Flexy Boxes - CSS flexbox playground and code generation tool

# data[].attributes.attachment_link.description
Online CSS flexbox playground and code generator. Supports all existing flexbox implementations.

# data[].attributes.attachment_link.description
An open list of example apps made with Flutter include many open source samples.

# data[].attributes.attachment_link.title
Google for Developers - Software Development Guides, Tools & More

# data[].attributes.attachment_link.description
Explore Google's developer tools for AI, Cloud, app, web, and software development to help you build smarter and ship faster.

# data[].attributes.attachment_link.readable_text
Current Sponsors

We're a small group of volunteers that spend their free time maintaining this project, funded by the community. If Babel has benefited you in your work, becoming a contributor or sponsoring might just be a great way to give back!

# data[].attributes.attachment_link.description
We're a small group of volunteers that spend their free time maintaining this project, funded by the community. If Babel has benefited you in your work, becoming a contributor or sponsoring might just be a great way to give back!

# data[].attributes.attachment_link.description
A searchable catalog of PostCSS plugins.

# data[].attributes.attachment_link.readable_text
Find the guides, samples, and references you need to use the database, visualize data, and build applications on the MongoDB data platform.

Zoe works at a university that uses MongoDB to store student records. Since her background is in SQL, Zoe reads the MongoDB Manual to learn how to build queries using the mongo shell.

Find more resources and support in MongoDB University and the MongoDB Community.

University

Free Online Courses on MongoDB University

Build your MongoDB expertise for free with in-depth lessons and videos on University.
Get started on MongoDB University

Community

Collaborative Community Forums

Learn and build relationships with like-minded developers using MongoDB.
Join our Community

© 2021 MongoDB, Inc.

© 2021 MongoDB, Inc.

# data[].attributes.attachment_link.description
Find the guides, samples, and references you need to use the database, visualize data, and build applications on the MongoDB data platform. Zoe works at a university that uses MongoDB to store student records. Since her background is in SQL, Zoe reads the MongoDB Manual to learn how to build queries using the mongo shell.

# data[].attributes.attachment_link.description
Mongoose provides a straight-forward, schema-based solution to model your application data. It includes built-in type casting, validation, query building, business logic hooks and more, out of the box.

# data[].attributes.attachment_link.description
Learn to use the Dart language and libraries.

# data[].attributes.attachment_link.readable_text
Compose design tools

Create dynamic layouts with Jetpack Compose. Then preview your layouts on any screen size and inspect Compose animations using the built-in inspection tools.

Intelligent code editor

Write better code, work faster, and be more productive with an intelligent code editor that provides code completion for Kotlin, Java, and C/C++ programing languages. Moreover, when editing Jetpack Compose you can see your code changes reflected immediately with Live Edit.

Find opportunities to optimize your Android app size before publishing by inspecting the contents of your app APK file or Android App Bundle. Inspect the manifest file, resources, and DEX files. Compare two APKs or Android App Bundles to see how your app size changed between app versions.

Getting started

Learn how to set up your app development environment, configure Android Studio, and start writing an Android app.

Platform

Android Studio package

Size

SHA-256 checksum

Windows
(64-bit)

android-studio-2022.3.1.22-windows.exe
Recommended

1.1 GB

cfb4cf2485493b7de74bcdc5d1c0421b70291f3e45257cb0e64da745c48870bc

Windows
(64-bit)

android-studio-2022.3.1.22-windows.zip
No .exe installer

1.1 GB

25e70bc4e8a901d66c2d2721c4a9122089916df417a725cf6c7de46857c3db0b

Mac
(64-bit)

android-studio-2022.3.1.22-mac.dmg

1.2 GB

c8c3c11fbf2251d1a79689d665907527b5d438d7ca75cab179ed0704978c82d7

Mac
(64-bit, ARM)

android-studio-2022.3.1.22-mac_arm.dmg

1.2 GB

c78ebd101756bc1ecd882d5de1ebe1842272c2f7c08afc65cd3a4a5e4ee66a08

Linux
(64-bit)

android-studio-2022.3.1.22-linux.tar.gz

1.2 GB

b2cb395a154eb25a36b6e43544569fbc704e466c86966ea0ee4ac4900b4112c9

ChromeOS

android-studio-2022.3.1.22-cros.deb

933.8 MB

377bd2a3037f08d0b7f7d57d3e9ca726dac226a6cf14c39c86a4e262cdea7e9e

More downloads are available in the download archives. For Android Emulator downloads, see the Emulator download archives.

Platform

SDK tools package

Size

SHA-256 checksum

Windows

commandlinetools-win-10406996_latest.zip

148.8 MB

9b782a54d246ba5d207110fddd1a35a91087a8aaf4057e9df697b1cbc0ef60fc

Mac

commandlinetools-mac-10406996_latest.zip

148.8 MB

6821609e885d4b68f4066751949a9211f4196ab36df9d63f7a5f9037ca64e2d6

Linux

commandlinetools-linux-10406996_latest.zip

148.8 MB

8919e8752979db73d8321e9babe2caedcc393750817c1a5f56c128ec442fb540

Command-line tools are included in Android Studio. If you do not need Android Studio, you can download the basic Android command-line tools above. You can use the included sdkmanager to download other SDK packages.

# data[].attributes.attachment_link.title
Download Android Studio & App Tools - Android Developers

# data[].attributes.attachment_link.description
Android Studio provides app builders with an integrated development environment (IDE) optimized for Android apps. Download Android Studio today.

# data[].attributes.attachment_link.description
Want to get started in design, but don't know where to begin? These lessons and exercises will help you start designing immediately.

# data[].attributes.attachment_link.description
Modern JavaScript Tutorial: simple, but detailed explanations with examples and tasks, including: closures, document and events, object oriented programming and more.

# data[].attributes.attachment_link.description
Get the latest cheat sheet for all-things TypeScript, including common functions, types, directives and more. Read on for complete info.

# data[].attributes.attachment_link.description
Variables · Functions · Interpolation · Brace expansions · Loops · Conditional execution · Command substitution · One-page guide to Bash scripting

# data[].attributes.attachment_link.readable_text
Ionic Framework is an open source UI toolkit for building performant, high-quality mobile and desktop apps using web technologies - HTML, CSS, and JavaScript - with integrations for popular frameworks like Angular and React.

Get started building by installing Ionic or following our First App Tutorial to learn the main concepts.

Ionic Framework focuses on the frontend UX and UI interaction of an app - UI controls, interactions, gestures, animations. It's easy to learn, and integrates with other libraries or frameworks, such as Angular, React, or Vue. Alternatively, it can be used standalone without any frontend framework using a simple script include. If you'd like to learn more about Ionic Framework before diving in, we created a video to walk you through the basics.

Ionic is the only mobile app stack that enables web developers to build apps for all major app stores and the mobile web from a single codebase. And with Adaptive Styling, Ionic apps look and feel at home on every device.

Ionic is built to perform and behave great on the latest mobile devices with best practices like efficient hardware accelerated transitions, and touch-optimized gestures.

Ionic is designed to work and display beautifully on all current mobile devices and platforms. With ready-made components, typography, and a gorgeous (yet extensible) base theme that adapts to each platform, you'll be building in style.

Ionic emulates native app UI guidelines and uses native SDKs, bringing the UI standards and device features of native apps together with the full power and flexibility of the open web. Ionic uses Capacitor (or Cordova) to deploy natively, or runs in the browser as a Progressive Web App.

Build and deploy apps that work across multiple platforms, such as native iOS, Android, desktop, and the web as a Progressive Web App - all with one code base. Write once, run anywhere.

Ionic Framework is built on top of reliable, standardized web technologies: HTML, CSS, and JavaScript, using modern Web APIs such as Custom Elements and Shadow DOM. Because of this, Ionic components have a stable API, and aren't at the whim of a single platform vendor.

Clean, simple, and functional. Ionic Framework is designed to work and display beautifully out-of-the-box across all platforms. Start with pre-designed components, typography, interactive paradigms, and a gorgeous (yet extensible) base theme.

Ionic Framework is built with simplicity in mind, so that creating Ionic apps is enjoyable, easy to learn, and accessible to just about anyone with web development skills.

While past releases of Ionic were tightly coupled to Angular, version 4.x of the framework was re-engineered to work as a standalone Web Component library, with integrations for the latest JavaScript frameworks, like Angular. Ionic can be used in most frontend frameworks with success, including React and Vue, though some frameworks need a shim for full Web Component support.

One of the main goals with moving Ionic Framework to Web Components was to remove any hard requirement on a single framework to host the components. This made it possible for the core components to work standalone in a web page with just a script tag. While working with frameworks can be great for larger teams and larger apps, it is now possible to use Ionic as a standalone library in a single page even in a context like WordPress.

Angular has always been at the center of what makes Ionic great. While the core components have been written to work as a standalone Web Component library, the @ionic/angular package makes integration with the Angular ecosystem a breeze.@ionic/angular includes all the functionality that Angular developers would expect coming from Ionic 2/3, and integrates with core Angular libraries, like the Angular router.

Ionic now has official support for the popular React library. Ionic React lets React developers use their existing web skills to build apps that target iOS, Android, the web, and the desktop. With @ionic/react, you can use all the core Ionic components, but in a way that feels like using native React components.

Support for other frameworks are expected in a future release. Currently official bindings for Vue are in development, though some components just work out of the box in those frameworks.

The official , or Command Line Interface, is a tool that quickly scaffolds Ionic apps and provides a number of helpful commands to Ionic developers. In addition to installing and updating Ionic, the CLI comes with a built-in development server, build and debugging tools, and much more. If you are an Ionic Appflow member, the CLI can be used to perform cloud builds and deployments, and administer your account.

To help build, deploy, and manage Ionic apps throughout their lifecycle, we offer a commercial service for production apps called Ionic Appflow, which is separate from the open source Framework.

Appflow helps developers and teams compile native app builds and deploy live code updates to Ionic apps from a centralized dashboard. Optional paid upgrades are available for more advanced capabilities like publishing directly to app stores, workflow automation, single sign-on (SSO) and access to connected services and integrations.

Appflow requires an Ionic Account and comes with a free "Hobby" plan for those interested in playing around with some of its features.

Ionic Framework is actively developed and maintained full-time by a core team, and its ecosystem is guided by an international community of developers and contributors fueling its growth and adoption. Developers and companies small and large use Ionic to build and ship amazing apps that run everywhere.

There are millions of Ionic developers in over 200 countries worldwide. Here are some ways to join:

Forum: A great place for asking questions and sharing ideas.

Slack: A lively place for devs to meet and chat in real time.

Twitter: Where we post updates and share content from the Ionic community.

GitHub: For reporting bugs or requesting new features, create an issue here. PRs welcome!

Content authoring: Write a technical blog or share your story with the Ionic community.

Ionic Framework is a free and open source project, released under the permissable MIT license. This means it can be used in personal or commercial projects for free. MIT is the same license used by such popular projects as jQuery and Ruby on Rails.

This documentation content (found in the ionic-docs repo) is licensed under the Apache 2 license.

# data[].attributes.attachment_link.description
Ionic is the app platform for web developers. Build amazing mobile, web, and desktop apps all with one shared code base and open web standards

# data[].attributes.attachment_link.readable_text
There's a lot of outdated information on the Web that leads new PHP users astray, propagating bad practices and insecure code. PHP: The Right Way is an easy-to-read, quick reference for PHP popular coding standards, links to authoritative tutorials around the Web and what the contributors consider to be best practices at the present time.

There is no canonical way to use PHP. This website aims to introduce new PHP developers to some topics which they may not discover until it is too late, and aims to give seasoned pros some fresh ideas on those topics they've been doing for years without ever reconsidering. This website will also not tell you which tools to use, but instead offer suggestions for multiple options, when possible explaining the differences in approach and use-case.

This is a living document and will continue to be updated with more helpful information and examples as they become available.

Translations

PHP: The Right Way is translated into many different languages:

Book

The most recent version of PHP: The Right Way is also available in PDF, EPUB and MOBI formats. Go to Leanpub

How to Contribute

Help make this website the best resource for new PHP programmers! Contribute on GitHub

Use the Current Stable Version (8.0)

If you are getting started with PHP, start with the current stable release of PHP 8.0. PHP 8.x adds many new features over the older 7.x and 5.x versions. The engine has been largely re-written, and PHP is now even quicker than older versions. PHP 8.0 is a major update of the language and contains many new features and optimizations.

Built-in web server

With PHP 5.4 or newer, you can start learning PHP without installing and configuring a full-fledged web server. To start the server, run the following command from your terminal in your project's web root:

Mac Setup

macOS comes prepackaged with PHP but it is normally a little behind the latest stable release. There are multiple ways to install the latest PHP version on macOS.

Install PHP via Homebrew

Homebrew is a package manager for macOS that helps you easily install PHP and various extensions. The Homebrew core repository provides "formulae" for PHP 5.6, 7.0, 7.1, 7.2, 7.3, 7.4, and PHP 8.0. Install the latest version with this command:

You can switch between Homebrew PHP versions by modifying your PATH variable. Alternatively, you can use brew-php-switcher to switch PHP versions automatically.

Install PHP via Macports

The MacPorts Project is an open-source community initiative to design an easy-to-use system for compiling, installing, and upgrading either command-line, X11 or Aqua based open-source software on the OS X operating system.

MacPorts supports pre-compiled binaries, so you don't need to recompile every dependency from the source tarball files, it saves your life if you don't have any package installed on your system.

At this point, you can install php54, php55, php56, php70, php71, php72, php73, php74 or php80 using the port install command, for example:

And you can run select command to switch your active PHP:

Install PHP via phpbrew

phpbrew is a tool for installing and managing multiple PHP versions. This can be really useful if two different applications/projects require different versions of PHP, and you are not using virtual machines.

Install PHP via Liip's binary installer

Another popular option is php-osx.liip.ch which provides one liner installation methods for versions 5.3 through 7.3. It doesn't overwrite the PHP binaries installed by Apple, but installs everything in a separate location (/usr/local/php5).

Compile from Source

All-in-One Installers

The solutions listed above mainly handle PHP itself, and do not supply things like Apache, Nginx or a SQL server. "All-in-one" solutions such as MAMP and XAMPP will install these other bits of software for you and tie them all together, but ease of setup comes with a trade-off of flexibility.

Windows Setup

You can download the binaries from windows.php.net/download. After the extraction of PHP, it is recommended to set the PATH to the root of your PHP folder (where php.exe is located) so you can execute PHP from anywhere.

For learning and local development, you can use the built in webserver with PHP 5.4+ so you don't need to worry about configuring it. If you would like an "all-in-one" which includes a full-blown webserver and MySQL too then tools such as the Web Platform Installer, XAMPP, EasyPHP, OpenServer and WAMP will help get a Windows development environment up and running fast. That said, these tools will be a little different from production so be careful of environment differences if you are working on Windows and deploying to Linux.

If you need to run your production system on Windows, then IIS7 will give you the most stable and best performance. You can use phpmanager (a GUI plugin for IIS7) to make configuring and managing PHP simple. IIS7 comes with FastCGI built in and ready to go, you just need to configure PHP as a handler. For support and additional resources there is a dedicated area on iis.net for PHP.

Generally running your application on different environment in development and production can lead to strange bugs popping up when you go live. If you are developing on Windows and deploying to Linux (or anything non-Windows) then you should consider using a Virtual Machine.

Chris Tankersley has a very helpful blog post on what tools he uses to do PHP development using Windows.

Common Directory structure

A common question among those starting out with writing programs for the web is, "where do I put my stuff?" Over the years, this answer has consistently been "where the DocumentRoot is." Although this answer is not complete, it's a great place to start.

For security reasons, configuration files should not be accessible by a site's visitors; therefore, public scripts are kept in a public directory and private configurations and data are kept outside of that directory.

For each team, CMS, or framework one works in, a standard directory structure is used by each of those entities. However, if one is starting a project alone, knowing which filesystem structure to use can be daunting.

Paul M. Jones has done some fantastic research into common practices of tens of thousands of github projects in the realm of PHP. He has compiled a standard file and directory structure, the Standard PHP Package Skeleton, based on this research. In this directory structure, DocumentRoot should point to public/, unit tests should be in the tests/ directory, and third party libraries, as installed by composer, belong in the vendor/ directory. For other files and directories, abiding by the Standard PHP Package Skeleton will make the most sense to contributors of a project.

The PHP community is large and diverse, composed of innumerable libraries, frameworks, and components. It is common for PHP developers to choose several of these and combine them into a single project. It is important that PHP code adhere (as close as possible) to a common code style to make it easy for developers to mix and match various libraries for their projects.

The Framework Interop Group has proposed and approved a series of style recommendations. Not all of them related to code-style, but those that do are PSR-1, PSR-12 and PSR-4. These recommendations are merely a set of rules that many projects like Drupal, Zend, Symfony, Laravel, CakePHP, phpBB, AWS SDK, FuelPHP, Lithium, etc are adopting. You can use them for your own projects, or continue to use your own personal style.

Ideally, you should write PHP code that adheres to a known standard. This could be any combination of PSRs, or one of the coding standards made by PEAR or Zend. This means other developers can easily read and work with your code, and applications that implement the components can have consistency even when working with lots of third-party code.

You can use PHP_CodeSniffer to check code against any one of these recommendations, and plugins for text editors like Sublime Text to be given real-time feedback.

You can fix the code layout automatically by using one of the following tools:

And you can run phpcs manually from shell:

It will show errors and describe how to fix them. It can also be helpful to include this command in a git hook. That way, branches which contain violations against the chosen standard cannot enter the repository until those violations have been fixed.

If you have PHP_CodeSniffer, then you can fix the code layout problems reported by it, automatically, with the PHP Code Beautifier and Fixer.

Another option is to use the PHP Coding Standards Fixer. It will show which kind of errors the code structure had before it fixed them.

English is preferred for all symbol names and code infrastructure. Comments may be written in any language easily readable by all current and future parties who may be working on the codebase.

Finally, a good supplementary resource for writing clean PHP code is Clean Code PHP.

Programming Paradigms

PHP is a flexible, dynamic language that supports a variety of programming techniques. It has evolved dramatically over the years, notably adding a solid object-oriented model in PHP 5.0 (2004), anonymous functions and namespaces in PHP 5.3 (2009), and traits in PHP 5.4 (2012).

Object-oriented Programming

PHP has a very complete set of object-oriented programming features including support for classes, abstract classes, interfaces, inheritance, constructors, cloning, exceptions, and more.

Functional Programming

PHP supports first-class functions, meaning that a function can be assigned to a variable. Both user-defined and built-in functions can be referenced by a variable and invoked dynamically. Functions can be passed as arguments to other functions (a feature called Higher-order Functions) and functions can return other functions.

Recursion, a feature that allows a function to call itself, is supported by the language, but most PHP code is focused on iteration.

New anonymous functions (with support for closures) are present since PHP 5.3 (2009).

PHP 5.4 added the ability to bind closures to an object's scope and also improved support for callables such that they can be used interchangeably with anonymous functions in almost all cases.

PHP supports various forms of meta-programming through mechanisms like the Reflection API and Magic Methods. There are many Magic Methods available like __get(), __set(), __clone(), __toString(), __invoke(), etc. that allow developers to hook into class behavior. Ruby developers often say that PHP is lacking method_missing, but it is available as__call() and __callStatic().

Namespaces

As mentioned above, the PHP community has a lot of developers creating lots of code. This means that one library's PHP code might use the same class name as another. When both libraries are used in the same namespace, they collide and cause trouble.

Namespaces solve this problem. As described in the PHP reference manual, namespaces may be compared to operating system directories that namespace files; two files with the same name may co-exist in separate directories. Likewise, two PHP classes with the same name may co-exist in separate PHP namespaces. It's as simple as that.

It is important for you to namespace your code so that it may be used by other developers without fear of colliding with other libraries.

One recommended way to use namespaces is outlined in PSR-4, which aims to provide a standard file, class and namespace convention to allow plug-and-play code.

In October 2014 the PHP-FIG deprecated the previous autoloading standard: PSR-0. Both PSR-0 and PSR-4 are still perfectly usable. The latter requires PHP 5.3, so many PHP 5.2-only projects implement PSR-0.

If you're going to use an autoloader standard for a new application or package, look into PSR-4.

Standard PHP Library

The Standard PHP Library (SPL) is packaged with PHP and provides a collection of classes and interfaces. It is made up primarily of commonly needed datastructure classes (stack, queue, heap, and so on), and iterators which can traverse over these datastructures or your own classes which implement SPL interfaces.

Command Line Interface

PHP was created to write web applications, but is also useful for scripting command line interface (CLI) programs. Command line PHP programs can help automate common tasks like testing, deployment, and application administration.

CLI PHP programs are powerful because you can use your app's code directly without having to create and secure a web GUI for it. Just be sure not to put your CLI PHP scripts in your public web root!

Try running PHP from your command line:

The -i option will print your PHP configuration just like the function.

The -a option provides an interactive shell, similar to ruby's IRB or python's interactive shell. There are a number of other useful command line options, too.

Let's write a simple "Hello, $name" CLI program. To try it out, create a file named hello.php, as below.

PHP sets up two special variables based on the arguments your script is run with. is an integer variable containing the argument count and is an array variable containing each argument's value. The first argument is always the name of your PHP script file, in this case hello.php.

The exit() expression is used with a non-zero number to let the shell know that the command failed. Commonly used exit codes can be found here.

To run our script, above, from the command line:

Xdebug

One of the most useful tools in software development is a proper debugger. It allows you to trace the execution of your code and monitor the contents of the stack. Xdebug, PHP's debugger, can be utilized by various IDEs to provide Breakpoints and stack inspection. It can also allow tools like PHPUnit and KCacheGrind to perform code coverage analysis and code profiling.

If you find yourself in a bind, willing to resort to var_dump()/ print_r(), and you still can't find the solution - maybe you need to use the debugger.

Installing Xdebug can be tricky, but one of its most important features is "Remote Debugging" - if you develop code locally and then test it inside a VM or on another server, Remote Debugging is the feature that you will want to enable right away.

Traditionally, you will modify your Apache VHost or .htaccess file with these values:

The "remote host" and "remote port" will correspond to your local computer and the port that you configure your IDE to listen on. Then it's just a matter of putting your IDE into "listen for connections" mode, and loading the URL:

Your IDE will now intercept the current state as the script executes, allowing you to set breakpoints and probe the values in memory.

Graphical debuggers make it very easy to step through code, inspect variables, and eval code against the live runtime. Many IDE's have built-in or plugin-based support for graphical debugging with Xdebug. MacGDBp is a free, open-source, stand-alone Xdebug GUI for Mac.

There are a ton of PHP libraries, frameworks, and components to choose from. Your project will likely use several of them - these are project dependencies. Until recently, PHP did not have a good way to manage these project dependencies. Even if you managed them manually, you still had to worry about autoloaders. That is no longer an issue.

Currently there are two major package management systems for PHP - Composer and PEAR. Composer is currently the most popular package manager for PHP, however for a long time PEAR was the primary package manager in use. Knowing PEAR's history is a good idea, since you may still find references to it even if you never use it.

Composer and Packagist

Composer is the recommended dependency manager for PHP. List your project's dependencies in a composer.json file and, with a few simple commands, Composer will automatically download your project's dependencies and setup autoloading for you. Composer is analogous to NPM in the node.js world, or Bundler in the Ruby world.

There is a plethora of PHP libraries that are compatible with Composer and ready to be used in your project. These "packages" are listed on Packagist, the official repository for Composer-compatible PHP libraries.

How to Install Composer

The safest way to download composer is by following the official instructions. This will verify the installer is not corrupt or tampered with. The installer installs a composer.phar binary in your current working directory.

We recommend installing Composer globally (e.g. a single copy in /usr/local/bin). To do so, run this command next:

Note: If the above fails due to permissions, prefix with sudo.

To run a locally installed Composer you'd use php composer.phar, globally it's simply composer.

Installing on Windows

For Windows users the easiest way to get up and running is to use the ComposerSetup installer, which performs a global install and sets up your$PATH so that you can just call composer from any directory in your command line.

How to Define and Install Dependencies

Composer keeps track of your project's dependencies in a file called composer.json. You can manage it by hand if you like, or use Composer itself. The composer require command adds a project dependency and if you don't have a composer.json file, one will be created. Here's an example that adds Twig as a dependency of your project.

Next, add this line to your application's primary PHP file; this will tell PHP to use Composer's autoloader for your project dependencies.

Now you can use your project dependencies, and they'll be autoloaded on demand.

Updating your dependencies

Composer creates a file called composer.lock which stores the exact version of each package it downloaded when you first ran composer install. If you share your project with others, ensure the composer.lock file is included, so that when they run composer install they'll get the same versions as you. To update your dependencies, run composer update. Don't use composer update when deploying, only composer install, otherwise you may end up with different package versions on production.

This is most useful when you define your version requirements flexibly. For instance, a version requirement of ~1.8 means "anything newer than 1.8.0, but less than 2.0.x-dev". You can also use the* wildcard as in 1.8.*. Now Composer's composer update command will upgrade all your dependencies to the newest version that fits the restrictions you define.

To receive notifications about new version releases you can sign up for libraries.io, a web service that can monitor dependencies and send you alerts on updates.

Checking your dependencies for security issues

The Local PHP Security Checker is a command-line tool, which will examine your composer.lock file and tell you if you need to update any of your dependencies.

Handling global dependencies with Composer

Composer can also handle global dependencies and their binaries. Usage is straight-forward, all you need to do is prefix your command with global. If for example you wanted to install PHPUnit and have it available globally, you'd run the following command:

PEAR

A veteran package manager that some PHP developers enjoy is PEAR. It behaves similarly to Composer, but has some notable differences.

PEAR requires each package to have a specific structure, which means that the author of the package must prepare it for usage with PEAR. Using a project which was not prepared to work with PEAR is not possible.

PEAR installs packages globally, which means after installing them once they are available to all projects on that server. This can be good if many projects rely on the same package with the same version but might lead to problems if version conflicts between two projects arise.

How to install PEAR

You can install PEAR by downloading the .phar installer and executing it. The PEAR documentation has detailed install instructions for every operating system.

If you are using Linux, you can also have a look at your distribution package manager. Debian and Ubuntu, for example, have an apt php-pear package.

How to install a package

If the package is listed on the PEAR packages list, you can install it by specifying the official name:

If the package is hosted on another channel, you need to discover the channel first and also specify it when installing. See the Using channel docs for more information on this topic.

Handling PEAR dependencies with Composer

If you are already using Composer and you would like to install some PEAR code too, you can use Composer to handle your PEAR dependencies. This example will install code from pear2.php.net:

The first section "repositories" will be used to let Composer know it should "initialize" (or "discover" in PEAR terminology) the pear repo. Then the require section will prefix the package name like this:

pear-channel/Package

The "pear" prefix is hardcoded to avoid any conflicts, as a pear channel could be the same as another packages vendor name for example, then the channel short name (or full URL) can be used to reference which channel the package is in.

When this code is installed it will be available in your vendor directory and automatically available through the Composer autoloader:

vendor/pear-pear2.php.net/PEAR2_HTTP_Request/pear2/HTTP/Request.php

To use this PEAR package simply reference it like so:

The Basics

PHP is a vast language that allows coders of all levels the ability to produce code not only quickly, but efficiently. However, while advancing through the language, we often forget the basics that we first learnt (or overlooked) in favor of short cuts and/or bad habits. To help combat this common issue, this section is aimed at reminding coders of the basic coding practices within PHP.

Design Patterns

When you are building your application it is helpful to use common patterns in your code and common patterns for the overall structure of your project. Using common patterns is helpful because it makes it much easier to manage your code and lets other developers quickly understand how everything fits together.

If you use a framework then most of the higher level code and project structure will be based on that framework, so a lot of the pattern decisions are made for you. But it is still up to you to pick out the best patterns to follow in the code you build on top of the framework. If, on the other hand, you are not using a framework to build your application then you have to find the patterns that best suit the type and size of application that you're building.

You can learn more about PHP design patterns and see working examples at:
https://designpatternsphp.readthedocs.io/

Working with UTF-8

This section was originally written by Alex Cabal over atPHP Best Practices and has been used as the basis for our own UTF-8 advice.

There's no one-liner. Be careful, detailed, and consistent.

Right now PHP does not support Unicode at a low level. There are ways to ensure that UTF-8 strings are processed OK, but it's not easy, and it requires digging in to almost all levels of the web app, from HTML to SQL to PHP. We'll aim for a brief, practical summary.

UTF-8 at the PHP level

The basic string operations, like concatenating two strings and assigning strings to variables, don't need anything special for UTF-8. However, most string functions, like strpos() and strlen(), do need special consideration. These functions often have an mb_* counterpart: for example, mb_strpos() and mb_strlen(). These mb_* strings are made available to you via the Multibyte String Extension, and are specifically designed to operate on Unicode strings.

The hard part is remembering to use the mb_* functions at all times. If you forget even just once, your Unicode string has a chance of being garbled during further processing.

Not all string functions have an mb_* counterpart. If there isn't one for what you want to do, then you might be out of luck.

You should use the mb_internal_encoding() function at the top of every PHP script you write (or at the top of your global include script), and the mb_http_output() function right after it if your script is outputting to a browser. Explicitly defining the encoding of your strings in every script will save you a lot of headaches down the road.

Finally, If you are building a distributed application and cannot be certain that the mbstring extension will be enabled, then consider using the patchwork/utf8 Composer package. This will use mbstring if it is available, and fall back to non UTF-8 functions if not.

UTF-8 at the Database level

If your PHP script accesses MySQL, there's a chance your strings could be stored as non-UTF-8 strings in the database even if you follow all of the precautions above.

To make sure your strings go from PHP to MySQL as UTF-8, make sure your database and tables are all set to the utf8mb4 character set and collation, and that you use the utf8mb4 character set in the PDO connection string. See example code below. This is critically important.

Note that you must use the utf8mb4 character set for complete UTF-8 support, not the utf8 character set! See Further Reading for why.

UTF-8 at the browser level

Use the mb_http_output() function to ensure that your PHP script outputs UTF-8 strings to your browser.

The browser will then need to be told by the HTTP response that this page should be considered as UTF-8. Today, it is common to set the character set in the HTTP response header like this:

The historic approach to doing that was to include the charset <meta> tag in your page's <head> tag.

Further reading

Internationalization (i18n) and Localization (l10n)
Disclaimer for newcomers: i18n and l10n are numeronyms, a kind of abbreviation where numbers are used to shorten words - in our case, internationalization becomes i18n and localization, l10n.
First of all, we need to define those two similar concepts and other related things:

Internationalization is when you organize your code so it can be adapted to different languages or regions without refactorings. This action is usually done once - preferably, at the beginning of the project, or else you will probably need some huge changes in the source!

Localization happens when you adapt the interface (mainly) by translating contents, based on the i18n work done before. It usually is done every time a new language or region needs support and is updated when new interface pieces are added, as they need to be available in all supported languages.

Pluralization defines the rules required between distinct languages to interoperate strings containing numbers and counters. For instance, in English when you have only one item, it is singular, and anything different from that is called plural; plural in this language is indicated by adding an S after some words, and sometimes changes parts of it. In other languages, such as Russian or Serbian, there are two plural forms in addition to the singular - you may even find languages with a total of four, five or six forms, such as Slovenian, Irish or Arabic.

Common ways to implement

The easiest way to internationalize PHP software is by using array files and using those strings in templates, such as <h1><?=$TRANS['title_about_page']?></h1>. This way is, however, hardly recommended for serious projects, as it poses some maintenance issues along the road - some might appear in the very beginning, such as pluralization. So, please, don't try this if your project will contain more than a couple of pages.

The most classic way and often taken as reference for i18n and l10n is a Unix tool called gettext. It dates back to 1995 and is still a complete implementation for translating software. It is easy enough to get running, while still sporting powerful supporting tools. It is about Gettext we will be talking here. Also, to help you not get messy over the command-line, we will be presenting a great GUI application that can be used to easily update your l10n source

Other tools

There are common libraries used that support Gettext and other implementations of i18n. Some of them may seem easier to install or sport additional features or i18n file formats. In this document, we focus on the tools provided with the PHP core, but here we list others for completion:

aura/intl: Provides internationalization (I18N) tools, specifically package-oriented per-locale message translation. It uses array formats for message. Does not provide a message extractor, but does provide advanced message formatting via theintl extension (including pluralized messages).

oscarotero/Gettext: Gettext support with an OO interface; includes improved helper functions, powerful extractors for several file formats (some of them not supported natively by thegettext command), and can also export to other formats besides.mo/.po files. Can be useful if you need to integrate your translation files into other parts of the system, like a JavaScript interface.

symfony/translation: supports a lot of different formats, but recommends using verbose XLIFF's. Doesn't include helper functions nor a built-in extractor, but supports placeholders usingstrtr() internally.

zend/i18n: supports array and INI files, or Gettext formats. Implements a caching layer to save you from reading the filesystem every time. It also includes view helpers, and locale-aware input filters and validators. However, it has no message extractor.

Other frameworks also include i18n modules, but those are not available outside of their codebases:

Laravel supports basic array files, has no automatic extractor but includes a @lang helper for template files.

Yii supports array, Gettext, and database-based translation, and includes a messages extractor. It is backed by the extension, available since PHP 5.3, and based on theICU project; this enables Yii to run powerful replacements, like spelling out numbers, formatting dates, times, intervals, currency, and ordinals.

If you decide to go for one of the libraries that provide no extractors, you may want to use the gettext formats, so you can use the original gettext toolchain (including Poedit) as described in the rest of the chapter.

Gettext

Installation

Here we will also be using Poedit to create translation files. You will probably find it in your system's package manager; it is available for Unix, Mac, and Windows, and can be downloaded for free on their website as well.

Structure

Types of files

There are three files you usually deal with while working with gettext. The main ones are PO (Portable Object) and MO (Machine Object) files, the first being a list of readable "translated objects" and the second, the corresponding binary to be interpreted by gettext when doing localization. There's also a POT (Template) file, which simply contains all existing keys from your source files, and can be used as a guide to generate and update all PO files. Those template files are not mandatory: depending on the tool you are using to do l10n, you can go just fine with only PO/MO files. You will always have one pair of PO/MO files per language and region, but only one POT per domain.

Domains

There are some cases, in big projects, where you might need to separate translations when the same words convey different meaning given a context. In those cases, you split them into different domains. They are, basically, named groups of POT/PO/MO files, where the filename is the said translation domain. Small and medium-sized projects usually, for simplicity, use only one domain; its name is arbitrary, but we will be using "main" for our code samples. In Symfony projects, for example, domains are used to separate the translation for validation messages.

Locale code

For some speakers, the country part may seem redundant. In fact, some languages have dialects in different countries, such as Austrian German ( de_AT) or Brazilian Portuguese ( pt_BR). The second part is used to distinguish between those dialects - when it is not present, it is taken as a "generic" or "hybrid" version of the language.

Directory structure

To use Gettext, we will need to adhere to a specific structure of folders. First, you will need to select an arbitrary root for your l10n files in your source repository. Inside it, you will have a folder for each needed locale, and a fixed LC_MESSAGES folder that will contain all your PO/MO pairs. Example:

Plural forms

As we said in the introduction, different languages might sport different plural rules. However, gettext saves us from this trouble once again. When creating a new .po file, you will have to declare the plural rules for that language, and translated pieces that are plural-sensitive will have a different form for each of those rules. When calling Gettext in code, you will have to specify the number related to the sentence, and it will work out the correct form to use - even using string substitution if needed.

Plural rules include the number of plurals available and a boolean test with n that would define in which rule the given number falls (starting the count with 0). For example:

Japanese: nplurals=1; plural=0 - only one rule

English: nplurals=2; plural=(n != 1); - two rules, first if N is one, second rule otherwise

Brazilian Portuguese: nplurals=2; plural=(n > 1); - two rules, second if N is bigger than one, first otherwise

Now that you understood the basis of how plural rules works - and if you didn't, please look at a deeper explanation on the LingoHub tutorial -, you might want to copy the ones you need from a list instead of writing them by hand.

When calling out Gettext to do localization on sentences with counters, you will have to provide it the related number as well. Gettext will work out what rule should be in effect and use the correct localized version. You will need to include in the .po file a different sentence for each plural rule defined.

Sample implementation

After all that theory, let's get a little practical. Here's an excerpt of a .po file - don't mind with its format, but with the overall content instead; you will learn how to edit it easily later:

msgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" msgid "We are now translating some strings" msgstr "Nós estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Olá %1$s! Sua última visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "Só uma mensagem não lida" msgstr[1] "%d mensagens não lidas"

The first section works like a header, having the msgid and msgstr especially empty. It describes the file encoding, plural forms and other things that are less relevant. The second section translates a simple string from English to Brazilian Portuguese, and the third does the same, but leveraging string replacement from so the translation may contain the user name and visit date. The last section is a sample of pluralization forms, displaying the singular and plural version as msgid in English and their corresponding translations as msgstr 0 and 1 (following the number given by the plural rule). There, string replacement is used as well so the number can be seen directly in the sentence, by using%d. The plural forms always have two msgid (singular and plural), so it is advised not to use a complex language as the source of translation.

Discussion on l10n keys

As you might have noticed, we are using as source ID the actual sentence in English. That msgid is the same used throughout all your.po files, meaning other languages will have the same format and the same msgid fields but translated msgstr lines.

Talking about translation keys, there are two main "schools" here:

1. msgid as a real sentence. The main advantages are:

if there are pieces of the software untranslated in any given language, the key displayed will still maintain some meaning. Example: if you happen to translate by heart from English to Spanish but need help to translate to French, you might publish the new page with missing French sentences, and parts of the website would be displayed in English instead;

it is much easier for the translator to understand what's going on and do a proper translation based on the msgid;

it gives you "free" l10n for one language - the source one;

The only disadvantage: if you need to change the actual text, you would need to replace the same msgid across several language files.

2. msgid as a unique, structured key. It would describe the sentence role in the application in a structured way, including the template or part where the string is located instead of its content.

it is a great way to have the code organized, separating the text content from the template logic.

however, that could bring problems to the translator that would miss the context. A source language file would be needed as a basis for other translations. Example: the developer would ideally have an en.po file, that translators would read to understand what to write infr.po for instance.

missing translations would display meaningless keys on screen (top_menu.welcome instead of Hello there, User! on the said untranslated French page). That is good it as would force translation to be complete before publishing - however, bad as translation issues would be remarkably awful in the interface. Some libraries, though, include an option to specify a given language as "fallback", having a similar behavior as the other approach.

The Gettext manual favors the first approach as, in general, it is easier for translators and users in case of trouble. That is how we will be working here as well. However, the Symfony documentation favors keyword-based translation, to allow for independent changes of all translations without affecting templates as well.

Everyday usage

In a typical application, you would use some Gettext functions while writing static text in your pages. Those sentences would then appear in .po files, get translated, compiled into .mo files and then, used by Gettext when rendering the actual interface. Given that, let's tie together what we have discussed so far in a step-by-step example:

1. A sample template file, including some different gettext calls

simply translates a msgid into its corresponding msgstr for a given language. There's also the shorthand function_() that works the same way;

does the same but with plural rules;

there's also and , that allows you to override the domain for a single call. More on domain configuration in the next example.

2. A sample setup file (i18n_setup.php as used above), selecting the correct locale and configuring Gettext

3. Preparing translation for the first run

One of the great advantages Gettext has over custom framework i18n packages is its extensive and powerful file format. "Oh man, that's quite hard to understand and edit by hand, a simple array would be easier!" Make no mistake, applications like Poedit are here to help - a lot. You can get the program from their website, it's free and available for all platforms. It's a pretty easy tool to get used to, and a very powerful one at the same time - using all features Gettext has available. This guide is based on PoEdit 1.8.

In the first run, you should select "File > New..." from the menu. You'll be asked straight ahead for the language: here you can select/filter the language you want to translate to, or use that format we mentioned before, such as en_US or pt_BR.

Now, save the file - using that directory structure we mentioned as well. Then you should click "Extract from sources", and here you'll configure various settings for the extraction and translation tasks. You'll be able to find all those later through "Catalog > Properties":

Source paths: here you must include all folders from the project where gettext() (and siblings) are called - this is usually your templates/views folder(s). This is the only mandatory setting;

Translation properties:

Project name and version, Team and Team's email address: useful information that goes in the .po file header;

Plural forms: here go those rules we mentioned before - there's a link in there with samples as well. You can leave it with the default option most of the time, as PoEdit already includes a handy database of plural rules for many languages.

Charsets: UTF-8, preferably;

Source code charset: set here the charset used by your codebase - probably UTF-8 as well, right?

Source keywords: The underlying software knows how gettext() and similar function calls look like in several programming languages, but you might as well create your own translation functions. It will be here you'll add those other methods. This will be discussed later in the "Tips" section.

After setting those points it will run a scan through your source files to find all the localization calls. After every scan PoEdit will display a summary of what was found and what was removed from the source files. New entries will fed empty into the translation table, and you'll start typing in the localized versions of those strings. Save it and a .mo file will be (re)compiled into the same folder and ta-dah: your project is internationalized.

4. Translating strings

As you may have noticed before, there are two main types of localized strings: simple ones and those with plural forms. The first ones have simply two boxes: source and localized string. The source string cannot be modified as Gettext/Poedit do not include the powers to alter your source files - you should change the source itself and rescan the files. Tip: you may right-click a translation line and it will hint you with the source files and lines where that string is being used. On the other hand, plural form strings include two boxes to show the two source strings, and tabs so you can configure the different final forms.

Whenever you change your sources and need to update the translations, just hit Refresh and Poedit will rescan the code, removing non-existent entries, merging the ones that changed and adding new ones. It may also try to guess some translations, based on other ones you did. Those guesses and the changed entries will receive a "Fuzzy" marker, indicating it needs review, appearing golden in the list. It is also useful if you have a translation team and someone tries to write something they are not sure about: just mark Fuzzy, and someone else will review later.

Finally, it is advised to leave "View > Untranslated entries first" marked, as it will help you a lot to not forget any entry. From that menu, you can also open parts of the UI that allow you to leave contextual information for translators if needed.

Tips & Tricks

Possible caching issues

If you are running PHP as a module on Apache ( mod_php), you might face issues with the .mo file being cached. It happens the first time it is read, and then, to update it, you might need to restart the server. On Nginx and PHP5 it usually takes only a couple of page refreshes to refresh the translation cache, and on PHP7 it is rarely needed.

Additional helper functions

As preferred by many people, it is easier to use _() instead of gettext(). Many custom i18n libraries from frameworks use something similar to t() as well, to make translated code shorter. However, that is the only function that sports a shortcut. You might want to add in your project some others, such as__() or _n() for ngettext(), or maybe a fancy_r() that would join gettext() and sprintf() calls. Other libraries, such as oscarotero's Gettext also provide helper functions like these.

In those cases, you'll need to instruct the Gettext utility on how to extract the strings from those new functions. Don't be afraid; it is very easy. It is just a field in the .po file, or a Settings screen on Poedit. In the editor, that option is inside "Catalog > Properties > Source keywords". Remember: Gettext already knows the default functions for many languages, so don't be afraid if that list seems empty. You need to include there the specifications of those new functions, following a specific format:

if you create something like t() that simply returns the translation for a string, you can specify it as t. Gettext will know the only function argument is the string to be translated;

if the function has more than one argument, you can specify in which one the first string is - and if needed, the plural form as well. For instance, if we call our function like this: __('one user', '%d users', $number), the specification would be__:1,2, meaning the first form is the first argument, and the second form is the second argument. If your number comes as the first argument instead, the spec would be__:2,3, indicating the first form is the second argument, and so on.

After including those new rules in the .po file, a new scan will bring in your new strings just as easy as before.

References

From Wikipedia:

Dependency injection is a software design pattern that allows the removal of hard-coded dependencies and makes it possible to change them, whether at run-time or compile-time.

This quote makes the concept sound much more complicated than it actually is. Dependency Injection is providing a component with its dependencies either through constructor injection, method calls or the setting of properties. It is that simple.

Basic Concept

We can demonstrate the concept with a simple, yet naive example.

Here we have a Database class that requires an adapter to speak to the database. We instantiate the adapter in the constructor and create a hard dependency. This makes testing difficult and means the Database class is very tightly coupled to the adapter.

This code can be refactored to use Dependency Injection and therefore loosen the dependency.

Complex Problem

If you have ever read about Dependency Injection then you have probably seen the terms "Inversion of Control" or "Dependency Inversion Principle". These are the complex problems that Dependency Injection solves.

Inversion of Control

Inversion of Control is as it says, "inverting the control" of a system by keeping organizational control entirely separate from our objects. In terms of Dependency Injection, this means loosening our dependencies by controlling and instantiating them elsewhere in the system.

For years, PHP frameworks have been achieving Inversion of Control, however, the question became, which part of control are we inverting, and where to? For example, MVC frameworks would generally provide a super object or base controller that other controllers must extend to gain access to its dependencies. This is Inversion of Control, however, instead of loosening dependencies, this method simply moved them.

Dependency Injection allows us to more elegantly solve this problem by only injecting the dependencies we need, when we need them, without the need for any hard coded dependencies at all.

S.O.L.I.D.

Single Responsibility Principle

The Single Responsibility Principle is about actors and high-level architecture. It states that "A class should have only one reason to change." This means that every class should only have responsibility over a single part of the functionality provided by the software. The largest benefit of this approach is that it enables improved code reusability. By designing our class to do just one thing, we can use (or re-use) it in any other program without changing it.

Open/Closed Principle

The Open/Closed Principle is about class design and feature extensions. It states that "Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification." This means that we should design our modules, classes and functions in a way that when a new functionality is needed, we should not modify our existing code but rather write new code that will be used by existing code. Practically speaking, this means that we should write classes that implement and adhere to interfaces, then type-hint against those interfaces instead of specific classes.

The largest benefit of this approach is that we can very easily extend our code with support for something new without having to modify existing code, meaning that we can reduce QA time, and the risk for negative impact to the application is substantially reduced. We can deploy new code, faster, and with more confidence.

Liskov Substitution Principle

The Liskov Substitution Principle is about subtyping and inheritance. It states that "Child classes should never break the parent class' type definitions." Or, in Robert C. Martin's words, "Subtypes must be substitutable for their base types."

For example, if we have a FileInterface interface which defines an embed() method, and we have Audio and Video classes which both implement the FileInterface interface, then we can expect that the usage of the embed() method will always do the thing that we intend. If we later create a PDF class or a Gist class which implement the FileInterface interface, we will already know and understand what the embed() method will do. The largest benefit of this approach is that we have the ability to build flexible and easily-configurable programs, because when we change one object of a type (e.g., FileInterface) to another we don't need to change anything else in our program.

Interface Segregation Principle

The Interface Segregation Principle (ISP) is about business-logic-to-clients communication. It states that "No client should be forced to depend on methods it does not use." This means that instead of having a single monolithic interface that all conforming classes need to implement, we should instead provide a set of smaller, concept-specific interfaces that a conforming class implements one or more of.

For example, a Car or Bus class would be interested in a steeringWheel() method, but a Motorcycle or Tricycle class would not. Conversely, a Motorcycle or Tricycle class would be interested in a handlebars() method, but a Car or Bus class would not. There is no need to have all of these types of vehicles implement support for both steeringWheel() as well as handlebars(), so we should break-apart the source interface.

Dependency Inversion Principle

The Dependency Inversion Principle is about removing hard-links between discrete classes so that new functionality can be leveraged by passing a different class. It states that one should "Depend on Abstractions. Do not depend on concretions.". Put simply, this means our dependencies should be interfaces/contracts or abstract classes rather than concrete implementations. We can easily refactor the above example to follow this principle.

There are several benefits to the Database class now depending on an interface rather than a concretion.

Consider that we are working in a team and the adapter is being worked on by a colleague. In our first example, we would have to wait for said colleague to finish the adapter before we could properly mock it for our unit tests. Now that the dependency is an interface/contract we can happily mock that interface knowing that our colleague will build the adapter based on that contract.

An even bigger benefit to this method is that our code is now much more scalable. If a year down the line we decide that we want to migrate to a different type of database, we can write an adapter that implements the original interface and injects that instead, no more refactoring would be required as we can ensure that the adapter follows the contract set by the interface.

Containers

The first thing you should understand about Dependency Injection Containers is that they are not the same thing as Dependency Injection. A container is a convenience utility that helps us implement Dependency Injection, however, they can be and often are misused to implement an anti-pattern, Service Location. Injecting a DI container as a Service Locator in to your classes arguably creates a harder dependency on the container than the dependency you are replacing. It also makes your code much less transparent and ultimately harder to test.

Most modern frameworks have their own Dependency Injection Container that allows you to wire your dependencies together through configuration. What this means in practice is that you can write application code that is as clean and de- coupled as the framework it is built on.

Further Reading

Many times your PHP code will use a database to persist information. You have a few options to connect and interact with your database. The recommended option until PHP 5.1.0 was to use native drivers such as mysqli, pgsql, mssql, etc.

Native drivers are great if you are only using one database in your application, but if, for example, you are using MySQL and a little bit of MSSQL, or you need to connect to an Oracle database, then you will not be able to use the same drivers. You'll need to learn a brand new API for each database - and that can get silly.

MySQL Extension

The mysql extension for PHP is incredibly old and has been superseded by two other extensions:

Not only did development stop long ago on mysql, but it was deprecated as of PHP 5.5.0, and has been officially removed in PHP 7.0.

Even if you are not using PHP 7.x yet, failing to consider this upgrade as soon as possible will lead to greater hardship when the PHP 7.x upgrade does come about. The best option is to replace mysql usage with mysqli or PDO in your applications within your own development schedules so you won't be rushed later on.
If you are upgrading from mysql to mysqli, beware lazy upgrade guides that suggest you can simply find and replace mysql_* with mysqli_*. Not only is that a gross oversimplification, it misses out on the advantages that mysqli provides, such as parameter binding, which is also offered in PDO.

PDO Extension

PDO is a database connection abstraction library - built into PHP since 5.1.0 - that provides a common interface to talk with many different databases. For example, you can use basically identical code to interface with MySQL or SQLite:

PDO will not translate your SQL queries or emulate missing features; it is purely for connecting to multiple types of database with the same API.

More importantly, PDO allows you to safely inject foreign input (e.g. IDs) into your SQL queries without worrying about database SQL injection attacks. This is possible using PDO statements and bound parameters.

Let's assume a PHP script receives a numeric ID as a query parameter. This ID should be used to fetch a user record from a database. This is the wrong way to do this:

This is terrible code. You are inserting a raw query parameter into a SQL query. This will get you hacked in a heartbeat, using a practice called SQL Injection. Just imagine if a hacker passes in an inventive id parameter by calling a URL like http://domain.com/?id=1%3BDELETE+FROM+users. This will set the $_GET['id'] variable to 1;DELETE FROM users which will delete all of your users! Instead, you should sanitize the ID input using PDO bound parameters.

This is correct code. It uses a bound parameter on a PDO statement. This escapes the foreign input ID before it is introduced to the database preventing potential SQL injection attacks.

For writes, such as INSERT or UPDATE, it's especially critical to still filter your data first and sanitize it for other things (removal of HTML tags, JavaScript, etc). PDO will only sanitize it for SQL, not for your application.

You should also be aware that database connections use up resources and it was not unheard-of to have resources exhausted if connections were not implicitly closed, however this was more common in other languages. Using PDO you can implicitly close the connection by destroying the object by ensuring all remaining references to it are deleted, i.e. set to NULL. If you don't do this explicitly, PHP will automatically close the connection when your script ends - unless of course you are using persistent connections.

Interacting with Databases

When developers first start to learn PHP, they often end up mixing their database interaction up with their presentation logic, using code that might look like this:

This is bad practice for all sorts of reasons, mainly that it's hard to debug, hard to test, hard to read and it is going to output a lot of fields if you don't put a limit on there.

While there are many other solutions to doing this - depending on if you prefer OOP or functional programming - there must be some element of separation.

Consider the most basic step:

That is a good start. Put those two items in two different files and you've got some clean separation.

Create a class to place that method in and you have a "Model". Create a simple .php file to put the presentation logic in and you have a "View", which is very nearly MVC - a common OOP architecture for most frameworks.
foo.php models/FooModel.php views/foo-list.php
This is essentially the same as what most modern frameworks are doing, albeit a little more manual. You might not need to do all of that every time, but mixing together too much presentation logic and database interaction can be a real problem if you ever want to unit-test your application.

Abstraction Layers

Many frameworks provide their own abstraction layer which may or may not sit on top of PDO. These will often emulate features for one database system that is missing from another by wrapping your queries in PHP methods, giving you actual database abstraction instead of just the connection abstraction that PDO provides. This will of course add a little overhead, but if you are building a portable application that needs to work with MySQL, PostgreSQL and SQLite then a little overhead will be worth it for the sake of code cleanliness.

Some abstraction layers have been built using the PSR-0 or PSR-4 namespace standards so can be installed in any application you like:

Templates provide a convenient way of separating your controller and domain logic from your presentation logic. Templates typically contain the HTML of your application, but may also be used for other formats, such as XML. Templates are often referred to as "views", which make up part of the second component of the model-view-controller (MVC) software architecture pattern.

Benefits

The main benefit to using templates is the clear separation they create between the presentation logic and the rest of your application. Templates have the sole responsibility of displaying formatted content. They are not responsible for data lookup, persistence or other more complex tasks. This leads to cleaner, more readable code which is especially helpful in a team environment where developers work on the server-side code (controllers, models) and designers work on the client-side code (markup).

Templates also improve the organization of presentation code. Templates are typically placed in a "views" folder, each defined within a single file. This approach encourages code reuse where larger blocks of code are broken into smaller, reusable pieces, often called partials. For example, your site header and footer can each be defined as templates, which are then included before and after each page template.

Finally, depending on the library you use, templates can offer more security by automatically escaping user-generated content. Some libraries even offer sand-boxing, where template designers are only given access to white-listed variables and functions.

Plain PHP Templates

Plain PHP templates are simply templates that use native PHP code. They are a natural choice since PHP is actually a template language itself. That simply means that you can combine PHP code within other code, like HTML. This is beneficial to PHP developers as there is no new syntax to learn, they know the functions available to them, and their code editors already have PHP syntax highlighting and auto-completion built-in. Further, plain PHP templates tend to be very fast as no compiling stage is required.

Every modern PHP framework employs some kind of template system, most of which use plain PHP by default. Outside of frameworks, libraries like Plates or Aura.View make working with plain PHP templates easier by offering modern template functionality such as inheritance, layouts and extensions.

Simple example of a plain PHP template

Using the Plates library.

Example of plain PHP templates using inheritance

Using the Plates library.

Compiled Templates

While PHP has evolved into a mature, object oriented language, it hasn't improved much as a templating language. Compiled templates, like Twig, Brainy, or Smarty*, fill this void by offering a new syntax that has been geared specifically to templating. From automatic escaping, to inheritance and simplified control structures, compiled templates are designed to be easier to write, cleaner to read and safer to use. Compiled templates can even be shared across different languages, Mustache being a good example of this. Since these templates must be compiled there is a slight performance hit, however this is very minimal when proper caching is used.
*While Smarty offers automatic escaping, this feature is NOT enabled by default.
Simple example of a compiled template

Using the Twig library.

{% include 'header.html' with {'title': 'User Profile'} %} <h1>User Profile</h1> <p>Hello, {{ name }}</p> {% include 'footer.html' %}

Example of compiled templates using inheritance

Using the Twig library.

// template.html <html> <head> <title>{% block title %}{% endblock %}</title> </head> <body> <main> {% block content %}{% endblock %} </main> </body> </html>

// user_profile.html {% extends "template.html" %} {% block title %}User Profile{% endblock %} {% block content %} <h1>User Profile</h1> <p>Hello, {{ name }}</p> {% endblock %}

Further Reading

Articles & Tutorials

Libraries

Errors

In many "exception-heavy" programming languages, whenever anything goes wrong an exception will be thrown. This is certainly a viable way to do things, but PHP is an "exception-light" programming language. While it does have exceptions and more of the core is starting to use them when working with objects, most of PHP itself will try to keep processing regardless of what happens, unless a fatal error occurs.

For example:

This is only a notice error, and PHP will happily carry on. This can be confusing for those coming from "exception-heavy" languages, because referencing a missing variable in Python for example will throw an exception:

The only real difference is that Python will freak out over any small thing, so that developers can be super sure any potential issue or edge-case is caught, whereas PHP will keep on processing unless something extreme happens, at which point it will throw an error and report it.

Error Severity

Another type of error message reported at compile time are E_STRICT messages. These messages are used to suggest changes to your code to help ensure best interoperability and forward compatibility with upcoming versions of PHP.

Changing PHP's Error Reporting Behaviour

Error Reporting can be changed by using PHP settings and/or PHP function calls. Using the built in PHP function error_reporting() you can set the level of errors for the duration of the script execution by passing one of the predefined error level constants, meaning if you only want to see Errors and Warnings - but not Notices - then you can configure that:

You can also control whether or not errors are displayed to the screen (good for development) or hidden, and logged (good for production). For more information on this check out the Error Reporting section.

Inline Error Suppression

You can also tell PHP to suppress specific errors with the Error Control Operator @. You put this operator at the beginning of an expression, and any error that's a direct result of the expression is silenced.

This might seem like a good idea, but there are a few undesirable tradeoffs. PHP handles expressions using an @ in a less performant way than expressions without an@. Premature optimization may be the root of all programming arguments, but if performance is particularly important for your application/library it's important to understand the error control operator's performance implications.

Secondly, the error control operator completely swallows the error. The error is not displayed, and the error is not sent to the error log. Also, stock/production PHP systems have no way to turn off the error control operator. While you may be correct that the error you're seeing is harmless, a different, less harmless error will be just as silent.

If there's a way to avoid the error suppression operator, you should consider it. For example, our code above could be rewritten like this:

One instance where error suppression might make sense is where fopen() fails to find a file to load. You could check for the existence of the file before you try to load it, but if the file is deleted after the check and before the fopen() (which might sound impossible, but it can happen) then fopen() will return false and throw an error. This is potentially something PHP should resolve, but is one case where error suppression might seem like the only valid solution.

Earlier we mentioned there's no way in a stock PHP system to turn off the error control operator. However, Xdebug has an xdebug.scream ini setting which will disable the error control operator. You can set this via your php.ini file with the following.

You can also set this value at runtime with the ini_set function

The " Scream" PHP extension offers similar functionality to Xdebug's, although Scream's ini setting is named scream.enabled.

This is most useful when you're debugging code and suspect an informative error is suppressed. Use scream with care, and as a temporary debugging tool. There's lots of PHP library code that may not work with the error control operator disabled.

ErrorException

PHP is perfectly capable of being an "exception-heavy" programming language, and only requires a few lines of code to make the switch. Basically you can throw your "errors" as "exceptions" using the ErrorException class, which extends the Exception class.

This is a common practice implemented by a large number of modern frameworks such as Symfony and Laravel. In debug mode (or dev mode) both of these frameworks will display a nice and clean stack trace.

There are also some packages available for better error and exception handling and reporting. Like Whoops!, which comes with the default installation of Laravel and can be used in any framework as well.

By throwing errors as exceptions in development you can handle them better than the usual result, and if you see an exception during development you can wrap it in a catch statement with specific instructions on how to handle the situation. Each exception you catch instantly makes your application that little bit more robust.

More information on this and details on how to use ErrorException with error handling can be found at ErrorException Class.

Exceptions

Exceptions are a standard part of most popular programming languages, but they are often overlooked by PHP programmers. Languages like Ruby are extremely Exception heavy, so whenever something goes wrong such as a HTTP request failing, or a DB query goes wrong, or even if an image asset could not be found, Ruby (or the gems being used) will throw an exception to the screen meaning you instantly know there is a mistake.

Another problem is when classes automatically throw an error to the screen and exit the process. When you do this you stop another developer from being able to dynamically handle that error. Exceptions should be thrown to make a developer aware of an error; they then can choose how to handle this. E.g.:

SPL Exceptions

This means you can add multiple catch blocks and handle different Exceptions differently. This can lead to the creation of a lot of custom Exceptions, some of which could have been avoided using the SPL Exceptions provided in the SPL extension.

If for example you use the __call() Magic Method and an invalid method is requested then instead of throwing a standard Exception which is vague, or creating a custom Exception just for that, you could just throw new BadMethodCallException;.

The best resource I've found on PHP security is The 2018 Guide to Building Secure PHP Software by Paragon Initiative.

Web Application Security

It is very important for every PHP developer to learn the basics of web application security, which can be broken down into a handful of broad topics:

1. Code-data separation.

When data is executed as code, you get SQL Injection, Cross-Site Scripting, Local/Remote File Inclusion, etc.

When code is printed as data, you get information leaks (source code disclosure or, in the case of C programs, enough information to bypass ASLR).

2. Application logic.

Missing authentication or authorization controls.

Input validation.

3. Operating environment.

PHP versions.

Third party libraries.

The operating system.

4. Cryptography weaknesses.

There are bad people ready and willing to exploit your web application. It is important that you take necessary precautions to harden your web application's security. Luckily, the fine folks at The Open Web Application Security Project (OWASP) have compiled a comprehensive list of known security issues and methods to protect yourself against them. This is a must read for the security-conscious developer. Survive The Deep End: PHP Security by Padraic Brady is also another good web application security guide for PHP.

Password Hashing

Eventually everyone builds a PHP application that relies on user login. Usernames and passwords are stored in a database and later used to authenticate users upon login.

It is important that you properly passwords before storing them. Hashing and encrypting are two very different things that often get confused.

Hashing is an irreversible, one-way function. This produces a fixed-length string that cannot be feasibly reversed. This means you can compare a hash against another to determine if they both came from the same source string, but you cannot determine the original string. If passwords are not hashed and your database is accessed by an unauthorized third-party, all user accounts are now compromised.

Unlike hashing, encryption is reversible (provided you have the key). Encryption is useful in other areas, but is a poor strategy for securely storing passwords.

Passwords should also be individually by adding a random string to each password before hashing. This prevents dictionary attacks and the use of "rainbow tables" (a reverse list of crytographic hashes for common passwords.)

Hashing and salting are vital as often users use the same password for multiple services and password quality can be poor.

Additionally, you should use a specialized password hashing algorithm rather than fast, general-purpose cryptographic hash function (e.g. SHA256). The short list of acceptable password hashing algorithms (as of June 2018) to use are:

Argon2 (available in PHP 7.2 and newer)

Scrypt

Bcrypt (PHP provides this one for you; see below)

PBKDF2 with HMAC-SHA256 or HMAC-SHA512

Fortunately, nowadays PHP makes this easy.
Hashing passwords with password_hash
In PHP 5.5 password_hash() was introduced. At this time it is using BCrypt, the strongest algorithm currently supported by PHP. It will be updated in the future to support more algorithms as needed though. The password_compat library was created to provide forward compatibility for PHP >= 5.3.7.

Below we hash a string, and then check the hash against a new string. Because our two source strings are different ('secret-password' vs. 'bad-password') this login will fail.

password_hash() takes care of password salting for you. The salt is stored, along with the algorithm and "cost", as part of the hash. password_verify() extracts this to determine how to check the password, so you don't need a separate database field to store your salts.

Data Filtering

Never ever (ever) trust foreign input introduced to your PHP code. Always sanitize and validate foreign input before using it in code. The filter_var() and filter_input() functions can sanitize text and validate text formats (e.g. email addresses).

Foreign input can be anything: $_GET and $_POST form input data, some values in the $_SERVER superglobal, and the HTTP request body via fopen('php://input', 'r'). Remember, foreign input is not limited to form data submitted by the user. Uploaded and downloaded files, session values, cookie data, and data from third-party web services are foreign input, too.

While foreign data can be stored, combined, and accessed later, it is still foreign input. Every time you process, output, concatenate, or include data in your code, ask yourself if the data is filtered properly and can it be trusted.

Data may be filtered differently based on its purpose. For example, when unfiltered foreign input is passed into HTML page output, it can execute HTML and JavaScript on your site! This is known as Cross-Site Scripting (XSS) and can be a very dangerous attack. One way to avoid XSS is to sanitize all user-generated data before outputting it to your page by removing HTML tags with the strip_tags() function or escaping characters with special meaning into their respective HTML entities with the htmlentities() or htmlspecialchars() functions.

Another example is passing options to be executed on the command line. This can be extremely dangerous (and is usually a bad idea), but you can use the built-in escapeshellarg() function to sanitize the executed command's arguments.

One last example is accepting foreign input to determine a file to load from the filesystem. This can be exploited by changing the filename to a file path. You need to remove "/", "../", null bytes, or other characters from the file path so it can't load hidden, non-public, or sensitive files.

Sanitization

Sanitization removes (or escapes) illegal or unsafe characters from foreign input.

For example, you should sanitize foreign input before including the input in HTML or inserting it into a raw SQL query. When you use bound parameters with PDO, it will sanitize the input for you.

Sometimes it is required to allow some safe HTML tags in the input when including it in the HTML page. This is very hard to do and many avoid it by using other more restricted formatting like Markdown or BBCode, although whitelisting libraries like HTML Purifier exists for this reason.
See Sanitization Filters
Unserialization

It is dangerous to unserialize() data from users or other untrusted sources. Doing so can allow malicious users to instantiate objects (with user-defined properties) whose destructors will be executed, even if the objects themselves aren't used. You should therefore avoid unserializing untrusted data.

If you absolutely must unserialize data from untrusted sources, use PHP 7's allowed_classes option to restrict which object types are allowed to be unserialized.

Validation

Validation ensures that foreign input is what you expect. For example, you may want to validate an email address, a phone number, or age when processing a registration submission.
See Validation Filters

Configuration Files

When creating configuration files for your applications, best practices recommend that one of the following methods be followed:

It is recommended that you store your configuration information where it cannot be accessed directly and pulled in via the file system.

If you must store your configuration files in the document root, name the files with a .php extension. This ensures that, even if the script is accessed directly, it will not be output as plain text.

Information in configuration files should be protected accordingly, either through encryption or group/user file system permissions.

It is a good idea to ensure that you do not commit configuration files containing sensitive information e.g. passwords or API tokens to source control.

Register Globals

NOTE: As of PHP 5.4.0 the register_globals setting has been removed and can no longer be used. This is only included as a warning for anyone in the process of upgrading a legacy application.

When enabled, the register_globals configuration setting makes several types of variables (including ones from$_POST, $_GET and $_REQUEST) available in the global scope of your application. This can easily lead to security issues as your application cannot effectively tell where the data is coming from.

For example: $_GET['foo'] would be available via $foo, which can override variables that have been declared.

If you are using PHP < 5.4.0 make sure that register_globals is off.

Error Reporting

Error logging can be useful in finding the problem spots in your application, but it can also expose information about the structure of your application to the outside world. To effectively protect your application from issues that could be caused by the output of these messages, you need to configure your server differently in development versus production (live).

Development

To show every possible error during development, configure the following settings in your php.ini:

Passing in the value -1 will show every possible error, even when new levels and constants are added in future PHP versions. The E_ALL constant also behaves this way as of PHP 5.4. - php.net

Reporting every possible error by PHP version
Production

To hide errors on your production environment, configure your php.ini as:

With these settings in production, errors will still be logged to the error logs for the web server, but will not be shown to the user. For more information on these settings, see the PHP manual:

Writing automated tests for your PHP code is considered a best practice and can lead to well-built applications. Automated tests are a great tool for making sure your application does not break when you are making changes or adding new functionality and should not be ignored.

There are several different types of testing tools (or frameworks) available for PHP, which use different approaches - all of which are trying to avoid manual testing and the need for large Quality Assurance teams, just to make sure recent changes didn't break existing functionality.

Test Driven Development

From Wikipedia:

Test-driven development (TDD) is a software development process that relies on the repetition of a very short development cycle: first the developer writes a failing automated test case that defines a desired improvement or new function, then produces code to pass that test and finally refactors the new code to acceptable standards. Kent Beck, who is credited with having developed or 'rediscovered' the technique, stated in 2003 that TDD encourages simple designs and inspires confidence.

There are several different types of testing that you can do for your application:

Unit Testing

Unit Testing is a programming approach to ensure functions, classes and methods are working as expected, from the point you build them all the way through the development cycle. By checking values going in and out of various functions and methods, you can make sure the internal logic is working correctly. By using Dependency Injection and building "mock" classes and stubs you can verify that dependencies are correctly used for even better test coverage.

When you create a class or function you should create a unit test for each behavior it must have. At a very basic level you should make sure it errors if you send it bad arguments and make sure it works if you send it valid arguments. This will help ensure that when you make changes to this class or function later on in the development cycle that the old functionality continues to work as expected. The only alternative to this would be var_dump() in a test.php, which is no way to build an application - large or small.

The other use for unit tests is contributing to open source. If you can write a test that shows broken functionality (i.e. fails), then fix it, and show the test passing, patches are much more likely to be accepted. If you run a project which accepts pull requests then you should suggest this as a requirement.

PHPUnit is the de-facto testing framework for writing unit tests for PHP applications, but there are several alternatives

Integration Testing

From Wikipedia:

Integration testing (sometimes called Integration and Testing, abbreviated "I&T") is the phase in software testing in which individual software modules are combined and tested as a group. It occurs after unit testing and before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.

Many of the same tools that can be used for unit testing can be used for integration testing as many of the same principles are used.

Functional Testing

Sometimes also known as acceptance testing, functional testing consists of using tools to create automated tests that actually use your application instead of just verifying that individual units of code are behaving correctly and that individual units can speak to each other correctly. These tools typically work using real data and simulating actual users of the application.

Functional Testing Tools

Behavior Driven Development

There are two different types of Behavior-Driven Development (BDD): SpecBDD and StoryBDD. SpecBDD focuses on technical behavior of code, while StoryBDD focuses on business or feature behaviors or interactions. PHP has frameworks for both types of BDD.

With StoryBDD, you write human-readable stories that describe the behavior of your application. These stories can then be run as actual tests against your application. The framework used in PHP applications for StoryBDD is Behat, which is inspired by Ruby's Cucumber project and implements the Gherkin DSL for describing feature behavior.

With SpecBDD, you write specifications that describe how your actual code should behave. Instead of testing a function or method, you are describing how that function or method should behave. PHP offers the PHPSpec framework for this purpose. This framework is inspired by the RSpec project for Ruby.

Behat, the StoryBDD framework for PHP, inspired by Ruby's Cucumber project;

PHPSpec, the SpecBDD framework for PHP, inspired by Ruby's RSpec project;

Codeception is a full-stack testing framework that uses BDD principles.

Complementary Testing Tools

Besides individual testing and behavior driven frameworks, there are also a number of generic frameworks and helper libraries useful for any preferred approach taken.

PHP applications can be deployed and run on production web servers in a number of ways.

Platform as a Service (PaaS)

PaaS provides the system and network architecture necessary to run PHP applications on the web. This means little to no configuration for launching PHP applications or PHP frameworks.

Recently PaaS has become a popular method for deploying, hosting, and scaling PHP applications of all sizes. You can find a list of PHP PaaS "Platform as a Service" providers in our resources section.

Virtual or Dedicated Servers

If you are comfortable with systems administration, or are interested in learning it, virtual or dedicated servers give you complete control of your application's production environment.

nginx and PHP-FPM

PHP, via PHP's built-in FastCGI Process Manager (FPM), pairs really nicely with nginx, which is a lightweight, high-performance web server. It uses less memory than Apache and can better handle more concurrent requests. This is especially important on virtual servers that don't have much memory to spare.

Apache and PHP

PHP and Apache have a long history together. Apache is wildly configurable and has many available modules to extend functionality. It is a popular choice for shared servers and an easy setup for PHP frameworks and open source apps like WordPress. Unfortunately, Apache uses more resources than nginx by default and cannot handle as many visitors at the same time.

Apache has several possible configurations for running PHP. The most common and easiest to setup is the prefork MPM with mod_php5. While it isn't the most memory efficient, it is the simplest to get working and to use. This is probably the best choice if you don't want to dig too deeply into the server administration aspects. Note that if you use mod_php5 you MUST use the prefork MPM.

Alternatively, if you want to squeeze more performance and stability out of Apache then you can take advantage of the same FPM system as nginx and run the worker MPM or event MPM with mod_fastcgi or mod_fcgid. This configuration will be significantly more memory efficient and much faster but it is more work to set up.

If you are running Apache 2.4 or later, you can use mod_proxy_fcgi to get great performance that is easy to setup.

Building and Deploying your Application

If you find yourself doing manual database schema changes or running your tests manually before updating your files (manually), think twice! With every additional manual task needed to deploy a new version of your app, the chances for potentially fatal mistakes increase. Whether you're dealing with a simple update, a comprehensive build process or even a continuous integration strategy, build automation is your friend.

Among the tasks you might want to automate are:

Dependency management

Compilation, minification of your assets

Running tests

Creation of documentation

Packaging

Deployment

Deployment Tools

Deployment tools can be described as a collection of scripts that handle common tasks of software deployment. The deployment tool is not a part of your software, it acts on your software from 'outside'.

There are many open source tools available to help you with build automation and deployment, some are written in PHP others aren't. This shouldn't hold you back from using them, if they're better suited for the specific job. Here are a few examples:

Phing can control your packaging, deployment or testing process from within a XML build file. Phing (which is based on Apache Ant) provides a rich set of tasks usually needed to install or update a web application and can be extended with additional custom tasks, written in PHP. It's a solid and robust tool and has been around for a long time, however the tool could be perceived as a bit old fashioned because of the way it deals with configuration (XML files).

Capistrano is a system for intermediate-to-advanced programmers to execute commands in a structured, repeatable way on one or more remote machines. It is pre-configured for deploying Ruby on Rails applications, however you can successfully deploy PHP systems with it. Successful use of Capistrano depends on a working knowledge of Ruby and Rake.

Ansistrano is a couple of Ansible roles to easily manage the deployment process (deploy and rollback) for scripting applications such as PHP, Python and Ruby. It's an Ansible port for Capistrano. It's been used by quite a lot of PHP companies already.

Rocketeer gets its inspiration and philosophy from the Laravel framework. Its goal is to be fast, elegant and easy to use with smart defaults. It features multiple servers, multiple stages, atomic deploys and deployment can be performed in parallel. Everything in the tool can be hot swapped or extended, and everything is written in PHP.

Deployer is a deployment tool written in PHP. It's simple and functional. Features include running tasks in parallel, atomic deployment and keeping consistency between servers. Recipes of common tasks for Symfony, Laravel, Zend Framework and Yii are available. Younes Rafie's article Easy Deployment of PHP Applications with Deployer is a great tutorial for deploying your application with the tool.

Magallanes is another tool written in PHP with simple configuration done in YAML files. It has support for multiple servers and environments, atomic deployment, and has some built in tasks that you can leverage for common tools and frameworks.

Further reading:

Server Provisioning

Managing and configuring servers can be a daunting task when faced with many servers. There are tools for dealing with this so you can automate your infrastructure to make sure you have the right servers and that they're configured properly. They often integrate with the larger cloud hosting providers (Amazon Web Services, Heroku, DigitalOcean, etc) for managing instances, which makes scaling an application a lot easier.

Ansible is a tool that manages your infrastructure through YAML files. It's simple to get started with and can manage complex and large scale applications. There is an API for managing cloud instances and it can manage them through a dynamic inventory using certain tools.

Puppet is a tool that has its own language and file types for managing servers and configurations. It can be used in a master/client setup or it can be used in a "master-less" mode. In the master/client mode the clients will poll the central master(s) for new configuration on set intervals and update itself if necessary. In the master-less mode you can push changes to your nodes.

Chef is a powerful Ruby based system integration framework that you can build your whole server environment or virtual boxes with. It integrates well with Amazon Web Services through their service called OpsWorks.

Further reading:

Continuous Integration

Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily - leading to multiple integrations per day. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly.

- Martin Fowler
There are different ways to implement continuous integration for PHP. Travis CI has done a great job of making continuous integration a reality even for small projects. Travis CI is a hosted continuous integration service for the open source community. It is integrated with GitHub and offers first class support for many languages including PHP.

Further reading:

Running your application on different environments in development and production can lead to strange bugs popping up when you go live. It's also tricky to keep different development environments up to date with the same version for all libraries used when working with a team of developers.

If you are developing on Windows and deploying to Linux (or anything non-Windows) or are developing in a team, you should consider using a virtual machine. This sounds tricky, but besides the widely known virtualization environments like VMware or VirtualBox, there are additional tools that may help you setting up a virtual environment in a few easy steps.

Vagrant

Vagrant creates folders for sharing your code between your host and your virtual machine, which means that you can create and edit your files on your host machine and then run the code inside your virtual machine.

A little help

If you need a little help to start using Vagrant there are some services that might be useful:

Puphpet: simple GUI to set up virtual machines for PHP development. Heavily focused in PHP. Besides local VMs, it can be used to deploy to cloud services as well. The provisioning is made with Puppet.

Phansible: provides an easy to use interface that helps you generate Ansible Playbooks for PHP based projects.

Docker

Docker - a lightweight alternative to a full virtual machine - is so called because it's all about "containers". A container is a building block which, in the simplest case, does one specific job, e.g. running a web server. An "image" is the package you use to build the container - Docker has a repository full of them.

A typical LAMP application might have three containers: a web server, a PHP-FPM process and MySQL. As with shared folders in Vagrant, you can leave your application files where they are and tell Docker where to find them.

You can generate containers from the command line (see example below) or, for ease of maintenance, build a docker-compose.yml file for your project specifying which to create and how they communicate with one another.

Docker may help if you're developing multiple websites and want the separation that comes from installing each on it's own virtual machine, but don't have the necessary disk space or the time to keep everything up to date. It's efficient: the installation and downloads are quicker, you only need to store one copy of each image however often it's used, containers need less RAM and share the same OS kernel, so you can have more servers running simultaneously, and it takes a matter of seconds to stop and start them, no need to wait for a full server boot.

Example: Running your PHP Applications in Docker

After installing docker on your machine, you can start a web server with one command. The following will download a fully functional Apache installation with the latest PHP version, map/path/to/your/php/files to the document root, which you can view at http://localhost:8080:

Learn more about Docker

The PHPDocker.io site will auto-generate all the files you need for a fully-featured LAMP/LEMP stack, including your choice of PHP version and extensions.

PHP is pretty quick by itself, but bottlenecks can arise when you make remote connections, load files, etc. Thankfully, there are various tools available to speed up certain parts of your application, or reduce the number of times these various time-consuming tasks need to run.

Opcode Cache

When a PHP file is executed, it must first be compiled into opcodes (machine language instructions for the CPU). If the source code is unchanged, the opcodes will be the same, so this compilation step becomes a waste of CPU resources.

An opcode cache prevents redundant compilation by storing opcodes in memory and reusing them on successive calls. It will typically check signature or modification time of the file first, in case there have been any changes.

It's likely an opcode cache will make a significant speed improvement to your application. Since PHP 5.5 there is one built in - Zend OPcache. Depending on your PHP package/distribution, it's usually turned on by default - check opcache.enable and the output of phpinfo() to make sure. For earlier versions there's a PECL extension.

Read more about opcode caches:

Object Caching

There are times when it can be beneficial to cache individual objects in your code, such as with data that is expensive to get or database calls where the result is unlikely to change. You can use object caching software to hold these pieces of data in memory for extremely fast access later on. If you save these items to a data store after you retrieve them, then pull them directly from the cache for following requests, you can gain a significant improvement in performance as well as reduce the load on your database servers.

Many of the popular bytecode caching solutions let you cache custom data as well, so there's even more reason to take advantage of them. APCu, XCache, and WinCache all provide APIs to save data from your PHP code to their memory cache.

The most commonly used memory object caching systems are APCu and memcached. APCu is an excellent choice for object caching, it includes a simple API for adding your own data to its memory cache and is very easy to setup and use. The one real limitation of APCu is that it is tied to the server it's installed on. Memcached on the other hand is installed as a separate service and can be accessed across the network, meaning that you can store objects in a hyper-fast data store in a central location and many different systems can pull from it.

Note that when running PHP as a (Fast-)CGI application inside your webserver, every PHP process will have its own cache, i.e. APCu data is not shared between your worker processes. In these cases, you might want to consider using memcached instead, as it's not tied to the PHP processes.

In a networked configuration APCu will usually outperform memcached in terms of access speed, but memcached will be able to scale up faster and further. If you do not expect to have multiple servers running your application, or do not need the extra features that memcached offers then APCu is probably your best choice for object caching.

Example logic using APCu:

Note that prior to PHP 5.5, APC provides both an object cache and a bytecode cache. APCu is a project to bring APC's object cache to PHP 5.5+, since PHP now has a built-in bytecode cache (OPcache).

Learn more about popular object caching systems:

PHPDoc

PHPDoc is an informal standard for commenting PHP code. There are a lot of different tags available. The full list of tags and examples can be found at the PHPDoc manual.

Below is an example of how you might document a class with a few methods;

The documentation for the class as a whole has the @author tag and a @link tag. The @author tag is used to document the author of the code and can be repeated for documenting several authors. The@link tag is used to link to a website indicating a relationship between the website and the code.

The second and third methods are very similar and have a single @param tag as did the first method. The important difference between the second and third methods' doc block is the inclusion/exclusion of the@return tag.@return void explicitly informs us that there is no return; historically omitting the @return void statement also results in the same (no return) action.

From the Source

People to Follow

It's difficult to find interesting and knowledgeable PHP community members when you are first starting out. You can find an abbreviated list of PHP community members to get you started at:

PHP PaaS Providers

To see which versions these PaaS hosts are running, head over to PHP Versions.

Frameworks

Rather than re-invent the wheel, many PHP developers use frameworks to build out web applications. Frameworks abstract away many of the low-level concerns and provide helpful, easy-to-use interfaces to complete common tasks.

You do not need to use a framework for every project. Sometimes plain PHP is the right way to go, but if you do need a framework then there are three main types available:

Micro Frameworks

Full-Stack Frameworks

Component Frameworks

Micro-frameworks are essentially a wrapper to route a HTTP request to a callback, controller, method, etc as quickly as possible, and sometimes come with a few extra libraries to assist development such as basic database wrappers and the like. They are prominently used to build remote HTTP services.

Many frameworks add a considerable number of features on top of what is available in a micro-framework; these are called Full-Stack Frameworks. These often come bundled with ORMs, Authentication packages, etc.

Component-based frameworks are collections of specialized and single-purpose libraries. Disparate component-based frameworks can be used together to make a micro- or full-stack framework.

Components

As mentioned above "Components" are another approach to the common goal of creating, distributing and implementing shared code. Various component repositories exist, the main two of which are:

Both of these repositories have command line tools associated with them to help the installation and upgrade processes, and have been explained in more detail in the Dependency Management section.

There are also component-based frameworks and component-vendors that offer no framework at all. These projects provide another source of packages which ideally have little to no dependencies on other packages, or specific frameworks.

For example, you can use the FuelPHP Validation package, without needing to use the FuelPHP framework itself.
Laravel's Illuminate components will become better decoupled from the Laravel framework. For now, only the components best decoupled from the Laravel framework are listed above.

Other Useful Resources

Cheatsheets

More best practices

News around the PHP and web development communities

You can subscribe to weekly newsletters to keep yourself informed on new libraries, latest news, events and general announcements, as well as additional resources being published every now and then:

There are also Weeklies on other platforms you might be interested in; here's a list of some.

PHP universe

Video Tutorials

YouTube Channels

Paid Videos

Books

There are many PHP books; sadly some are now quite old and no longer accurate. In particular, avoid books on "PHP 6", a version that will now never exist. The next major release of PHP after 5.6 was "PHP 7", partly because of this.

This section aims to be a living document for recommended books on PHP development in general. If you would like your book to be added, send a PR and it will be reviewed for relevancy.

Free Books

Paid Books

Read the Official PHP Events Calendar

PHP User Groups

If you live in a larger city, odds are there's a PHP user group nearby. You can easily find your local PUG at PHP.ug. Alternate sources might be Meetup.com or a search for php user group near me using your favorite search engine (i.e. Google). If you live in a smaller town, there may not be a local PUG; if that's the case, start one!

Special mention should be made of two global user groups: NomadPHP and PHPWomen. NomadPHP offers twice monthly online user group meetings with presentations by some of the top speakers in the PHP community. PHPWomen is a non-exclusive user group originally targeted towards the women in the PHP world. Membership is open to everyone who supports a more diverse community. PHPWomen provide a network for support, mentorship and education, and generally promote the creating of a "female friendly" and professional atmosphere.
Read about User Groups on the PHP Wiki

PHP Conferences

The PHP community also hosts larger regional and national conferences in many countries around the world. Well-known members of the PHP community usually speak at these larger events, so it's a great opportunity to learn directly from industry leaders.
Find a PHP Conference

ElePHPants

ElePHPant is that beautiful mascot of the PHP project with elephant in their design. It was originally designed for the PHP project in 1998 by Vincent Pontier - spiritual father of thousands of elePHPants around the world and 10 years later adorable plush elephant toy came to birth as well. Now elePHPants are present at many PHP conferences and with many PHP developers at their computers for fun and inspiration.
Interview with Vincent Pontier

# data[].attributes.attachment_link.description
There's a lot of outdated information on the Web that leads new PHP users astray, propagating bad practices and insecure code. PHP: The Right Way is an easy-to-read, quick reference for PHP popular coding standards, links to authoritative tutorials around the Web and what the contributors consider to be best practices at the present time.

# data[].attributes.attachment_link.readable_text
Python is an easy to learn, powerful programming language. It has efficient high-level data structures and a simple but effective approach to object-oriented programming. Python's elegant syntax and dynamic typing, together with its interpreted nature, make it an ideal language for scripting and rapid application development in many areas on most platforms.

The Python interpreter and the extensive standard library are freely available in source or binary form for all major platforms from the Python web site, https://www.python.org/, and may be freely distributed. The same site also contains distributions of and pointers to many free third party Python modules, programs and tools, and additional documentation.

The Python interpreter is easily extended with new functions and data types implemented in C or C++ (or other languages callable from C). Python is also suitable as an extension language for customizable applications.

This tutorial introduces the reader informally to the basic concepts and features of the Python language and system. It helps to have a Python interpreter handy for hands-on experience, but all examples are self-contained, so the tutorial can be read off-line as well.

For a description of standard objects and modules, see The Python Standard Library . The Python Language Reference gives a more formal definition of the language. To write extensions in C or C++, read Extending and Embedding the Python Interpreter and Python/C API Reference Manual . There are also several books covering Python in depth.

This tutorial does not attempt to be comprehensive and cover every single feature, or even every commonly used feature. Instead, it introduces many of Python's most noteworthy features, and will give you a good idea of the language's flavor and style. After reading it, you will be able to read and write Python modules and programs, and you will be ready to learn more about the various Python library modules described in The Python Standard Library .

The is also worth going through.

# data[].attributes.attachment_link.title
The Python Tutorial - Python 3.10.4 documentation

# data[].attributes.attachment_link.description
Python is an easy to learn, powerful programming language. It has efficient high-level data structures and a simple but effective approach to object-oriented programming.

# data[].attributes.attachment_link.title
Documentation de Django | Documentation de Django | Django

# data[].attributes.attachment_link.description
Tout ce que vous devez savoir sur Django.

# data[].attributes.attachment_link.readable_text
"These sorts of things are in my opinion the best way to learn a language.", What people have said about us:

brberg at Media Cloisters

"It's the best web site of the year so far.", Andy Todd at halfcooked

"Addictive way to learn the ins and outs of Python.. a must for all programmers!", salimma at stumbleupon

"This challenge is fantastic. Clever, addictive and really gets your mind working. I feel like I'm playing Myst.", James Tauber after finishing level 22.

"I've been using Python since 1991, and while I've always enjoyed it, I have to confess this is the most Python fun I've had this century! Excellent work. Thank you!", Tim Peters

"If you've got any Python chops, I highly recommend giving it a shot. The puzzles are very well constructed, and the clues are clever. I felt continually challenged, but almost never at a total loss for things to try.", Thiamin Trek at 96db.com

# data[].attributes.attachment_link.description
"These sorts of things are in my opinion the best way to learn a language.", What people have said about us: brberg at Media Cloisters "It's the best web site of the year so far.", Andy Todd at halfcooked "Addictive way to learn the ins and outs of Python..

# data[].attributes.attachment_link.description
A nice collection of often useful examples done in Vue.js

# data[].attributes.attachment_link.title
REACT JS TUTORIAL #1 - Reactjs Javascript Introduction & Workspace Setup

# data[].attributes.attachment_link.readable_text
Welcome to the very start of your React Native journey! If you're looking for environment setup instructions, they've moved to their own section. Continue reading for an introduction to the documentation, Native Components, React, and more!

Many different kinds of people use React Native: from advanced iOS developers to React beginners, to people getting started programming for the first time in their career. These docs were written for all learners, no matter their experience level or background.

You can start here and read through these docs linearly like a book; or you can read the specific sections you need. Already familiar with React? You can skip that section -or read it for a light refresher.

To work with React Native, you will need to have an understanding of JavaScript fundamentals. If you're new to JavaScript or need a refresher, you can dive in or brush up at Mozilla Developer Network.

While we do our best to assume no prior knowledge of React, Android, or iOS development, these are valuable topics of study for the aspiring React Native developer. Where sensible, we have linked to resources and articles that go more in depth.

This introduction lets you get started immediately in your browser with interactive examples like this one:

The above is a Snack Player. It's a handy tool created by Expo to embed and run React Native projects and share how they render in platforms like Android and iOS. The code is live and editable, so you can play directly with it in your browser. Go ahead and try changing the "Try editing me!" text above to "Hello, world!"

Optionally, if you want to setup a local development environment, you can follow our guide to setting up your environment on your local machine and paste the code examples into your App.js file there. (If you are a web developer, you may already have a local environment set up for mobile browser testing!)

With React, you can make components using either classes or functions. Originally, class components were the only components that could have state. But since the introduction of React's Hooks API, you can add state and more to function components.

Hooks were introduced in React Native 0.58., and because Hooks are the future-facing way to write your React components, we wrote this introduction using function component examples. Where useful, we also cover class components under a toggle like so:

Function Component Example

Class Component Example

You can find more examples of class components in previous versions of this documentation.

People from many different development backgrounds are learning React Native. You may have experience with a range of technologies, from web to Android to iOS and more. We try to write for developers from all backgrounds. Sometimes we provide explanations specific to one platform or another like so:

Developer Notes Web Android iOS

Web developers may be familiar with this concept.

Android developers may be familiar with this concept.

iOS developers may be familiar with this concept.

Menu paths are written in bold and use carets to navigate submenus. Example: Android Studio > Preferences

Now that you know how this guide works, it's time to get to know the foundation of React Native: Native Components.

# data[].attributes.attachment_link.description
Welcome to the very start of your React Native journey! If you're looking for environment setup instructions, they've moved to their own section. Continue reading for an introduction to the documentation, Native Components, React, and more! Many different kinds of people use React Native: from advanced iOS developers to React beginners, to people getting started programming for the first time in their career.

# data[].attributes.attachment_link.title
Next.js Resources! (Books, Courses, Articles, Videos) · Discussion #29628 · vercel/next.js

# data[].attributes.attachment_link.description
You can't perform that action at this time. You signed in with another tab or window. You signed out in another tab or window. Reload to refresh your session. Reload to refresh your session.

# data[].attributes.attachment_link.description
Interested in learning more about Laravel? This section features tutorials on everything from getting started with Laravel, to expert topics, and everything in between.

# data[].attributes.attachment_link.title
LaraShout | Laravel Tutorials and Guides

# data[].attributes.attachment_link.description
LaraShout a go to resource for Laravel related tutorials, guides and tips. Helps you to learn Laravel, PHP, JavaScript and CSS. Enhance you web development skills and succeed.

# data[].attributes.attachment_link.description
Tuts Make is a tutorial point about Web & Technology. Here you can learn PHP, laravel, Codeigniter, jQuery, JavaScript, Node js, Angular js, Wordpress, etc.

# data[].attributes.attachment_link.readable_text
Description

Des discussions autour du JavaScript avec ceux qui l'utilisent au quotidien.

Développeur front ou back end, freelance ou employé, CTO ou CEO d'une entreprise avec une stack JS ?

Nous allons parlé avec tous ces acteurs francophones de la communauté JavaScript !

Tous les épisodes

# data[].attributes.attachment_link.description
Des discussions autour du JavaScript avec ceux qui l'utilisent au quotidien. Développeur front ou back end, freelance ou employé, CTO ou CEO d'une entreprise avec une stack JS ? Nous allons parlé avec tous ces acteurs francophones de la communauté JavaScript !

# data[].attributes.attachment_link.title
Les Cast Codeurs Podcast | Liste des épisodes

# data[].attributes.attachment_link.description
Dans l'interview, nous n'avons pas eu le temps de parler: De Vet et des workflows associés (via les commandes documentées sur la page GitHub) qui permettent de verrouiller les push sur le git remote.

# data[].attributes.attachment_link.title
20 VS Code Shortcuts For Pro Developers | .cult by Honeypot

# data[].attributes.attachment_link.description
Here some handy shortcuts to help you code faster when using Visual Studio Code. You probably use VS on the daily so take note of these shortcuts!

# data[].attributes.attachment_link.readable_text
Jest is a JavaScript testing framework designed to ensure correctness of any JavaScript codebase. It allows you to write tests with an approachable, familiar and feature-rich API that gives you results quickly.

Jest makes testing delightful.

# data[].attributes.attachment_link.description
Jest is a JavaScript testing framework designed to ensure correctness of any JavaScript codebase. It allows you to write tests with an approachable, familiar and feature-rich API that gives you results quickly. Jest makes testing delightful.

# data[].attributes.attachment_link.readable_text
JavaScript is one of the most loved and hated language in the world. It is loved because it is potent. You can make a full-stack application by just learning JavaScript and nothing else. It is also hated because it behaves in unexpected and upsetting ways, which, if you're not invested in understanding the language, might make you hate it 💔.

This blog will explain how JavaScript executes code in the browser, and we will learn it through animated gifs 😆. After reading this blog, you will be one step closer to becoming a rockstar developer. 🎸😎

" Everything in JavaScript happens inside an Execution Context."

I want everyone to remember this statement as it is essential. You can assume this Execution context to be a big container, invoked when the browser wants to run some JavaScript code.

In this container, there are two components 1. Memory component 2. Code component

Memory component is also known as variable environment. In this memory component, variables and functions are stored as key-value pairs.

Code component is a place in the container where code is executed one line at a time. This code component also has a fancy name, namely 'Thread of Execution'. I think it sounds cool!

Execution context

JavaScript is a synchronous, single-threaded language. It is because it can only execute one command at a time and in a specific order.

var a = 2;
var b = 4;

var sum = a + b;

console.log(sum);

Let's take a simple example,

In this simple example, we initialize two variables, a and b and store 2 and 4, respectively.

Then we add the value of a and b and store it in the sum variable.

Let's see how JavaScript will execute the code in the browser 🤖

The browser creates a global execution context with two components, namely memory and code components.

The Browser will execute the JavaScript code in two-phase

1> Memory Creation Phase

2> Code Execution Phase

In the memory creation phase, JavaScript will scan through all the code and allocate memory to all the variables and functions in the code. For variables, JavaScript will store undefined in the memory creation phase, and for functions, it will keep the entire function code, which we will be looking at the following example.

Now, in the 2nd phase, i.e. code execution, it starts going through the whole code line by line.

As it encounters var a = 2, it assigns 2 to 'a' in memory. Until now, the value of 'a' was undefined.

Similarly, it does the same thing for the b variable. It assigns 4 to 'b'. Then it calculates and stores the value of the sum in memory which is 6. Now, in the last step, it prints the sum value in the console and then destroys the global execution context as our code is finished.

Functions in JavaScript, when you compare with other programming languages, work differently.

Let's take an simple example,

var n = 2;

function square(num) {
 var ans = num * num;
 return ans;
}

var square2 = square(n);
var square4 = square(4);

The above example has an function which takes an argument of type number and returns the square of the number.

JavaScript will create a global execution context and allocate memory to all the variables and functions in the first phase when we run the code, as shown below.

For functions, It will store the entire function in the memory.

Here comes the exciting part, When JavaScript runs functions, it will create an execution context inside the global execution context.

As it encounters var a = 2, it assigns 2 to 'n' in memory. Line number 2 is a function, and as the function has been allocated memory in the memory execution phase, it will directly jump to line number 6.

square2 variable will invoke the square function, and javascript will create a new execution context.

This new execution context for the square function will assign memory to all the variables present in the function in the memory creation phase.

After assigning memory to all the variables inside the function, it will execute the code line by line. It will get the value of num, which is equal to 2 for the first variable and then it will calculate ans. After ans has been calculated, it will return the value which will be assigned to square2.

Once the function returns the value, it will destroy its execution context as it has completed the work.

Now it will follow a similar procedure for line number 7 or square4 variable, as shown below.

Once all the code is executed, the global execution context will also be destroyed, and this is how JavaScript will execute the code behind the scene.

When a function is invoked in JavaScript, JavaScript creates an execution context. Execution context will get complicated as we nest functions inside a function.

JavaScript manages code execution context creation and deletion with the the help of Call Stack.

A stack (sometimes called a "push-down stack") is an ordered collection of items where the addition of new items and the removal of existing items always takes place at the same end eg. stack of books.

Call Stack is a mechanism to keep track of its place in a script that calls multiple functions.

Let's take an example

function a() {
 function insideA() {
 return true;
 }
 insideA();
}
a();

We are creating a function 'a', which calls another function 'insideA' that returns true. I know the code is dumb and doesn't do anything, but it will help us understand how JavaScript handles callback functions.

JavaScript will create a global execution context. Global execution context will assign memory to function 'a' and invoke' function a' in the code execution phase.

An execution context is created for function a, which is placed above the global execution context in the call stack.

Function a will assign memory and invoke function insideA. An execution context is created for function insideA and placed above the call stack of 'function a'.

Now, this insideA function will return true and will be removed from the call stack.

As there is no code inside 'function a' execution context will be removed from the call stack.

Finally, the global execution context is also removed from the call stack.

I hope this post was informative. 💪🏾 Feel free to reach out to me if you have any questions.

For more such insights, check out my blog website blog.webdrip.in

# data[].attributes.attachment_link.description
JavaScript is one of the most loved and hated language in the world. It is loved because it is potent. You can make a full-stack application by just learning JavaScript and nothing else. It is also hated because it behaves in unexpected and upsetting ways, which, if you're not invested in understanding the language, might make you hate it 💔.

# data[].attributes.attachment_link.readable_text
A Full-Stack developer is a developer who can manage both Front End and Back End web development. The "Front-End" development refers to the user interface, while "Back-End" means the server, application, and database. The Back-End is managed using programming languages like Java, PHP, Ruby, and Python.

Advantages:

Master all the techniques involved in a development project.

Can provide help to all the team members

Can reduce the cost of the project

Can reduce the time used for team communication

Disadvantages:

The solution chosen can be dependent on developer skills

The solution chosen can be wrong for the project

Being a full-stack developer is increasingly complex

Front End Developer

Front-end developers code the whole website using different web languages like HTML, CSS, and javascript. Front-end developers deal with website design, outlook, and make creative websites. Design is all about the way a website looks. It is essential because it is the part of the website where users visit.

Skills You Need To Land Your First Front End:

1. Html/CSS

2. Javascript/jquery

3. CSS and Javascript Frameworks

4. CSS Preprocessing

5. Version Control/git

6. Responsive Design

7. Testing/debugging

8. Browser Developer Tools

9. Building and Automation Tools/Web Performance

10. Command Line

Back End Developer

Back-end Development refers to server-side development. Back End Developer responsible for back-end server-side web application.

Language You Need To Learn Your First Back End Developer:

1. Python

2. Java

3. PHP

4. SQL

5. Git

6. HTML

7. CSS

8. JavaScript

9. Communication

How To Become A Full-Stack Web Developer

A full-stack developer requires years of experience. You may have to learn both web languages used in the back-end and front end. There are so many resources available from where you can learn about Full Stack and "become a full-stack developer" There are different methods to learn. You have to do smart work instead of hard work. Practicing is more important than reading books and notes. You can learn from YouTube, buying courses, and joining the developer communities.

A full-stack developer is skilled in:

Writing front-end code in JavaScript, HTML, and Java

Writing back-end code in Java, Python, and Ruby

Security and Networking

Dealing with APIs

Client coordination and Project management

Creating, querying, and understanding databases

Handling complete system infrastructure, including OS and hardware

Popular stacks that the developer would have to work with include:

1. Django stack: JavaScript - Python - Django - MySQL

2. Ruby on Rails: Javascript - Ruby - SQLite - PHP

3. MEAN stack: JavaScript - MongoDB- Express - Angular JS - Node.js

4. LEMP stack: JavaScript - Linux- Nginx - MySQL - PHP

5. LAMP stack: JavaScript - Linux - Apache - MySQL - PHP

Tactics That Turn a Developer Into a Full-Stack Development

Project Ideas

1. Blog (CRUD)

2. Todo App

3. Chat Bot

4. Quiz App

Congratulations!!!

You're now a full-stack developer. You can now consider yourself as a one-man army.

# data[].attributes.attachment_link.description
A Full-Stack developer is a developer who can manage both Front End and Back End web development. The "Front-End" development refers to the user interface, while "Back-End" means the server, application, and database. The Back-End is managed using programming languages like Java, PHP, Ruby, and Python.

# data[].attributes.attachment_link.description
Je suis Loïc TRUCHOT, expert JavaScript et formateur dans différentes écoles. Je vous livre ici mes réflexions sur JS, ce langage au coeur du web et bien au delà, si important aujourd'hui, et pourtant souvent méconnu ou mal aimé. Nous abordons aussi l'écosystème de javascript, et des concepts plus profonds ou généraux du développement web et logiciel.

# data[].attributes.attachment_link.readable_text
HTTP request logger middleware for node.js

Named after Dexter, a show you should not watch until completion.

API

Create a new morgan logger middleware function using the given format and options. The format argument may be a string of a predefined name (see below for the names), a string of a format string, or a function that will produce a log entry.

The format function will be called with three arguments tokens, req, and res, where tokens is an object with all defined tokens, req is the HTTP request and res is the HTTP response. The function is expected to return a string that will be the log line, or undefined / null to skip logging.

Morgan accepts these properties in the options object.

Write log line on request instead of response. This means that a requests will be logged even if the server crashes, but data from the response (like the response code, content length, etc.) cannot be logged.

Function to determine if logging is skipped, defaults to false. This function will be called as skip(req, res).

Output stream for writing log lines, defaults to process.stdout.

There are various pre-defined formats provided:

Standard Apache combined log output.

:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"

Standard Apache common log output.

:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length]

Concise output colored by response status for development use. The :status token will be colored green for success codes, red for server error codes, yellow for client error codes, cyan for redirection codes, and uncolored for information codes.

:method :url :status :response-time ms - :res[content-length]

Shorter than default, also including response time.

:remote-addr :remote-user :method :url HTTP/:http-version :status :res[content-length] - :response-time ms

The minimal output.

:method :url :status :res[content-length] - :response-time ms

To define a token, simply invoke morgan.token() with the name and a callback function. This callback function is expected to return a string value. The value returned is then available as ":type" in this case:

Calling morgan.token() using the same name as an existing token will overwrite that token definition.

The token function is expected to be called with the arguments req and res, representing the HTTP request and HTTP response. Additionally, the token can accept further arguments of it's choosing to customize behavior.

The current date and time in UTC. The available formats are:

clf for the common log format ("10/Oct/2000:13:55:36 +0000")

iso for the common ISO 8601 date time format (2000-10-10T13:55:36.000Z)

web for the common RFC 1123 date time format (Tue, 10 Oct 2000 13:55:36 GMT)

If no format is given, then the default is web.

The HTTP version of the request.

The HTTP method of the request.

The Referrer header of the request. This will use the standard mis-spelled Referer header if exists, otherwise Referrer.

The remote address of the request. This will use req.ip, otherwise the standard req.connection.remoteAddress value (socket address).

The user authenticated as part of Basic auth for the request.

The given header of the request. If the header is not present, the value will be displayed as"-" in the log.

The given header of the response. If the header is not present, the value will be displayed as"-" in the log.

The time between the request coming into morgan and when the response headers are written, in milliseconds.

The digits argument is a number that specifies the number of digits to include on the number, defaulting to 3, which provides microsecond precision.

The status code of the response.

If the request/response cycle completes before a response was sent to the client (for example, the TCP socket closed prematurely by a client aborting the request), then the status will be empty (displayed as "-" in the log).

The time between the request coming into morgan and when the response has finished being written out to the connection, in milliseconds.

The digits argument is a number that specifies the number of digits to include on the number, defaulting to 3, which provides microsecond precision.

The URL of the request. This will use req.originalUrl if exists, otherwise req.url.

The contents of the User-Agent header of the request.

Compile a format string into a format function for use by morgan. A format string is a string that represents a single log line and can utilize token syntax. Tokens are references by:token-name. If tokens accept arguments, they can be passed using[], for example: :token-name[pretty] would pass the string'pretty' as an argument to the token token-name.

The function returned from morgan.compile takes three arguments tokens, req, and res, where tokens is object with all defined tokens, req is the HTTP request and res is the HTTP response. The function will return a string that will be the log line, or undefined / null to skip logging.

Normally formats are defined using morgan.format(name, format), but for certain advanced uses, this compile function is directly available.

Examples

Simple app that will log all request in the Apache combined format to STDOUT

Simple app that will log all request in the Apache combined format to STDOUT

Simple app that will log all requests in the Apache combined format to the file access.log.

Simple app that will log all requests in the Apache combined format to one log file per day in the log/ directory using the rotating-file-stream module.

The morgan middleware can be used as many times as needed, enabling combinations like:

Log entry on request and one on response

Log all requests to file, but errors to console

... and more!

Sample app that will log all requests to a file using Apache format, but error responses are logged to the console:

Sample app that will use custom token formats. This adds an ID to all requests and displays it using the :id token.

License

# data[].attributes.attachment_link.description
HTTP request logger middleware for node.js Named after Dexter, a show you should not watch until completion. Create a new morgan logger middleware function using the given format and options. The format argument may be a string of a predefined name (see below for the names), a string of a format string, or a function that will produce a log entry.

# data[].attributes.attachment_link.readable_text
There's a lot of community-driven public discussion forums, chats and channels where you can get help with any WebAssembly-related questions, answer them for others, or subscribe to WebAssembly news.

Here are just some of the popular ways to get started:

Interesting in contributing to WebAssembly? Check out the Contributing page.

# data[].attributes.attachment_link.description
There's a lot of community-driven public discussion forums, chats and channels where you can get help with any WebAssembly-related questions, answer them for others, or subscribe to WebAssembly news. Here are just some of the popular ways to get started: Interesting in contributing to WebAssembly? Check out the Contributing page.

# data[].attributes.attachment_link.description
'Caninclude' tool to help determine if one HTML tag can be included in another HTML tag

# data[].attributes.attachment_link.readable_text
Hey readers! This blog is all about ES6. It includes all the topics related with examples. Before reading further, I want to specify that this was not a blog post initially, these are just my personal notes that I use as a reference guide, so I apologize for any misspells here :)

Table of Contents

Notes

let/const

Before moving to the point, let us understand two concepts here:

1. Global Scope - Variable is declared outside the function. This variable is accessible inside every function present in the code.

2. Function Scope - Variable is declared inside (within) a function, outside that it is not accessible anywhere.

3. Block Scope - In short, block scope means variables which are declared in a { } block are not accessible outside it. This block can be anif statement, for/while loop, etc.

var: function/ global scoped. Eg:

→ as you can see, var is both global and function scoped, which often creates a confusion. So avoid using it.

The above line of code will throw an error as there's no variable msg outside the function message (where we have logged the variable). So it will show as undefined.

let: block scoped. Eg:

→ let keyword can't be redeclared:

result: SyntaxError - redeclaration of let x

But when we use let inside a function, it works like:

Inside the function box() when we log the value of size, it shows a reference error. That is because, let is block scoped.

Anything inside curly braces { } is block scoped. In the above scenario, the function box() is a block.

const: block scoped. Eg:

const are very similar to let except that they can't be changed and redeclared.

→ therefore let and const are preferred over var keyword for declaring variables.

Objects

objects are written within curly braces { } as collection of key:value pairs.

key: property name

value: value of that property

Creating an empty object:

Talking specifically about ES6, before ES6 we had to specify both (key, value) even if both are of same names.

ES6 help us to get rid of duplication when we have same key:value names. So now our code will look like this:

this

this is a keyword. It basically returns a reference to the object it is placed within

💡 NOTE:

When we call a function as a method in an object, the this keyword returns a reference to that object. 👇

But when we call the function alone, outside the object this returns the global object (browser window) and hence we get the result as undefined 👇

Arrow Functions

array.map()

If we have an array -

We want to map the objects. Now there are two methods, es6 one is shorter and easier.

Object Destructuring

Let's say we have an object called girl such that it has 3 keys as follows:

Normally, we would do something like this to get the values:

const name = girl.name; const age = girl.age; const country = girl.country;

here, as you can see we have to repeat the object name girl everytime we want to get a value. This problem can be solved by object destructuring:
const { name, age, country } = girl;

this one line code works same as the previous code. So destructuring made our code shorter and easier to understand.

In case you want to use an alias (a different variable name) for your work:
const {country: ctry} = girl;
This above line of code means we've defined a new variable called ctry and set that equals to country.

Spread Operator

CASE I - COMBINING ARRAYS

If we want to combine these two arrays:
const combined = one.concat(two);const combined = [...one, ...two];
If we want to add things in-between:
const combined = [...one, '9', '7', ...two ];
If we want to clone an array:
const myDupli = [...two];

CASE II - COMBINING OBJECTS

If we want to combine these two objects:
const combined = {...alpha, ...beta};
If we want to add more properties in b/w:
const gamma = { ...alpha, surName:'Purohit', ...beta, country: 'India'}const betaV2 = {...beta};
Classes

Let us take an example of an object boy here. We have a function called run inside it. Now if we've some bug in the future or we've to modify our function for a different object, it would be a long way.

To overcome this and make our work easier, we use classes:

Now that we've created a class, let's try building our object again -
const boy = new Boy("Samridh");
with this above class, we've implemented the run method in a single line of code. If someday we find a bug here, we've to modify it in just a single place {inside class Boy}. So this is the advantage of using classes in JS.

Inheritance

If we have a class Boy such that -

and we want to create another class (having similar properties + some specific properties of its own). We can do this using the keyword extends

we just created the class Girl here. Let us now create a const using this -
const myGirl = new Girl("Shreya");
and we're done. This code basically means that now the const myGirl will have the functions eat + run + constructor property of Boy class. So we can use it like -

Now let's say we want to create another constructor inside the Girl class {which is extended from Boy class, So the constructor inside this Girl class is called derived class constructor.}.

We MUST HAVE TO call super() constructor inside the new constructor, otherwise we'll get an error (as using this in derived class constructor requires super() class). Now this must be looking confusing, let's look at the example below -

calling super() constructor:

In a child class constructor, this cannot be used until super is called.

Modules

Sometimes we have many no. of classes declared in a single file. This makes the code long, confusing and messy. To avoid this, we separate these classes into different files and import them as a module into the main file. This is called modularity.

Let's look it in action. Here's what our folder src will look like:

both Boy and Girl classes are private in the folder, in order to use them we made them public using the export keyword.

We use import keyword in line 1 of girl.js as it is an extended version of the Boy class.

Now half of the work is done. For now, these classes are not accessible in our main app.js file. For that we've to import them in our app.js file. We can do that by using -

Default and Named Exports

Named Exports

We can export more than one objects from a specific module. This is called named export. Eg:

Here we exported a class Car and a function add.

Default Exports

It is basically the main object that is exported from the module. It is generally used in case we've only a single object to export. Let's see how it is -

💡 Now we don't need the import { Car } from "./car";

Instead, we use import Car from "./car"; in case of default exports.

👋 Woosh! You've made it to the end. Hope I've helped you somehow. I write articles like this whenever I've some spare time. Besides this, I share content related to web development daily on Twitter. Let's connect there! @eyeshreya

# data[].attributes.attachment_link.description
Hey readers! This blog is all about ES6. It includes all the topics related with examples. Before reading further, I want to specify that this was not a blog post initially, these are just my personal notes that I use as a reference guide, so I apologize for any misspells here :) Before moving to the point, let us understand two concepts here: Global Scope - Variable is declared outside the function.

# data[].attributes.attachment_link.readable_text
Hello Everyone 👋,

Git is an important part of daily programming (especially if you're working with a team) and is widely used in the software industry.

Since there are many various commands you can use, mastering Git takes time. But some commands are used more frequently (some daily). So in this post, I will share and explain the top 10 Git commands that every developer should know.
1. Git Init
The git init command is used to initialize a blank repository. It creates a .git folder in the current working directory

The above command will create an empty .git repository. Suppose we want to make a git repository on our desktop. To do so, open Git Bash on the desktop and run the above command. Consider the below output:

The above command will create a new subdirectory named .git that holds all necessary repository files. The .git subdirectory can be understood as a Git repository skeleton. Consider the below image:

An empty repository .git is added to my existing project. If we want to start version-controlling for existing files, we have to track these files with git add command, followed by a commit.
2. Git Commit
The git commit command is used to save the changes to the local repository. This command will help you keep a record of all the changes made. We also need to write a short message to explain what we have developed or changed in the source code.

The above command will prompt a default editor and ask for a commit message. We have made a change to newfile1.txt and want it to commit it. It can be done as follows:

Consider the below output:

As we run the command, it will prompt a default text editor and ask for a commit message. The text editor will look like as follows:

Press the Esc key and after that 'I' for insert mode. Type a commit message whatever you want. Press Esc after that ':wq' to save and exit from the editor. Hence, we have successfully made a commit.

We can check the commit by git log command. Consider the below output:

We can see in the above output that log option is displaying commit-id, author detail, date and time, and the commit message.
3. Git Status
The git status command is used to display the state of the current repository & staging area.

We can gather information these information using git status command:

i) Whether the current branch is up to date

ii) Whether there is anything to commit, push or pull

iii)Whether there are files staged, unstaged or untracked

iv) Whether there are files created, modified, or deleted

Consider the below output:

In the above output, the list of all untracked files is displayed by the git status command. We can track all the untracked files by Git Add command.
4. Git Add
When we create, modify or delete a file, these changes will happen in our local and won't be included in the next commit (unless we change the configurations).

We need to use the git add command to include the changes of a file(s) into our next commit.

To add a single file:

Consider the below output:

From the above output, we can see newfile.txt has been added to our repository. Now, we have to commit it to share on Git.

To add everything at once:

or

In the above output, all the files are displaying as untracked files by Git. To track all of these files at once, run the below command:

The above command will add all the files available in the repository. Consider the below scenario:

We can either create four new files, or we can copy it, and then we add all these files at once. Consider the below output:

In the above output, all the files have been added. The status of all files is displaying as staged.
5. Git Merge
When you've completed development in your branch and everything works fine, the final step is merging the branch with the parent branch (dev or master). This is done with the git merge command.

The git merge command is used to integrate different branches into a single branch. It's important to remember that you first need to be on the specific branch that you want to merge with your feature branch.
6. Git Push
After committing your changes, the next thing you want to do is send your changes to the remote server. Git push uploads your commits to the remote repository.

$ git push -u origin <branch_name>

The file abc.jpg is successfully pushed to the origin master. We can track it in a remote location. I have pushed these changes to my GitHub account. I can track it there in my repository. Consider the below image:

In the above output, the pushed file abc.jpg is uploaded on my GitHub account's master branch repository.
7. Git Pull
The git pull command is used to get updates from the remote repo. This command is a combination of git fetch and git merge which means that, when we use git pull, it gets the updates from remote repository (git fetch) and immediately applies the latest changes in your local (git merge).
8. Git Clone
Git clone is a command for downloading existing source code from a remote repository (like Github, for example). In other words, Git clone basically makes an identical copy of the latest version of a project in a repository and saves it to your computer.

$ git clone https://name-of-the-repository-link

9. Git branch
Branches are highly important in the git world. By using branches, several developers are able to work in parallel on the same project simultaneously. We can use the git branch command for creating, listing and deleting branches

This command will create branch B1 locally in the Git directory.
10. Git Checkout
This is also one of the most used Git commands. To work in a branch, first you need to switch to it. We use git checkout mostly for switching from one branch to another. We can also use it for checking out files and commits.

$ git checkout

As you can see in the given output that master branch has switched to TestBranch.

So these are my 10 most-used git commands that I come across in my daily programming. I hope you find it useful. If yes then let me know in the comments.

Also if you got any question feel free to ping me on Twitter

You can now extend your support by buying me a Coffee.😊👇
Buy Me A Coffee
Thanks for Reading 😊

# data[].attributes.attachment_link.title
Top 10 Git Commands Every Developer Should Know

# data[].attributes.attachment_link.description
Hello Everyone 👋, Git is an important part of daily programming (especially if you're working with a team) and is widely used in the software industry. Since there are many various commands you can use, mastering Git takes time. But some commands are used more frequently (some daily).

# data[].attributes.attachment_link.title
Remaking WordPress in JS stack. Hello to a new CMS for Next.js websites.

# data[].attributes.attachment_link.title
11 Front End Development Trends You Should Follow in 2021 - Java Code Geeks - 2021

# data[].attributes.attachment_link.description
Interested to learn about Development Trends? Check our article presenting Development Trends You Should Follow in 2021.

# data[].attributes.attachment_link.embed_code
11 Front End Development Trends You Should Follow in 2021

# data[].attributes.attachment_link.readable_text
When in comes to Web Development nothing beats JavaScript. But sometimes we have to do a bit more demanding task, for example analyzing big pile of data. In that case Python might be a superior option. But that's just one function of our website. Do we want to switch to Python just because of that one feature? Probably not.

So what if we could build our backend mostly using NodeJS and only use Python when we have to.

That would be awesome right? We can use child process in Node.JS to run a python script when needed.

And if we want we can pass data to our python script also.

In Python in order to be able to read the data you must import the sys module.

Now instead on passing data while spawning the Python process, lets send data in stream.

Finally we can send response back to our nodejs from the python script

So this article has come to an end. But make sure you check out my other articles.

# data[].attributes.attachment_link.description
When in comes to Web Development nothing beats JavaScript. But sometimes we have to do a bit more demanding task, for example analyzing big pile of data. In that case Python might be a superior option. But that's just one function of our website.

# data[].attributes.attachment_link.readable_text
The JavaScript .at() method was introduced in the August release of the ECMA International TC39's relative indexing proposal to allow developers to grab elements based on their indexes.

Selecting elements in JavaScript is a common occurrence in development, but, before the introduction of the .at() method, JavaScript had existing methods and techniques to select elements or characters from the start or end of lists or within a string.

The bracket notation, [], is commonly used to get an element at a specific index. But, this has its drawbacks. For instance, we cannot use a negative index syntax like arr[-1] to access the last item in a list, which has become popular in Python.

Consequently, developers resort to using the slice() method and the length property to grab items from the end of a list. Nonetheless, they also have their respective drawbacks.

In this tutorial, we'll look at the JavaScript .at() method, its use cases, and how it can improve developers' experiences compared to preexisting methods.

The indexable object prototype

The .at() method is located on the prototype of indexable objects.

These objects, which can formulate index entries, include classes like Array, String, and TypedArray, which are Array.prototype.at(), String.prototype.at(), and %TypedArray%.prototype.at(), respectively.

Because of this, we can perform the .at() method directly on these indexable objects.

Existing methods for getting list elements

To see the benefits of the .at() method, we will quickly walk through some of the existing methods for comparison purposes. This will also serve as a refresher for beginners.

Let's consider an array of elements called arr:

const arr = [1, 2, "three", 4, 5, true, false];

By using the bracket notation, [], on the arr array, we can get an element at a specific index. For instance, arr[0] returns the first element, 1, and so on. But, to get an item from the end of an unknown length, we use the length property or the slice() method.

Using the length property

The length property's syntax is written as the following:

arr[arr.length - N];

Here, N equals the nth element from the end of a list, and by using the syntax, we can grab any element from the end of that list.

In the following code, we use the syntax to grab the last element of the arr array:

const arr = [1, 2, "three", 4, 5, true, false];
const lastItem = arr[arr.length - 1];
console.log(lastItem);  // Expected Output: false

This works fine, but the syntax can be inconvenient and tedious for a simple task. Besides, one of its drawbacks when working with the returned value of a function compels us to first store the returned value in a variable before applying the syntax:

function appendNumber(arr, N) {
  arr.push(N);
  return arr;
}

const tempArr = appendNumber([1, 2, "three", 4, 5, true, false], 6);
console.log(tempArr[tempArr.length - 1]); // Expected Output: 6

In the code above, the returned value of the appendNumber() function is first stored in the tempArr variable before the length property is applied.

The slice() method

Developers can also employ the slice() method to grab the last item of a list using the following syntax:

arr.slice(-1)[0]

This syntax allows a negative index, something you'll see in the .at() method later in this tutorial.

The negative index here indicates an offset from the end of the array. For instance, slice(-1) removes the last item from the back and returns a new array; slice(-2) removes the last two, and so on.

But here, the focus is on the last item, hence slice(-1) in the syntax. Then, the [0] notation selects the item at that index.

Using the syntax, we can grab the last item of the arr array like so:

const arr = [1, 2, "three", 4, 5, true, false];

console.log(arr.slice(-1)[0]); // Expected Output: false

Unlike the length property above, this method does not force us to store the returned value of a function before using the syntax. Hence making it more flexible:

function appendNumber(arr, N) {
  arr.push(N);
  return arr;
}

console.log(appendNumber([1, 2, "three", 4, 5, true, false], 6).slice(-1)[0]); // 6

Nonetheless, the syntax looks odd and doesn't portray its intention. And of course, it can be inconvenient as well.

Why not access the last array element witharr[-1]?

This question often comes up from JavaScript beginners, especially if they come from a programming language like Python.

The arr[-1] notation in JavaScript is a valid object property. Remember everything in JavaScript, including arrays, are objects. So anytime we use the bracket notation, for instance, arr[0], we reference the property of the object with the key 0.

By rewriting the arr array in the object notation, we have something like this:

const arr = {
  0: 1,
  1: 2,
  3: "three",
  // ...
};

console.log(arr[0]); // Expected Output: 1

In the above code, we don't have a key -1. So, arr[-1] returns a value of undefined. If the object property has a key -1, as seen in the code below, arr[-1] returns its corresponding value:

const arr = {
  "-1": "valid"
};

console.log(arr[-1]); // Expected Output: valid

This means we can't use the arr[-1] to grab the last element because it's a valid syntax already. To use the negative index syntax to return an element from the end of a list, we will use the .at() method.

The .at() syntax

When using the .at() syntax, it receives an index of an item to return. When passing a negative index, it counts from the end of the list or string and returns the item or character found. Else, it returns undefined:

at(index)

The .at() method in practice

As mentioned earlier, the .at() method receives an index of the item to return. In this section, we will cover its use cases.

Let's revisit the arr array and see how the .at() method allows us to seamlessly return an index element:

const arr = [1, 2, "three", 4, 5, true, false];

console.log(arr.at(0)); // Expected Output: 1
console.log(arr.at(2)); // Expected Output: "three"
console.log(arr.at(-1)); // Expected Output: false
console.log(arr.at(-3)); // Expected Output: 5

When a positive index passes to the .at() method, it returns the element at that index. For a negative index, it counts back from the last element in the list and returns the element.

In the above code, at(-1) counts one from the end of the array and returns false, which is the element found. In the same way, at(-3) counts three from the end and returns 5.

Like arrays, we can do the same for strings:

const str = "The last alphabet is z";

console.log(str.at(0)); // Expected Output: T
console.log(str.at(-1)); // Expected Output: z

As we can see, this method is pleasant to use. With just .at(-1), we get the last character of the str string. If we did the same task with the length property, we would have a longer syntax, like so:

console.log(str[str.length - 1]); // Expected Output: z

Working with the returned value of a function

The .at() method, unlike the length property, does not compel us to store the returned value of a function in a variable before we can use it.

The following code outputs the last element pushed to an array:

function appendNumber(arr, N) {
  arr.push(N);
  return arr;
}

console.log(appendNumber([1, 2, "three", 4, 5, true, false], 6).at(-1));
// Expected Output: 6

In the code, the .at() method applies directly to the returned value without first storing the value in a variable.

The .at() method accepts numbers with a decimal

When a number with a decimal passes to the .at() method, it considers the value before the decimal point and returns the item at that index.

Let's take a look at the following code:

const arr = [1, 2, "three", 4, 5, true, false];
console.log(arr.at(0.6)); // Expected Output: 1
console.log(arr.at(-3.6)); // Expected Output: 5

In the code above, the first console outputs the item at the 0 index while the second console counts three from the end of the array and outputs the found item.

This is beneficial when we want to randomly select an index element. This can be demonstrated with a rock-paper-scissors game project. We can use the .at() method syntax to determine a random selection for the computer.

The following code illustrates how we can apply the .at() method to randomly select the computer's choice:

const computerOptions = ["rock", "paper", "scissors"];
const randomIndex = Math.random() * computerOptions.length;

console.log(computerOptions.at(randomIndex));

Try it yourself on CodeSandbox.

With Math.random(), we get a floating-point number between 0 (inclusive) and the array length. Then, when the .at() method receives this floating-point number as an index, it considers the value before the decimal point and returns the element at that index.

Using the square bracket notation for the same task is not possible unless we first floor the random number (that is, round the number down to the nearest integer), as seen in the code below:

const randomIndex = Math.floor(Math.random() * computerOptions.length);

console.log(computerOptions[randomIndex]);

This is because the bracket notation returns an undefined value for numbers with decimals:

const arr = [1, 2, "three", 4, 5, true, false];
console.log(arr[0.6]); // Expected Output: undefined

The .at() method saves us the extra steps of using Math.floor to floor a random number.

Browser support

At the time of writing this tutorial, the .at() method works pretty well with the popular modern browsers, except a few. See browser support here.

Conclusion

The .at() method, as we have seen in this tutorial, is pleasant when grabbing items based on their index. It is also concise to use compared to the preexisting methods.

If you have any questions or contributions, please share them in the comment section. And if you like this tutorial, endeavor to share it around the web.

Try it for free.

# data[].attributes.attachment_link.title
Using the new JavaScript .at() method - LogRocket Blog

# data[].attributes.attachment_link.description
The JavaScript .at() method was introduced in the August release of the ECMA International TC39's relative indexing proposal to allow developers to grab elements based on their indexes. Selecting elements in JavaScript is a common occurrence in development, but, before the introduction of the .at() method, JavaScript had existing methods and techniques to select elements or characters from the start or end of lists or within a string.

# data[].attributes.attachment_link.readable_text
Why You Should Choose CSS Libraries Instead of Vanilla CSS

CSS stands for "Cascading Style Sheets" and is a language for styling web pages and websites. It uses a model to create sets of rules or styles for classes or components on your website. It looks like this:

A simple CSS File

I won't go further into CSS, as you probably already know it.

Why do we need to improve CSS?

Well, Vanilla CSS has quite a clunky model. You have to keep all of your styles in a separate file or use the <style> tag. This means you end up with loads of files looking something like this:

A cluttered src folder

Another catch about CSS is that properties like display and transition are hard to understand unless someone experienced teaches you them. Sometimes they're also harder to use or differentiate, like align-items and align-content sound virtually the same but are reasonably different.

The solution people thought up for this was a brand new idea: Utility classes. These classes are already programmed into a CSS file that you import in your HTML (or somewhere else!). You use these classes, like bg-red-500 or btn-primary to easily apply common (or not so common) CSS rules to your components. This also makes your code cleaner and easier to read for your colleagues or just for yourself!

Today, the two libraries we'll be looking at are Bootstrap and Tailwind CSS, both of which are extremely well known and popular in the CSS and web development community. We'll also look at why you probably shouldn't use Vanilla CSS.

# data[].attributes.attachment_link.description
CSS stands for "Cascading Style Sheets" and is a language for styling web pages and websites. It uses a model to create sets of rules or styles for classes or components on your website. It looks like this: I won't go further into CSS, as you probably already know it.

# data[].attributes.attachment_link.readable_text
Welcome to Product Hunt! 👋

The place to launch and discover new tech products.

For the first 4 hours of the day, we're hiding upvotes to help every product get a chance to catch your interest. Read more

💌 Get the best of Product Hunt, directly in your inbox.

Clerk - Drop-in authentication & user management for React

Clerk - Drop-in authentication & user management for React

Clerk - Drop-in authentication & user management for React

# data[].attributes.attachment_link.title
Product Hunt - The best new products in tech.

# data[].attributes.attachment_link.description
Product Hunt is a curation of the best new products, every day. Discover the latest mobile apps, websites, and technology products that everyone's talking about.

# data[].attributes.attachment_link.readable_text
Give a boost to your coding speed

Photo by Paul Esch-Laurent on Unsplash

VS Code is one of the most popular editors for web development. When writing code, we often require certain formatting actions, and a lot of them are supported by VS Code itself. While most actions can be found from Menu options, having hands-on keyboard shortcuts can help improve your coding speed by a lot.

# data[].attributes.attachment_link.title
15 Useful VS Code Shortcuts to Boost Your Productivity

# data[].attributes.attachment_link.description
VS Code is one of the most popular editors for web development. When writing code, we often require certain formatting actions, and a lot of them are supported by VS Code itself. While most actions can be found from Menu options, having hands-on keyboard shortcuts can help improve your coding speed by a lot.

# data[].attributes.attachment_link.readable_text
Emmet is a plugin for many popular text editors which greatly improves HTML & CSS workflow:

You've already known how to use Emmet abbreviations: its syntax is inspired by CSS selectors.

Each abbreviation is transformed in runtime: just slightly change its name to get a different result.

With Emmet you can quickly write a bunch of code, wrap code with new tags, quickly traverse and select important code parts and more!

Users can easily add new snippets and fine-tune Emmet experience with just a few JSON files.

Dig into Emmet source code and re-use its modules to create your very own and unique actions.

Emmet is written in pure JavaScript and works across different platforms: web browser, Node.js, Microsoft WSH and Mozilla Rhino.

# data[].attributes.attachment_link.title
Emmet - the essential toolkit for web-developers

# data[].attributes.attachment_link.description
Emmet is a plugin for many popular text editors which greatly improves HTML & CSS workflow: You've already known how to use Emmet abbreviations: its syntax is inspired by CSS selectors. Each abbreviation is transformed in runtime: just slightly change its name to get a different result.

# data[].attributes.attachment_link.title
10+ Projects You Can Do to Become a Frontend Master

# data[].attributes.attachment_link.description
Learning to code can be challenging and perplexing, especially if you don’t know where to begin. The greatest approach to improve your programming abilities is to use them to create coding projects. H...

# data[].attributes.attachment_link.readable_text
Hey there folks! When you got less time to code a program, you find yourself falling prey to shortcuts. But at the end of the day, such practices only lead to poor quality code, wasted efforts, and the worst of all, bad coding habits ಥ_ಥ

Now, you might say, why do coding habits even matter if the code is working? The thing is that if you implement good coding practices, they will save you time, effort, resources, and a hell lot of headaches. Moreover, you'll get a working code too! This is a win-win situation right?

So, today I present to you 10 of the best coding practices that you can start utilizing right now ;)

1. Backup and save your work

A dead battery, blackout, fire, nuclear disaster, and the worst and cutest disaster: your cat sitting on your laptop - all of these may result in loss of data. Always make sure to save often and back up your code on some kind of version control system. This is quite a simple way to ensure that your code stays safe. The reason that I discussed this point first is that if you lose your code, how are you gonna implement the other programming practices I'm gonna talk about? I can't stress this enough, back up and save your work people!!! If you lose your work just because of a minor issue, then all your hard work, all-nighters and headaches are gonna be for nothing.

A very important habit that could help you and others that may use your code is to start each function or method you create with a comment. You can outline exactly what the function or method does, its parameters, and what it returns in the comment. You should also describe any possible errors or exceptions. Doing this practice right from the beginning keeps you consistent with commenting. You may be tempted that you could come back later and add this, but chances are that you won't.

In addition to commenting, be sure to document what your code does. This can be a short README file or a big document depending on your program. No matter what it is, this guide should explain exactly the actions that the code performs. The guide should include any dependencies and instructions on how to build, install, test, or use your code.

3. Use descriptive variable names

In the past, programmers faced a lot of difficulties while naming variables and were limited by slow, clunky interfaces. Above all, they needed to save time, ink, and paper. So they used short variable names that were often non-descriptive. Today, we don't face as many difficulties as they did. Still, the culture of vague naming conventions continues. Being descriptive while naming variables is gonna save you a lot of headaches.

These days, it's not as if you can't use short names though. But the point is that will you remember what exactly that name meant a month or even a week from now? Will some other programmer who sees your code or works on the same project understand what that certain variable was for? Most of the time, this happens if you don't add comments;

To avoid such things, the names should be descriptive For example, instead of simply writing "getLowest", you might write "getLowestAttendance". Think a bit about what you're actually trying to do with your code. Then name the variables or even the functions used in your code, appropriately.

4. Do not hard code

For all those who don't know what is hard coding: It is fixing data or parameters in a program in such a way that they cannot be altered without modifying the entire program.

Avoid hard-coding anything, other than constants. System-level settings, usernames, passwords, etc. should never be hard-coded. Hard coding could be seen as irresponsible with major consequences. If your "hard-coded" code ever becomes accessible, it represents a huge security risk when endpoints and access credentials are exposed. Moreover, security pitfalls should always be avoided, at any cost. Safety is a good coding practice as well as the best practice for every single step of the project.

5. Write readable and efficient code

Every person has their own coding standards. Some might prefer one style over the other when it comes to certain things like naming conventions, file structure, etc. There are IDEs where you can set your preferred style. When all the files of the projects use the same style, naming convention, spacing, etc., your code becomes easier to read and understand.

Yes, I know that everybody wants to be as efficient and optimized as possible. Sometimes programmers flex their skills and talents by writing complex code. But the thing is that nothing matters when no one can even read your code! I don't know who said this but;

Readable code is understandable code

6. Test your code

This is a vital programming practice. Nothing matters if your code doesn't work. While coding, if you ever come across an error or an exception, don't brush this off. It could be a sign of a great disaster. Even if the bug is small and can be fixed later, still, remove that bug now. I'll repeat that for the people in the back, remove that bug now people! Chances are that you are gonna forget about little Mr. Bug and he's gonna come haunt you later on.

Don't assume that everything's gonna go perfectly. If there is an exception, deal with it immediately. Handling exceptions can make your code longer Yes, this can make your code longer and possibly even subtract from its readability, but ignoring the problem doesn't make it go away. I don't think anyone would want their code going out into the world with any sort of error that they knew they could have possibly fixed.

Automated testing tools can also help to validate builds and releases while making your code more supportable. These tests are a form of documentation. They will tell you how the code is supposed to perform. Never sweep any coding problem under the rug. Test your code often even while writing it and make the changes required, so that you save yourself from any future hassles.

7. Limiting your line length

Ever read a newspaper article? Or a blog article? Our eyes always like to read tall and narrow blocks of text as we find reading long lines hard. Therefore, even while coding, limit your line length to 80-90 characters. This would be a good length if you are reading code from a terminal window. Keep your lines short and split your code in small blocks so that everything piece of code would fit in perfectly in a decent-sized window. If you are writing a big program, then divide it into short sections, adding a comment at the top of each one explaining its function. Keep your code short and simple but make sure that it is efficient too!

8. Collaborate

As a programmer, you sit in front of your desk a lot, alone. If you can't do something you may also want to smash that desk too. But things can be different when you collaborate with someone, be a part of a team. You can share your progress and ideas with them. Different minds sitting together working on something may lead to new and better ideas.

If you're an experienced programmer, you may mentor a junior programmer. Maybe you could learn something too while doing so. If you're fresh out of school, you might find a mentor who can teach you something. Moreover, while working with your team, you just might become friends and this may lead to more adventures. Collaboration is one of the most overlooked coding practices, but it is an essential one.

9. Be consistent

A consistent programmer is a good programmer. No matter what you do, consistency is important. For example, when you're making a new method with functions that matches an existing one, be sure to use a comparable name, parameter order, and structure for the code's body. The same can be used for classes. The new class created should also have the same interface and match any new names with those already existing. If you find out that there is no convention for something you are working on, create one by yourself and then just stick to it. This is a good practice that will make your code more readable and help you to find any bugs or errors easily.

10. Have fun

At the end of the day, it's important to remember why you got into coding in the first place! Hopefully, it was because you enjoy it. If you are a programmer, then you spend a large number of hours writing code, so you should always try to have fun. Work on projects that intrigue you. Work in a place or in an environment that you like and are comfortable in. Be around people that you like to be around. Remember that, if you aren't happy, then you can't write a code that is gonna make your employers happy. So, have fun while coding!

Conclusion

Good coding practices are all about writing readable code, being consistent, handling errors efficiently and saving everything to version controls. But they're also about having fun and enjoying the process of what you're doing. If you follow these practices, you're gonna start coding like a pro in no time ;)

# data[].attributes.attachment_link.title
Top 10 Programming Practices to Code like a Pro

# data[].attributes.attachment_link.description
Hey there folks! When you got less time to code a program, you find yourself falling prey to shortcuts. But at the end of the day, such practices only lead to poor quality code, wasted efforts, and the worst of all, bad coding habits ಥ_ಥ Now, you might say, why do coding habits even matter if the code is working?

# data[].attributes.attachment_link.title
7 useful HTML attributes you may not know

# data[].attributes.attachment_link.description
HTML is the cornerstone of web development. Yet, many aspiring programmers merely skim the surface...

# data[].attributes.attachment_link.readable_text
JavaScript UI tools for building efficient interfaces of web applications, quickly

If you came here looking for highly popular JavaScript libraries, let me save you some time. This blog post isn't for you. There are a plethora of resources out there talking about the "top so and so" JavaScript resources. I don't want to add to the pile.

I am here to talk about the real MVPs, the lesser-known gems that don't get the due attention in the overcrowded JavaScript ecosystem.

Some of these tools are libraries and some of them are frameworks. However, most of them are emerging technologies, carrying immense potential, waiting to be tapped by beginner, intermediate, or advanced level developers.

So without further ado, let me get straight to the point, Here's a curated list of JavaScript UI and CSS tools that have become a part of our design and development processes in 2021:

Most of you must have heard Ryan Dahl's talk in the JSConf EU in 2018. In the talk titled " Top 10 Things I Regret About Node.js," he explains how Nodejs hasn't grown well in response to JavaScript's evolving capabilities.

So he started working on another, improved run time environment called Deno.js. Yes, Deno is the anagram of Node and is essentially a collection of all the things Ryan had missed out on building in Node.js.

One of the striking features of Deno (in contrast to Nodejs) is its enhanced security protocols. When you use Deno as a run-time environment, it executes the code in a sandbox. That means the run time environment can't access the network, environment variables, or the file system unless you give them permission to do so.

I like to use Deno as a JavaScript library whenever I feel NPM is going to be too problematic for a certain project. With Deno, you can import packages just by using the URL of the concerned package.

Here is an example of the code you need to write for importing a Deno package:
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
So you can host the modules you create wherever you like and import them directly using the URL.

If your modules are reusable, don't worry about typing the URL time and again. You can just re-export the module from a local file on your system.

On top of that, Deno is browser-compatible, you just need to add a bit of code to transpile the code to the latest ES version.

And the TypeScript support it offers is tremendously useful!

There are JavaScript frameworks like Angular and React that come packed with tons of features and strong communities. And then there is Svelte.

Svelte is a relatively newer front-end JavaScript framework that is ideal for beginner and intermediate level developers. It has an extremely easy learning curve so the developers aren't burdened with a plethora of new tools to learn.

However, its most attractive feature is its ability to convert the app code into JavaScript at the build time itself. So no more diving into the complexities of code conversion at run time!

Like Angular and React, Svelte too has a component-based architecture. You could use the entire framework for your app's front-end or you could only ship the components you wish to use.

Also, the boilerplate code requirements while using Svelte is quite less compared to other frameworks. As a beginner, you could simply use basic technologies like HTML and CSS to write the code. Whenever I have a small team of developers working on a small project, Svelte is my first choice for quick front-end development.

Well, Ext JS is more of a framework than a library for how comprehensive it is with its features for front-end development. But it's not too vast and you can choose the components you want to integrate with your web project while ditching the rest.

There was a time Ext JS was gaining huge popularity as a useful tool for creating data-intensive HTML5 apps. But soon, the buzz began to fade and questions like " Will Ext JS die soon " started appearing on the Stack Overflow-like platforms.

I still believe it is a great tool for building quick cross-platform web applications with its library of 140+ UI components. Even though it's not as sophisticated as other top JavaScript frameworks but hey, having a Starbucks in the town doesn't mean we don't need the local cafes, right?

From grids and trees to forms and menus, you can find decent options for a vast variety of widgets in the collection. Moreover, Ext JS comes with in-built design accelerating tools like Stencils and Themer.

So prototyping a web application with Ext JS is both quick and exquisite.

Integrate Sencha Test with Ext JS and you can easily automate end-to-end as well as unit testing for the app. Talk about fast release cycles for newer, enhanced versions of the project!

Gatsby JS has been a reliable static-site generator for quite a few years now. Especially for building static progressive web apps, it's a great tool that is always in sync with the latest web standards.

Obviously then, it leverages modern tools like Reactjs, GraphQL, WebPack, and ES6+ versions to build the web app.

Speaking of WebPack, did you know Gatsby JS makes it incredibly easy to optimize your web app for performance? All you have to do is write the source code. Gatsby JS will find the most efficient WebPack configuration to suit your code and compile it automatically!

Moreover, Gatsby JS is based on Google's PRPL architecture. That means, it Pushes and Renders critical resources for the initial routing of the app. It then pre-caches the rest of the routing and implements lazy loading to reduce the app load time massively!

Gatsby JS has a vast library of over 2000+ plug-ins for quick design and development of various functionalities. It also lets you integrate or import data from APIs, CMSs, databases and other multiple sources.

What distinguishes Gatsby JS from other static site generators is its ability to avoid re-executing the redundant parts of the app code. So its capable of building and deploying web apps at least 2.5x faster!

Web components are like the ready-made building blocks for development, only they are much more customizable and flexible than frameworks. Polymer is a JavaScript library that lets you leverage the power of web components in order to optimize your design and development processes.

Polymer has a massive library of reusable web components for a range of elements - from buttons, maps, and toolbars to core elements for front-end development.

In fact, you can also create your own web components using LitElement, Polymer's own base class for building extremely light-weight web components. You can use these web components wherever you use HTML, including your main document and a comprehensive JS framework.

One of the critical features of Polymer is its Shadow DOM. It's a technology that lets you encapsulate your web components such that they remain individual and unaffected by the changes in the overall application code.

Polymer is one of the best JavaScript libraries to use in 2021 for how it eases the collaboration between designers and developers.

There is no complexity involved in matching the source code to suit the design specifications. Both the designer and the developer can use Polymer's LitElement to take care of their respective jobs.

Already quite popular, Bulma is an open-source CSS framework based on Flexbox. Meaning, you don't have to deal with two-dimensional layouts while designing the UI of your app. It lets you focus on either a row or a column-based layout while writing mode of the document.

Bulma is built to ease the development process of web apps, especially from the CSS perspective. So it's pretty easy to learn and use. Otherwise, what's the point of using a CSS framework if you have to spend time learning a new technology!

The biggest advantage of using Bulma for a web application is its responsiveness. With Bulma, you can rest assured that your app will be fully optimized for mobile views.

But I love it the most because it's so flexible!. With a modular architecture, Bulma enables you to use only those elements that you need for your web app. That means, complete access to a wealth of resources with no technical debt.

Lastly, the framework is highly customizable. You can choose the size of the grid layouts once and the rest of the columns (or rows) will adjust to the size automatically. (Remember, Flexbox?)

Bulma comes with comprehensive documentation and is supported strongly by a community of over 200,000 developers. So kickstarting your project using Bulma CSS won't need much of an effort.

Despite being a low level CSS framework, Tailwind CSS has gained huge popularity as a highly customizable tool for building efficient design elements.

In contrast to the likes of Bootstrap, Tailwind CSS doesn't provide you with ready-use components. Instead, it gives you foundational components that you can use as building blocks for designing custom interfaces for your web application.

With Tailwind CSS, you don't have to worry about naming classes of all the elements you create. It has an in-built system of utility classes that you can use for most of your components. This makes the whole process of CSS development less painful, if I may say so.

Tachyons is a light-weight yet comprehensive CSS toolkit based on the mobile-first architecture. It helps you build highly responsive web applications with minimal coding effort, especially on the CSS front.

The entire library collectively weighs not more than 14kb! So even after you add images, HTML markup, and other lighter JS tools, it's absolutely possible to still keep your web page size under 100kb.

Also, Tachyons is fully modular. So you have the liberty to integrate only a few elements from the framework into your web project. You could choose a pre-built component or element from its open-source library or you could easily build one with its single-purpose classes.

It's not necessary for a tool or technology to be mainstream in order for us to trust it. There are tons of very resourceful JavaScript tools that haven't yet gained a lot of popularity and I shared some of my personal favorites in the content above. However, please do check out the official websites/GitHub repos of these tools to know more about their features, pros, and cons in detail.

# data[].attributes.attachment_link.title
8 Interesting JavaScript UI and CSS Tools You Must Try in 2021

# data[].attributes.attachment_link.description
If you came here looking for highly popular JavaScript libraries, let me save you some time. This blog post isn't for you. There are a plethora of resources out there talking about the "top so and...

# data[].attributes.attachment_link.readable_text
In this post I want to tell you my first experience with Figma, how I am defining my design system, what resources I have found and how to create slides with your own brand.

A promise is a promise, here is the last article I've been working on 🙈

I tell you my experience using @figmadesign, how I've organized it and the resources I've used.
I hope you discover something new or motivate you to start using it 🎉

dawntraoz.com/blog/a-front-e...

How a design system is helping me

Creating my own design system has helped me:

To be consistent between the products I create. For example, my website uses the same components, style and typography as my slides. It helps to be aligned and create a brand.

To reuse elements, creating components and use them in new pages, products or sections. Allowing me to save a lot of time both adding new content and modifying existing one.

Although a design system is time-consuming, the good thing is that you can do it little by little and define and improve it over time.

The next steps will be to create guidelines, in case one day I work with more people, and to unify the designs of my side projects with Dawntraoz's brand, but little by little.

For now, I leave you with this design system made in Figma, which is amazing, 🦄 Pegasus Design System

If you want to know more about this topic, I recommend you to take a look at Míriam González's talk, where she shares super useful resources 👉 Design Systems 101

First steps learning Figma

I started reading the Figma Basics tutorial, where the concepts behind Figma are explained. I'll summarize what I found very useful in my journey:

Frames: the Artboards of Figma where you have preset sizes as standard Desktop, Tablet and Phone sizes.

Constrains: to fix elements to the sides of their parent, this is useful to resize the elements when you resize the screen.

For example, the header element is fixed top-left-right to its parent - Homepage Frame-, when the homepage width increase the header will grow with it.

You can also check the chekbox - Fix position when scrolling- to simulate position: sticky.

Components: to reuse elements of the design, creating new instances of them.

To create a component you just need to right click the element already created and select the option Create Component.

Once it's ready, to create a new instance: go to the Assets panel and drag & drop the component.

Styles: to define a set of properties like colors, texts, shadows... which could be reused across the design.

For example, to create a generic text: define the properties of your text, i.e. font family, size, decoration, ...; then, click on the Styles icon (the icon with 4 dots) and click on the + icon to save it.

If you want to know all the properties you can add to your custom text styles, check Typography systems in Figma.

To reuse it, just click on the Styles icon again and select the one you want. You will see something like this:

Smart selection: selecting multiple elements using Ctrl+Shift+Click allows you to adjust spacing between elements (click & drag - pink lines) and change the position (drag & drop - pink circles).

Exporting, commenting & sharing: you can export in PNG, JPG, SVG and PDF formats all your elements and designs, more people will be able to give you feedback on your design by commenting on it and you will be able to share your designs via a link with anyone.

To get to know these points in detail and practice them with a use case, just register at Figma ✨ It's free for your first 3 projects 🎉

Organising my content

When I got to know the basics of Figma, I started to organise my project and to turn my website into a design, which was already designed (not ideal, but that's how I started).

Next, I will tell you how I have set up the project by sections.

Style guide: Colors, typography and iconography

Two of Figma's most powerful features are components and styles. They let you reuse UI objects and attributes so you can maintain designs systematically at scale. - by Figma

As I went through the main page of my website, I saved the styles, both colours and fonts, that I defined.

Once I had defined all of them, I created a page called Style guide where I represented the colours, their name and their hexadecimal value, as well as the typographies for each type of heading or text.

And the same thing happened with the iconography, as I added the SVG icons to my design I created components in the Style guide page. This way I can control from one place how they are displayed and export them in isolation.

Components

For those parts that make up my design and that I'm going to reuse, it could be none other than the components section. This is where the variants and properties that Figma offers us come into the picture, let's see what it's about.

I will tell you how I've used them in my project, but as I'm not an expert, it's better to look at the recommendations Figma gives us at https://www.figma.com/best-practices/creating-and-organizing-variants/

Well, the first thing I had to do was to create the content of what was going to be my first component, a custom heading with a gradient by colour. This component had a different size in desktop & mobile and a different gradient in light & dark mode, a total of 4 variants.

To define the variants I had to take into account 2 properties: the screen, which corresponds to the desktop or mobile version, and the mode, being light or dark.

In the image above the first heading on the top left would be the desktop version in light mode, and on the bottom right the mobile version in dark mode.

This grouping could have been done differently, we will see this in the next section with the Header layout component.

Layout

Although our layout elements, the header and footer, are components in Figma, it made more sense to me to have a special section for them and that's why I created the Layout page.

As I mentioned before, when I had to create 4 variants of each component to cover both desktop and mobile in light and dark mode, I wondered if I had done it correctly and when I asked on Twitter my doubt was solved.

That's how I discovered the base components (the master piece). Basically, when you create a variant you are making a copy of the content, not an instance, and when I wanted to modify something on desktop, for example, I would have to do it for light and dark mode and that's not ideal. That's why the base component has saved me!

Header
In the Header/Base component I design the desktop and mobile version of the header, I only take into account the screen property. Then I create the Header component that uses the Header/Base instances and there I design the light and dark mode variants. This way, the day I want to change something in the mobile/desktop design I will only have to apply it in Header/Base and Header will be updated automatically!

Footer
For the footer it was easier because it doesn't vary depending on the mode, so a Footer component was more than enough. But one thing I discovered when trying to add a border bottom to the footer titles is that I needed a plugin to help me apply the border I wanted: Border

Once the header and footer were already created, I was adding them to the page layouts, until I decided to create a template to reuse the structure and add the container spacing in the body section. As you can see below:

Grids

To avoid having to redefine the size and fit the components to the columns every time I wanted to modify one of the grids, I decided to create a section where I could isolate them and instantiate them in the design of my pages.

For example, for the blog listing I created a two column grid on desktop with a full width version for mobile (using variants with a screen property):

Pages

And now, having put all the pieces of the design together, it's time to define our pages!

Making use of the template we created on the layout page and choosing the corresponding heading component for desktop or mobile in light mode, as well as the listing grid, we are ready to go 🎉

Article cards

And as I wanted to have a space for the feature images of the articles, I created a page called Article cards, where I design the images and export them.

To export the frame with the feature image, I added one export option and set the type of file I wanted to export to JPG. Then I clicked the preview tab to see the result and the export button to get the picture.

Everything you need to know about export by Figma

Using plugins

After defining my project I decided to do some research and look for cool stuff. Let's see what I have found 🔍

Custom Slides

I'm quite proud of this part, to be honest 🙈.

I recently started giving talks but, doing it on my own, I didn't have a company template to make the slides. So, I decided to use free templates that I found on the internet. But, as you can imagine, it had nothing to do with my web design.

Searching on Google how to make my own slides with Figma, I found this video Export slide deck presentations from Figma to Google Slides, which explains the use of a plugin to convert frames made in Figma into Google Slides or, even, interactive slides generated in an url.

The plugin is Pitchdeck Presentation Studio, which I highly recommend. This is how it looks like:

There you can add animations to the elements (not compatible with Google Slides), add speaker notes, change the slides order, ...

The wonderful thing is to be able to use the components of your web design for your slides, what a fantasy 🦄

Illustrations

As I created new slides, I wanted to put in some cool geometric shapes and I thought, why not illustrations?

When I think of illustrations I always think of Humaaans by Pablo Stanley, so I went straight to his website and found a wonderful plugin for figma so I could add my illustrations without leaving here, that's amazing 😍.

The plugin is called Blush and you can find it in the community or by going directly to its page 👉 https://www.figma.com/community/plugin/838959511417581040/Blush

For TailwindCSS lovers

It is possible to export all our styles, colors and typography, as a preset for tailwind.config.js by using the plugin: https://www.figma.com/community/plugin/785619431629077634/Figma-Tailwindcss

Side note: If the plugin doesn't have a description on how to use it, it's because you need to go to Files tab (or right click) > Plugins > Click on the plugin you want to use and voilà!

This is the result by using it in my project:

# data[].attributes.attachment_link.description
In this post I want to tell you my first experience with Figma, how I am defining my design system, what resources I have found and how to create slides with your own brand.

# data[].attributes.attachment_link.readable_text
When displaying content on a webpage, there's often a need to layout the content in a particular way. For example, we may want the header and footer sections to span the entire width of the viewport while the main content be organized as a three-column layout. Header section itself may be divided into a fixed-width logo section to the left and a flexible-width title section to the right.

CSS Grid Layout is a standard that gives user interface designers a powerful system to implement layouts with ease. It's part of the CSS3 specification standardized by W3C.

It's meant to complement and not replace earlier systems such as CSS Flexbox.

Discussion

Why should I adopt CSS Grid when there's already CSS Flexbox?
Traditionally, layout was done using HTML tables. Then came CSS properties display, float and position that allowed us to control the layout. While these are still relevant, Flexbox came along to provide an easier way to distribute space and align content.

The limitation with Flexbox is that it does layout only in one direction. Thus, items can be laid out horizontally but not vertically at the same time. Even if the items were to wrap across multiple lines, items on each line will not be aligned to those on other lines. Via nesting, Flexbox can be used to create two-dimensional layouts but CSS Grid is easier to use.

CSS Grid is capable of aligning items both horizontally and vertically. Interestingly, items within the grid can also overlap, which neither Flexbox nor a HTML table element is capable of doing.

CSS Grid doesn't replace Flexbox. Grid items can be flex parents and vice versa.

Which are the key building blocks of CSS Grid?

CSS Grid has the following parts:

Container: This is the element that contains the grid within it. It's defined by CSS display: grid.

Item: Immediate child elements of a container are grid items. Grandchildren and further nested elements are not considered as grid items.

Line: A grid is split into rows and columns using grid lines. Lines also define the container's borders. Lines are numbered, starting from 1. Thus, a grid of m rows will have m+1 horizontal lines; of n columns will have n+1 vertical lines.

Track: A grid track is a generic term for a grid row or column. It's the space between two adjacent grid lines.

Cell: This is an intersection of a row and a column. It's the smallest unit of the grid that can be referenced.

Area: This consists of one or more adjacent grid cells.

What are the different ways of specifying width in CSS Grid?
Grid items, rows and columns can be sized explicitly using CSS properties grid-template-rows and grid-template-columns. For example, grid-template-columns: 90px 50px 120px defines three columns with exact sizes.

What if we had five items but only two columns are defined? The extra three grid items will be sized implicitly. If grid-auto-flow: column, we'll end up with five columns. If grid-auto-flow: row, we'll end up with three rows with the last row having only one item.

For explicit sizes we can use px, em, %, etc. Fractional sizes ( fr) can also be used. Thus, grid-template-columns: 1fr 2fr will make two columns, with the second one twice as wide as the first. While px specifies fixed sizes, fr specifies flexible sizes. Fractional sizes are calculated based on remaining space after other length values have been processed. For example, given grid-template-columns: 3rem 25% 1fr 2fr, the calculation would be 1fr = ((gridwidth) - (3rem) - (25% of gridwidth)) / 3. The value auto will stretch grid item to fill remaining space.

How do I control the alignment of content in CSS Grid?

A grid item can be aligned within its cell or area using CSS property justify-self for horizontal alignment and align-self for vertical alignment. These effectively adjust margins for the items. Each of these properties can take values start, end, center, or stretch.

What if we wish to apply the same alignment to all grid items? This is done by specifying CSS properties at the container level. Use justify-items for horizontal alignment and align-items for vertical alignment. As a shortcut, there's also place-items that specifies alignment in both directions.

What if all the grid's tracks take up a space smaller the container? Then justify-content and align-content becomes useful not just for alignment but also for adding spaces in the right places to fill the container. These effectively adjust padding for the container. Some allowed values include normal, start, end, center, stretch, space-around, space-between, space-evenly, baseline, first baseline, and last baseline.

Alignment works for both inline and block elements.

What are named areas and where are they useful?
We can make an item span multiple columns using grid-column-start, grid-column-end, grid-row-start, and grid-row-end. Shortcuts for these are grid-column and grid-row. For example, grid-column: 3 / span 2 says that item will start from third column and span two columns.

Grid areas offer a simpler way to avoid using grid line numbers. Areas can be only rectangles. Areas are named for easy referencing. Gaps can exist between areas but not between cells within an area. Gaps themselves can be set using grid-row-gap and grid-column-gap, with grid-gap as a shorthand to set both. Grid gaps are also called gutters.

Within HTML elements, use CSS property grid-area to name the target area. This tells exactly in which area this content must be placed. The mapping of grid cells to grid areas is done using the grid-template-areas property. For a responsive design, we could use media queries to switch between different definitions of template areas without duplicating the content.

When there's nested grids, what's the use of subgrids?
Consider the use of grids to lay out cards. With nested grids, each card has an inner grid that's used to organize card title, an image and a description. Layout of contents in the inner grid is independent of the outer grid. Moreover, one card is not aware of alignment of contents in another card. This means that if some card titles run into multiple lines, subsequent content within the inner grid will not be aligned across cards (the outer grid).

Subgrid solves this problem. A subgrid defers the definition of its rows and columns to its parent grid container. Content of the subgrid influence the sizing and alignment of its parent container.

A subgrid can be created with { display:grid; grid-template-columns:subgrid; grid-template-rows:subgrid; }. It's possible to create rows-only or columns-only subgrid. Within the subgrid, we may not want extra spacing between rows. This is achieved with row-gap:0.

Could you share additional technical details on CSS Grid?
It's interesting to note that grid line numbers can be negative. Value -1 refers to last line; value -2 is last but one line; and so on. Also, fractional widths can be floating point numbers.

With fractional units, available space is filled up but it still obeys the minimum size of container or the content within. Sizes are not calculated upfront. Only after content is placed into grid items, the sizes of grid tracks are calculated.

By default, grid items will be stretched to fit the grid area. Avoid using percentages in paddings or margins on grid items. Number of rows and columns can be defined using grid-template-areas, grid-template-rows and grid-template-columns. If there's conflict, the larger number will be used.

Don't assume you need breakpoints, for example, to reflow content with varying number of columns. Sizing with only percentages will not help you exercise the full power and flexibility of CSS Grid. CSS Grid is simple enough to be used directly. Don't look for a grid framework.

What are some resources for beginners to learn CSS Grid?
From the many online resources to learn CSS Grid, we mention a few: A Complete Grid Guide by CSS-Tricks, Rachel Andrew's Grid by Example and Layout Lab by Jen Simmons.

An interactive CSS Grid cheatsheet from Ali Alaa is handy.

For debugging CSS Grid, there are browser add-ons that developers can use. Firefox DevTools comes with Grid Inspector to inspect the grid and show line numbers and grid area names.

Most browsers support CSS Grid, including partial support from IE11. See Can I Use to see current support.

Milestones

The Swiss formalize the use of grids as a design tool. They see grids as bringing order to a design layout.

Frame-based layout via stylesheets is proposed.

CSS3 Advanced Layout Module is proposed. By April 2009, this becomes CSS Template Layout Module. The idea of CSS Grid Layout closely follows from these early drafts. However, these early proposals are not adopted by browser makers.

W3C publishes a working draft of CSS Flexible Box Layout or Flexbox. After multiple revisions, first Candidate Recommendation of Flexbox is released in September 2012.

Microsoft needs a flexible layout tool for the web and native app development on Windows. With some inspiration from Silverlight, Microsoft ships IE10 with an implementation of a grid layout behind -ms- vendor prefix. This is followed with a W3C working draft of CSS Grid Layout. Thus, for the first time W3C gets a draft along with a working implementation.

After many months of internal development, Twitter open sources Bootstrap. It's a CSS framework that enables easier creation of layouts based on a 12-column grid. CSS Grid provides a more flexible layout since designers need not start with 12 columns.

W3C publishes CSS Grid Layout Module Level 1 as a Candidate Recommendation. This is also the year when many major browsers start supporting CSS Grid.

W3C publishes the first working draft of CSS Grid Layout Module Level 2. Level 2 adds subgrid capabilities and allows nested grids to participate in the sizing of parent grids. It also adds aspect-ratio-controlled gutters. In December 2019, Firefox becomes the first browser to implement subgrids and continues to be the only browser even in December 2020.

References

1. Aderinokun, Ire. 2017. "CSS Grid Layout Terminology, Explained." Bitsofcode, February 07. Accessed 2019-05-27.

2. Andrew, Rachel. 2015. "Three years with CSS Grid Layout." November 03. Accessed 2019-05-27.

3. Babich, Nick. 2019. "Top Website Layouts That Never Grow Old." Xd Ideas, Adobe, November 8. Accessed 2020-07-21.

4. Caniuse. 2020. "subgrid." Caniuse. Accessed 2020-12-12.

5. Coyier, Chris. 2019. "Quick! What's the Difference Between Flexbox and Grid?" CSS-Tricks, February 12. Updated 2019-02-14. Accessed 2019-05-27.

6. CSS-Tricks. 2016. "A Complete Guide to Grid." CSS-Tricks, November 06. Updated 2019-04-03. Accessed 2019-05-27.

7. Gustafson, Aaron. 2017. "The Story of CSS Grid, from Its Creators." October 19. Accessed 2019-05-27.

8. JavaScript Teacher. 2018a. "CSS Grid - The Swiss Army Knife For Website and Application Layouts." Medium, July 31. Accessed 2019-05-27.

9. JavaScript Teacher. 2018b. "CSS Grid - The Beginner's Guide." freeCodeCamp, July 30. Accessed 2019-05-27.

10. Layout Land. 2018a. "Flexbox vs. CSS Grid - Which is Better?" Layout Land, on YouTube, January 29. Accessed 2019-05-27.

11. Layout Land. 2018b. "9 Biggest Mistakes with CSS Grid." Layout Land, on YouTube, July 16. Accessed 2019-05-27.

12. MDN Web Docs. 2019a. "Box alignment in CSS Grid Layout." Mozilla Developer Network, March 23. Accessed 2019-05-27.

13. MDN Web Docs. 2019b. "CSS Grid Inspector: Examine grid layouts." Mozilla Developer Network, March 23. Accessed 2019-05-27.

14. Otto, Mark. 2011. "Bootstrap from Twitter." Blog, Twitter, August 19. Accessed 2019-05-27.

15. Paolino, Johna. 2019. "CSS Grid for Designers." Times Open, via Medium, January 03. Accessed 2019-05-27.

16. Rego, Manuel. 2017. "CSS Grid Layout: A New Layout Module for the Web." Blog, WebKit, March 09. Accessed 2019-05-27.

17. Rendle, Robin. 2017. "Does CSS Grid Replace Flexbox?" CSS-Tricks, March 31. Accessed 2019-05-27.

18. Statuscode. 2018. "CSS Grid Explained Quickly (with diagrams and code)." Statuscode, on YouTube, January 07. Accessed 2019-05-27.

19. Suh, Jonathan. 2019. "Homepage." Learn CSS Grid. Accessed 2019-05-27.

20. Tubik Studio. 2017. "Best Practices for Website Header Design." UX Planet, on Medium, June 2. Accessed 2020-07-21.

21. Vujasinović, Ekaterina. 2020. " CSS Subgrid - How to Build Complex Layouts in a Simple Way." Ditdot, August 19. Accessed 2020-12-12.

22. W3C. 2005. "CSS3 Advanced Layout Module." W3C Working Draft, December 15. Accessed 2019-05-27.

23. W3C. 2009. "CSS Template Layout Module." W3C Working Draft, April 02. Accessed 2019-05-27.

24. W3C. 2011. "Grid Layout." W3C Working Draft, April 07. Accessed 2019-05-27.

25. W3C. 2017. "CSS Grid Layout Module Level 1." W3C Candidate Recommendation, December 14. Accessed 2019-05-27.

26. W3C. 2018a. "CSS Flexible Box Layout Module Level 1." W3C Candidate Recommendation, November 19. Accessed 2019-05-27.

27. W3C. 2018b. "CSS Grid Layout Module Level 2." W3C Working Draft, June 28. Accessed 2019-05-27.

28. W3C. 2018c. "CSS Box Alignment Module Level 3." Editor's Draft, December 06. Accessed 2019-05-27.

Further Reading

1. Aderinokun, Ire. 2017. "CSS Grid Layout Terminology, Explained." Bitsofcode, February 07. Accessed 2019-05-27.

2. Coyier, Chris. 2019. "Quick! What's the Difference Between Flexbox and Grid?" CSS-Tricks, February 12. Updated 2019-02-14. Accessed 2019-05-27.

3. CSS-Tricks. 2016. "A Complete Guide to Grid." CSS-Tricks, November 06. Updated 2019-04-03. Accessed 2019-05-27.

4. Gustafson, Aaron. 2017. "The Story of CSS Grid, from Its Creators." October 19. Accessed 2019-05-27.

5. JavaScript Teacher. 2018b. "CSS Grid - The Beginner's Guide." freeCodeCamp, July 30. Accessed 2019-05-27.

6. Suh, Jonathan. 2019. "Homepage." Learn CSS Grid. Accessed 2019-05-27.

Article Stats

Cite As

Devopedia. 2020. "CSS Grid Layout." Version 6, December 12. Accessed 2021-09-09. https://devopedia.org/css-grid-layout

Copy citation

# data[].attributes.attachment_link.description
When displaying content on a webpage, there's often a need to layout the content in a particular way. For example, we may want the header and footer sections to span the entire width of the viewport while the main content be organized as a three-column layout.

# data[].attributes.attachment_link.readable_text
Sur l'auteur

Je m'appelle Kitty Giraudel, je suis un·e développeur·se front-end français·e basé·e à Berlin (Allemagne) depuis 2015, actuellement en poste à Gorillas.

Je suis également l'auteur·e d'un livre français sur CSS intitulé CSS3 Pratique du Design Web (publié aux éditions Eyrolles), ainsi qu'un livre sur Sass (en Anglais) intitulé Jump Start Sass (publié aux éditions Learnable).

Contributions

Sass Guidelines est un projet ouvert que je maintiens sur mon temps libre. S'assurer qu'il soit toujours à jour, documenté et pertinent représente beaucoup de travail. Heureusement, je reçois l'aide de nombreux et généreux contributeurs, notamment pour la tenue à jour des différentes traductions. Pensez à les remercier !

Si vous souhaitez apporter votre contribution, vous pouvez tweeter et faire passer l'info, et le cas échéant corriger les erreurs typographiques en ouvrant une pull-request sur le dépôt GitHub.

Dernière chose avant de commencer : si vous avez aimé ce document, ou s'il est utile à votre travail ou à celui de votre équipe, n'hésitez pas à le soutenir pour que je puisse continuer de le faire évoluer !

Table des matières

À propos de Sass

Voici comment Sass est décrit dans la documentation :

Sass est une extension de CSS qui ajoute puissance et élégance au langage de base.

L'objectif ultime de Sass est de combler les lacunes de CSS. Nous le savons, CSS n'est pas le meilleur langage du monde [citation needed]. Même s'il est très simple d'apprentissage, il peut rapidement devenir confus, en particulier dans les projets à grande échelle.

Sass intervient ici comme un méta-langage, pour améliorer la syntaxe CSS afin d'offrir des fonctionnalités supplémentaires et des outils pratiques. Dans le même temps, Sass entend rester proche du langage CSS.

Il ne s'agit pas de transformer CSS en langage de programmation. L'intention de Sass est simplement d'intervenir là où CSS montre ses limites. C'est pour cela qu'il est si simple de se lancer dans Sass : il ne fait qu'ajouter quelques fonctionnalités à CSS.

Ceci étant, il y a bien des manières d'utiliser ces fonctionnalités. Certaines sont bonnes, d'autres mauvaises, comme toujours. Les recommandations qui suivent ont pour objectif de vous donner une approche documentée et cohérente de l'écriture de code Sass.

Ruby Sass ou LibSass

Le premier commit de Sass remonte à la fin 2006, il y a près de 10 ans. Inutile de dire qu'il a fait un long chemin depuis. À l'origine le projet a été développé en Ruby, mais d'autres variantes sont apparues ici et là. Celle qui a rencontré le plus de succès, LibSass (écrite en C/C++) est désormais proche de la compatibilité totale avec la version Ruby originale.

En 2014, les équipes de Ruby Sass et de LibSass ont décidé d'attendre que les deux versions soient synchronisées avant de continuer à avancer. Depuis lors, LibSass publie activement de nouvelles versions pour être toujours au niveau de son grand frère. Les quelques petites incohérences qui demeurent sont listées par mes soins dans le projet Sass-Compatibility. Si vous avez connaissance d'une incompatibilité entre les deux versions qui ne serait pas listée, n'hésitez pas à ouvrir un ticket.

Pour revenir au choix de votre compilateur, en fait tout dépend de votre projet. Si vous travaillez sur un projet Ruby on Rails, il est préférable d'utiliser Ruby Sass qui convient parfaitement dans ce cas. Il faut également garder à l'esprit que Ruby Sass sera toujours l'implémentation de référence et sera toujours en avance par rapport à LibSass. Si vous souhaitez basculer de Ruby Sass à LibSass, cet article est pour vous.

Pour des projets non-Ruby, LibSass est probablement une meilleure idée. Si vous utilisez Node.js par exemple, node-sass est tout indiqué.

Sass ou SCSS

Il règne encore une certaine confusion autour du nom Sass, et pour une bonne raison : Sass désigne à la fois le préprocesseur et sa propre syntaxe. Pas très commode, n'est-ce pas ?

En fait, Sass désignait à l'origine une syntaxe dont la caractéristique était d'être basée sur l'indentation. Rapidement, les développeurs de Sass ont décidé de rapprocher Sass et CSS en proposant une syntaxe compatible avec CSS, appelée SCSS (pour Sassy CSS qu'on peut traduire par CSS à la Sass ou CSS classieux). Sa devise : si c'est valide en CSS, c'est du SCSS valide.

Depuis lors, Sass (le préprocesseur) propose deux syntaxes différentes : Sass (pas tout en majuscules, s'il vous plaît), qu'on appelle aussi la syntaxe indentée, et SCSS. Vous pouvez utiliser celle que vous voulez, les deux sont strictement équivalentes en termes de fonctionnalités. C'est donc une question d'esthétique personnelle.

La syntaxe de Sass repose sur l'indentation pour se débarrasser des accolades, des points-virgules et autres symboles de ponctuation, ce qui produit une syntaxe allégée et raccourcie. De son côté, SCSS est plus facile à apprendre puisqu'il repose sur la syntaxe CSS à laquelle il ne fait qu'ajouter quelques fonctionnalités.

Personnellement, je préfère SCSS parce qu'il est plus proche de CSS et plus accessible aux développeurs. C'est pourquoi SCSS est la syntaxe par défaut tout au long de ce document. Si vous préférez la syntaxe Sass indentée, vous pouvez choisir cette option dans le panneau des options.

Autres préprocesseurs

Pourquoi choisir Sass plutôt qu'un autre préprocesseur ? Cette question peut toujours se poser aujourd'hui. Il n'y a pas si longtemps, l'argumentation aurait porté sur l'avantage de Sass dans les projets basés sur Ruby. Aujourd'hui que LibSass est synchronisé avec Ruby Sass, ce sont les performances de Sass qu'on pourrait mettre en avant.

Ce que j'aime avec Sass c'est son approche conservatrice de CSS. La conception de Sass est basée sur quelques principes forts : pour l'essentiel, elle découle de la conviction de ses concepteurs que (a) l'ajout de nouvelles fonctionnalités a un coût lié à leur complexité qui doit être justifié par leur utilité réelle et (b) on doit pouvoir comprendre facilement ce que fait un bloc de styles en regardant ce seul bloc. De plus, Sass est beaucoup plus attentif aux détails que les autres préprocesseurs. De ce que je peux constater, ses concepteurs sont extrêmement soucieux de supporter tous les cas d'usage de CSS même les plus borderlines, et d'assurer la cohérence globale. En d'autres termes, Sass est un logiciel créé pour résoudre de vrais problèmes, qui aide les développeurs en ajoutant des fonctionnalités utiles à CSS lorsque celui-ci se révèle insatisfaisant.

À côté des préprocesseurs, nous devons aussi mentionner d'autres outils dont on a beaucoup parlé dernièrement tels que PostCSS et cssnext.

PostCSS est souvent (et de manière incorrecte) baptisé "postprocesseur". Cette supposition, au-delà du nom trompeur, vient de l'idée que PostCSS analyserait du code CSS déjà processé par un préprocesseur. Bien que cela puisse fonctionner ainsi, ce n'est pas un pré-requis, si bien que PostCSS est désormais rangé simplement dans la catégorie "processeur".

On parle souvent de "postprocesseurs" dans la mesure où ils compilent de la syntaxe propriétaire ou non-standardisée en CSS actuel. Ceci étant dit, ils sont assez proches des préprocesseurs, à ceci près qu'ils ne font qu'ajouter la syntaxe future de CSS.

PostCSS permet d'accéder aux "tokens" des feuilles de styles (comme les sélecteurs, propriétés, valeurs), pour les manipuler en JavaScript et compiler le tout en CSS à nouveau. Par exemple, la librairie Autoprefixer qui ajoute les préfixes constructeurs est bâtie sur PostCSS. Elle analyse toutes les règles pour voir si des préfixes sont nécessaires en faisant des requêtes auprès de l'outil de support CanIUse, puis ajoute les préfixes requis ou les supprime lorsqu'ils ne le sont plus (en fonction des options choisies).

C'est très puissant pour créer des outils qui fonctionnent avec n'importe quel préprocesseur (ou même vanilla CSS), mais PostCSS n'est pas spécialement facile à utiliser (pour l'instant). Il faut avoir quelques connaissances en JavaScript pour s'en servir et son API est parfois déroutante. Si Sass prodigue un ensemble de fonctionnalités qui facilitent l'écriture de CSS, PostCSS confère un accès direct à l'AST CSS ( Abstract Syntax Tree) et JavaScript.

Pour résumer, Sass est assez simple à prendre en main et aide à résoudre la majorité des problèmes de maintenance de feuilles de styles de qualité. De son côté, PostCSS est plus difficile à appréhender (surtout sans connaissances en JavaScript) mais s'avère être extrêmement puissant. Rien ne vous empêche d'utiliser les deux. En fait, PostCSS offre même un parser officiel juste pour ça.

Merci à Cory Simmons pour son aide et son expertise dans cette section.

Introduction

Pourquoi un guide de style

Un guide de style n'est pas simplement un document agréable à lire, qui décrit l'état idéal de votre code. C'est un document-clé dans la vie d'un projet, qui décrit la façon dont un code devrait être écrit et pourquoi. C'est peut-être beaucoup pour un projet modeste, mais c'est une aide inappréciable pour créer un code propre, extensible et maintenable.

Il va sans dire que plus il y a de développeurs impliqués dans un projet, plus les guides de style sont nécessaires. Et plus l'échelle du projet est développée, plus un guide de style est obligatoire.

Harry Roberts le dit très bien dans ses CSS Guidelines:

Adopter des lignes de conduite en matière de code (on ne parle pas là d'un guide de style visuel donc) est primordial pour les équipes qui :

conçoivent et maintiennent des produits sur une durée raisonnable ;

sont constituées de développeurs de multiples horizons et aux capacités variées ;

sont constituées de plusieurs développeurs travaillant sur un même projet à un moment donné ;

accueillent régulièrement de nouveaux collaborateurs ;

ont des bases de codes sur lesquelles des développeurs différents travaillent en alternance.

Avertissement

Commençons par le commencement : ceci n'est pas un guide de style CSS. Ce document ne parlera pas des conventions de nommage des classes CSS, des patterns modulaires ou de la question des IDs dans le monde CSS. Ces recommandations ne traitent que de contenus spécifiques à Sass.

Par ailleurs, ce guide de style est personnel et par conséquent très engagé. Vous pouvez le voir comme un ensemble de méthodologies et de conseils que j'ai polis et donnés pendant des années. Il me donne aussi l'opportunité de faire des liens vers un bon nombre de ressources instructives, n'hésitez pas à vous reporter aux lectures complémentaires.

Bien sûr, ce n'est pas la seule façon de faire, et cela correspondra ou pas à votre projet. Vous pouvez choisir ce qui vous intéresse et l'adapter à vos propres besoins. Comme on dit, ça dépend.

Principes fondamentaux

Au bout du compte, s'il est une chose que je souhaite que vous reteniez de ce guide c'est que Sass devrait toujours rester aussi simple que possible.

Mes petites expériences stupides avec Sass, comme les opérateurs bitwise, les itérateurs et générateurs ou encore un parser JSON ont montré tout ce qu'on peut faire avec ce préprocesseur.

Cependant, CSS est un langage simple. L'intention de Sass est d'écrire du CSS, par conséquent il ne devrait pas être plus compliqué que le bon vieux CSS. Le principe KISS (Keep It Simple Stupid) est essentiel ici et il devrait même prendre le pas sur le principe DRY (Don't Repeat Yourself) dans certaines circonstances.

Parfois, il vaut mieux se répéter un peu pour conserver un code maintenable plutôt que construire un système lourd et inutilement compliqué qui devient difficile à maintenir en raison de sa complexité.

Encore une citation de Harry Roberts : le pragmatisme doit prendre le pas sur la perfection. Il est possible qu'à certains moments vous soyez amené à aller contre les règles énoncées ici. Si ça fait sens, si ça vous paraît juste, faites-le. Le code est un moyen, pas une fin en soi.

Étendre le guide de style

Une grande partie de ce guide de style est basée sur mes propres opinions. J'ai lu et écrit du code Sass depuis plusieurs années déjà, au point où j'ai adopté un grand nombre de principes quand il s'agit d'écrire du code CSS propre. Je comprends que tout ne convienne pas à tout le monde, c'est parfaitement normal.

C'est pourquoi je pense qu'un guide de style est fait pour être étendu. S'approprier Sass Guidelines peut vouloir dire avoir un document stipulant que le code s'en tient à ces conventions à l'exception de quelques règles personnelles ; suite à quoi ces règles seraient détaillées.

Un exemple d'extension de guide de style peut être trouvé dans le dépôt SassDoc (traduit):

Ceci est une extension de Node Styleguide par Felix Geisendörfer. Toute chose stipulée dans ce document prévaut sur une indication contraire mentionnée dans Node Styleguide.

Syntaxe & formatage

À mon avis, la première chose que devrait proposer un guide de style est de décrire la façon dont notre code doit être écrit, du point vue de son aspect.

Lorsque plusieurs développeurs sont impliqués dans l'écriture de CSS sur un même projet, il ne faut pas longtemps avant que l'un d'entre eux commence à faire les choses à sa façon. Les directives servent à éviter cette perte de cohérence, mais aussi à aider chacun à lire et à mettre à jour le code.

Globalement, voici ce que nous voulons (inspiré sans honte des CSS Guidelines) :

Une indentation à deux (2) espaces, pas de tabulation ;

Pas plus de 80 caractères par ligne ;

Du CSS écrit sur plusieurs lignes ;

Une utilisation efficace des lignes vides.

Chaînes de caractères

Ça peut paraître incroyable, mais les chaînes de caractères jouent un grand rôle dans les écosystèmes CSS et Sass. La plupart des valeurs CSS sont soit des longueurs soit des identifiants, il est donc crucial de se tenir à des règles lorsqu'on utilise ces chaînes dans Sass.

Encodage

Afin d'éviter tout problème potentiel lié à l'encodage des caractères, il est recommandé de forcer l'encodage UTF-8 dans le fichier principal en utilisant la directive @charset. Assurez-vous que ce soit le premier élément de la feuille de style et qu'il n'y ait aucun caractère de quelque nature en amont.

Guillemets

En CSS, les chaînes de caractères n'ont pas à être entourées de guillemets, pas même celles qui contiennent des espaces. Prenez les noms de font-family par exemple : peu importe qu'elles soient ou non entre guillemets.

C'est pourquoi dans Sass les chaînes de caractères n'ont pas non plus à être entourées de guillemets. Mieux, (et heureusement) une chaîne de caractères entre guillemets est strictement équivalente à sa jumelle sans guillemets (p.ex. 'abc' est strictement égale à abc).

Ceci étant, les langages qui ne requièrent pas d'envelopper les chaînes de caractères entre guillemets sont une infime minorité, c'est la raison pour laquelle les chaînes de caractères devraient toujours être entourées de guillemets simples (') dans Sass (pourquoi des guillemets simples ? parce qu'ils sont plus faciles à taper sur un clavier qwerty). À part la cohérence avec d'autres langages, dont JavaScript le cousin de CSS, il y a plusieurs raisons à ce choix :

les noms de couleurs sont traités comme des couleurs lorsqu'ils ne sont pas entre guillemets, ce qui peut conduire à de sérieux problèmes ;

la plupart des colorations syntaxiques fonctionnent mieux avec les guillemets ;

la lisibilité est améliorée ;

il n'y a pas de raison valable de ne pas utiliser de guillemets.

Selon les spécifications CSS, la déclaration @charset doit utiliser des guillemets doubles pour être considérée valide. Cependant, Sass s'en assure en compilant vos feuilles de styles si bien que vous pouvez tout à fait utiliser des guillemets simples, même pour @charset.

Chaînes comme valeurs CSS

Il convient de faire une distinction entre les chaînes de caractères qui sont des valeurs CSS (il s'agit d'identifiants CSS) comme dans l'exemple qui précède, et les chaînes de caractères correspondant à des types de données Sass (par exemple les clés des maps).

On ne met pas de guillemets pour les premières, mais il en faut pour ces dernières.

Chaînes contenant des guillemets

Si une chaîne de caractères contient un ou plusieurs guillemets simples, on peut éviter l'utilisation d'échappements répétés en enveloppant la chaîne à l'intérieur de guillemets doubles (") .

URLs

Les URL doivent être écrites entre guillemets pour les mêmes raisons que ci-dessus :

Nombres

Dans Sass, un nombre est une donnée qui peut avoir une unité ou pas et qui décrit une longueur, une durée, une fréquence, un angle, etc. Cela permet d'effectuer des calculs sur les mesures.

Zéros

Une valeur décimale inférieure à 1 doit être précédée d'un zéro. N'écrivez pas de zéros finaux après le point.

Dans Sublime Text ainsi que d'autres éditeurs permettant d'effectuer des remplacements à partir d'expressions régulières, il est très facile d'ajouter le zéro manquant avant le point. Remplacez simplement \s+\.(\d+) par \ 0.$1. N'oubliez pas l'espace précédant le 0 par contre.

Unités

S'agissant de longueurs, une valeur égale à 0 ne doit pas être suivie de son unité.

Attention, cette pratique doit être utilisée uniquement pour les longueurs. Les zéros sans unité ne sont pas autorisés pour les propriétés utilisant des durées, comme transition-delay. Théoriquement, si un zéro sans unité est utilisé comme durée, la déclaration est jugée invalide. Tous les navigateurs ne sont pas aussi stricts, mais certains le sont. Pour résumer : n'omettez l'unité que pour les longueurs.

L'erreur la plus courante en ce qui concerne les nombres dans Sass est de penser que les unités sont de simples chaînes de caractères qu'on peut accoler à un nombre sans problème. Même si cela semble vrai, ce n'est pas ainsi que les unités fonctionnent. On peut voir les unités comme des symboles algébriques. Par exemple, dans le monde réel, si on multiplie 5 mètres par 5 mètres, on obtient 25 mètres carrés. La même logique s'applique à Sass.

Pour ajouter une unité à un nombre, vous devez multiplier ce nombre par 1 unité.

Remarquez qu'en ajoutant 0 membre de cette unité on obtient le même résultat, mais je recommande la méthode indiquée ci-dessus car l'ajout de 0 unité peut créer une certaine confusion. En effet, si vous essayez de convertir un nombre dans une autre unité compatible, ajouter 0 ne fonctionnera pas. Davantage d'information à ce sujet dans cet article sur CSS-Tricks.

En fin de compte, tout dépend de ce que vous cherchez à obtenir. Rappelez-vous simplement qu'ajouter l'unité sous forme de chaîne de caractères n'est pas la bonne méthode. Utilisez des longueurs, pas des chaînes de caractères.

Pour supprimer l'unité d'une valeur, il suffit de la diviser par une fois son unité.

Si vous ajoutez une unité sous forme de chaîne de caractères à un nombre, le résultat est une chaîne de caractères, ce qui vous empêche d'effectuer toute opération sur la valeur. De même avec l'opération slice si vous découpez la partie numérique d'un nombre - ce qui n'est sans doute pas le résultat souhaité.

Calculs

Les calculs numériques de premier niveau devraient toujours être entre parenthèses. Non seulement la lisibilité s'en trouve considérablement améliorée, mais les éventuels cas borderline sont résolus en forçant Sass à évaluer le contenu entre parenthèses.

Nombres magiques

L'expression "nombre magique" est un vieux terme de programmation qui désigne une constante numérique non nommée. Quelque chose comme un nombre aléatoire qui fonctionne sans que l'on sache dire exactement pourquoi.

Est-il utile de préciser que les nombres magiques sont une plaie et doivent être évités à tout prix ? Si vous ne pouvez pas expliquer logiquement la raison pour laquelle un nombre fonctionne, ajoutez un commentaire détaillant la façon dont vous êtes arrivé à ce nombre et pourquoi vous pensez qu'il est approprié. Il vaut mieux expliquer pourquoi vous ne comprenez pas comment quelque chose fonctionne que de laisser au développeur qui vous suivra le soin de comprendre les raisons de votre choix.

À ce sujet, CSS-Tricks a un superbe article à propos des nombres magiques en CSS, que je vous recommande de lire.

Couleurs

Les couleurs occupent une place importante dans le langage CSS. Naturellement, Sass devient un excellent allié lorsqu'il s'agit de manipuler les couleurs, essentiellement à l'aide de quelques fonctions puissantes.

Sass est si utile quand il s'agit de manipuler les couleurs que des articles sont apparus de toute part pour en parler. Permettez-moi de vous recommander quelques lectures :

Formats de couleurs

Pour simplifier les couleurs autant que possible, mon conseil est de respecter l'ordre de préférence suivant pour les formats :

1. Notation HSL;

2. Notation RGB;

3. Notation hexadécimale (en minuscules et en version raccourcie lorsque c'est possible).

Les mots-clés de couleur ne devraient pas être utilisés, sauf quand il s'agit de prototypage rapide. En effet, ils sont en anglais et certains d'entre eux font un bien piètre travail quand il s'agit d'exprimer la couleur qu'ils représentent, surtout pour des personnes dont l'anglais n'est pas la langue maternelle. De plus, les mots-clés n'ont pas vraiment de valeur sémantique. Par exemple, grey se trouve être plus foncé que darkgrey, et la confusion entre grey et gray peut engendrer une utilisation incohérente de cette couleur.

La représentation HSL n'est pas seulement la plus facile à appréhender pour le cerveau humain [citation requise], elle rend aussi les modifications de couleurs plus simples en permettant d'ajuster la teinte, la saturation et la valeur de manière individuelle.

Le format RGB a également l'avantage d'indiquer du premier coup d'oeil si la couleur est plutôt bleue, verte ou rouge. C'est pourquoi il peut être plus approprié que le format HSL dans certains cas, surtout quand il s'agit de décrire un pur rouge, vert ou bleu. Cependant, ce format rend la construction d'une couleur via ses trois composantes difficile.

Enfin, l'hexadécimal est presque indéchiffrable pour le cerveau humain. Ne l'utilisez qu'en dernier recours, si vous en avez besoin.

Si vous utilisez la notation HSL ou RGB, ajoutez toujours un espace après la virgule, mais n'ajoutez pas d'espace entre les parenthèses et le contenu.

Couleurs et variables

Si vous utilisez une couleur plusieurs fois, enregistrez-la dans une variable portant un nom représentatif de la couleur.

Vous pouvez maintenant utiliser cette variable où vous voulez. Cependant, si son usage est lié à un thème, je vous conseille de ne pas utiliser la variable directement mais plutôt de l'enregistrer elle-même dans une autre variable dont le nom explique la fonction.

De cette façon vous éviterez qu'une modification de votre thème ne conduise à quelque chose comme $sass-pink: blue. Cet article explique bien pourquoi il est important de bien nommer ses variables.

Éclaircir et obscurcir les couleurs

Les fonctions lighten et darken manipulent la luminosité d'une couleur dans l'espace HSL en augmentant ou en diminuant sa valeur. En fait, elles ne sont rien d'autre que des alias du paramètre $lightness de la fonction adjust-color.

Toutefois, il arrive souvent que ces fonctions ne produisent pas le résultat escompté. La fonction mix est une autre façon d'éclaircir une couleur en la mélangeant à du blanc ou à du noir.

Illustration de la différence entre lighten/darken et mix par KatieK

Si vous ne voulez pas écrire la fonction mix à chaque fois, vous pouvez créer deux fonctions faciles à utiliser, tint et shade (qui sont incluses dans Compass) pour obtenir la même chose :

La fonction scale-color échelonne les propriétés de manière plus fluide en prenant en compte leur degré de luminosité actuelle. Elle donne des résultats aussi beaux que mix mais avec des conventions d'utilisation plus claires. Le facteur d'échelonnage n'est cependant pas le même.

Listes

Les listes sont l'équivalent des arrays (tables) dans Sass. Une liste est une structure de données plate (contrairement à maps) dont le but est de stocker des valeurs de tout type (y compris des listes, ce qui autorise l'imbrication de listes).

Les listes doivent respecter les recommandations suivantes :

sur une ligne ou sur plusieurs lignes ;

impérativement sur plusieurs lignes si elles comptent plus de 80 caractères ;

toujours utiliser une virgule pour séparer les éléments de la liste, sauf si elle est utilisée pour un contenu CSS ;

toujours entre parenthèses ;

ajouter une virgule après le dernier élément de la liste si elle compte plusieurs lignes.

Lorsque vous ajoutez de nouveaux items à une liste, utilisez toujours l'API fournie. N'essayez pas de les ajouter manuellement.

Dans cet article, je parcours un certain nombre de trucs et astuces pour comprendre et manipuler les listes en Sass.

Maps

Avec Sass, les auteurs de feuilles de styles peuvent définir des maps, qui sont l'équivalent en Sass des tableaux associatifs (ou dictionnaires ou tables d'association), des hashs ou même des objets JavaScript. Une map est une structure de données qui associe des clés (keys) à des valeurs. Les clés comme les valeurs peuvent être de tout type, y compris de type map même si je ne recommanderais pas l'utilisation de types complexes comme clés, ne serait-ce que dans un souci de simplicité.

Les maps doivent être écrites comme suit :

un espace après les deux-points (:) ;

parenthèse ouvrante (() sur la même ligne que les deux-points (:) ;

clés entre guillemets si ce sont des chaînes de caractères (soit 99% des cas) ;

chaque paire clé/valeur sur sa propre ligne ;

virgule (,) à la fin de chaque clé/valeur ;

virgule finale (,) après le dernier item pour faciliter l'ajout, la suppression ou la réorganisation d'items ;

parenthèse fermante ()) sur sa propre ligne ;

pas d'espace ni de retour à la ligne entre la parenthèse finale et le point-virgule final.

Illustration :

Ensemble de règles CSS

Ici nous allons réviser ce que tout le monde sait, mais voici comment on devrait écrire une règle CSS (du moins selon la plupart des recommandations, dont CSS Guidelines) :

les sélecteurs liés sur la même ligne, sinon sur une ligne différente ;

l'accolade ouvrante ({) sur la ligne du dernier sélecteur séparé de celui-ci par un espace ;

chaque déclaration sur une même ligne ;

un espace après les deux-points (:) ;

toujours un point-virgule (;) à la dernière déclaration d'une règle ;

l'accolade fermante (}) sur sa propre ligne ;

une nouvelle ligne après l'accolade fermante.

Illustration:

En plus de ces recommandations liées à CSS, nous devons être attentifs aux points suivants :

les variables locales doivent être déclarées avant toute autre déclaration, puis séparées des autres par une ligne ;

les inclusions de mixins sans @content doivent venir avant toute déclaration ;

les sélecteurs imbriqués doivent toujours apparaître sur une nouvelle ligne ;

les inclusions de mixins avec @content doivent apparaître après les sélecteurs imbriqués ;

pas de saut de ligne avant une accolade fermante (}).

Illustration:

Ordre des déclarations

Je ne connais aucun autre sujet où les opinions sont aussi partagées qu'en ce qui concerne l'ordre des déclarations CSS. Concrètement, deux opinions s'opposent :

s'en tenir à l'ordre alphabétique ;

classer les déclarations par type (position, display, color, font, autres...).

Il y a du pour et du contre dans chacune. D'un côté, l'ordre alphabétique est universel (du moins pour les langues utilisant l'alphabet latin), donc il n'y a pas de dispute possible quant à la position d'un sélecteur par rapport à un autre. Cependant, il me paraît bizarre de ne pas avoir des propriétés telles que bottom et top l'une derrière l'autre. Pourquoi les animations devraient-elles apparaître avant le type de display ? L'ordre alphabétique crée de nombreuses bizarreries.

D'un autre côté, ordonner par propriété semble parfaitement logique. Les déclarations de font sont regroupées, top et bottom sont réunis et la lecture d'une règle CSS ressemble à une petite histoire. Mais à moins de s'en tenir à des conventions comme Idiomatic CSS, cette façon de faire laisse encore beaucoup de place à l'interprétation. Où situer white-space ? font ou display ? Où situer overflow ? Et quel ordre donner aux propriétés à l'intérieur d'un groupe ? (alphabétique ?... ô ironie...).

Il existe encore un autre modèle d'ordonnancement des types, Concentric CSS, qui semble assez populaire lui aussi. Concentric CSS s'appuie sur le modèle de boîte pour définir l'ordre : il part de l'extérieur pour aller vers l'intérieur.

Je dois dire que je n'arrive pas à me décider moi-même. Un récent sondage de CSS-Tricks a montré que plus de 45% des développeurs ordonnent leurs déclarations par type, contre 14% par ordre alphabétique. 39% le font au hasard, et j'en fais partie.

Tableau montrant comment les développeurs ordonnent leurs déclarations CSS

C'est la raison pour laquelle je ne recommande pas de choix particulier dans ce guide de style. Choisisssez celui que vous préférez, du moment qu'il reste cohérent tout au long de vos feuilles de style (en d'autres termes : pas l'option au hasard).

Une étude récente montre que l'utilisation de CSS Comb (qui s'appuie sur un ordre par type) pour organiser les déclarations CSS permet de réduire la taille moyenne des fichiers gzippés de 2,7% contre 1,3% lorsqu'ils sont ordonnés alphabétiquement.

Imbrication des sélecteurs

Parmi les fonctionnalités offertes par Sass, l'une d'entre elles est souvent mal utilisée, c'est l'imbrication des sélecteurs. Celle-ci permet aux auteurs de feuilles de styles de créer de longs sélecteurs en imbriquant des sélecteurs plus courts les uns dans les autres.

Règle générale

Par exemple, l'imbrication Sass suivante :

... génèrera ce CSS :

En suivant la même idée, il est possible depuis Sass 3.3 d'utiliser la référence au sélecteur courant (&) pour générer des sélecteurs avancés, par exemple :

... génèrera ce CSS :

Cette méthode est souvent utilisée avec les conventions de nommage BEM pour générer des sélecteurs .block__element et .block--modifier à partir du sélecteur d'origine (.block dans ce cas).

Même si cela peut sembler anecdotique, la génération de nouveaux sélecteurs à l'aide de la référence au sélecteur courant (&) rend impossible la recherche de ces sélecteurs dans le code puisqu'ils n'existent pas en soi.

Le problème avec l'imbrication des sélecteurs est qu'elle rend le code plus difficile à lire. On doit reconstituer mentalement le sélecteur qui en résulte à partir des niveaux d'indentation. Il n'est pas toujours évident de se représenter ce que donnera le CSS final.

C'est d'autant plus vrai à mesure que les sélecteurs s'allongent et que les références au sélecteur courant (&) se multiplient. À un certain point, le risque de confusion devient tellement élevé que l'imbrication n'en vaut pas la peine.

Pour éviter de telles situations, nous évitons l'imbrication des sélecteurs autant que possible. Il y a cependant quelques exceptions à cette règle.

Pour éviter de telles situations, il existe la fameuse Règle d'Inception ( The Inception Rule) depuis quelques années. Celle-ci déconseille d'imbriquer au-delà de 3 niveaux, en référence au film Inception de Christopher Nolan. Je suis plus drastique encore et vais jusqu'à déconseiller l'imbrication des sélecteurs autant que faire se peut.

Bien qu'il y ait bien évidemment quelques exceptions à cette règle comme nous allons le voir dans la prochaine section, cette opinion tranchée semble malgré tout assez populaire. Vous pouvez en lire davantage dans Beware of Selector Nesting et Avoid nested selectors for more modular CSS.

Exceptions

Pour commencer, il est permis - et même recommandé - d'imbriquer les pseudo-classes et les pseudo-éléments à l'intérieur du sélecteur initial.

Non seulement l'imbrication des pseudo-classes et pseudo-éléments est parfaitement justifiée (parce qu'il s'agit de sélecteurs étroitement liés) mais aussi elle permet de conserver tout ce qui concerne un même composant au même endroit.

De plus, lorsqu'on utilise des classes décrivant un état indépendant du composant telles que .is-active, il est tout à fait justifié de les imbriquer dans le sélecteur du composant de façon à avoir un code bien ordonné.

Last but not least, lorsqu'on applique un style à un élément parce qu'il se trouve être contenu dans un autre élément spécifique, il est également logique de l'imbriquer afin que tout ce qui concerne cet élément soit réuni au même endroit.

Comme pour toute chose, ce qui compte ce ne sont pas les détails mais la cohérence globale. Si vous vous sentez en confiance avec l'imbrication des sélecteurs, utilisez-la. Assurez-vous que toute l'équipe soit d'accord avec cette façon de faire.

Conventions de nommage

Dans cette section, nous ne traiterons pas des conventions de nommage CSS pour une meilleure maintenabilité et le passage à l'échelle ; non seulement cela dépend de chacun, mais cela sort du cadre d'un guide de style Sass. Je vous suggère de consulter les conventions recommandées par CSS Guidelines.

Il existe un certain nombre de choses que l'on peut nommer en Sass, et il est important de bien les nommer de façon à assurer la cohérence et la lisibilité de votre code :

Les placeholders Sass sont délibérément omis, car ils peuvent être considérés comme des sélecteurs CSS normaux, et suivent par conséquent les mêmes modèles de nommage que les classes.

En ce qui concerne les variables, les fonctions et les mixins, nous allons nous tenir à quelque chose de très CSS : bas-de-casse et séparation par un tiret, et surtout signifiant.

Constantes

Si vous êtes un développeur de frameworks ou si vous écrivez des bibliothèques, vous pouvez avoir besoin de variables qui ne sont pas supposées être mises à jour, en aucune circonstance : en d'autres termes des constantes. Malheureusement (ou heureusement ?), Sass ne permet pas de définir de telles entités, c'est pourquoi nous devons nous tenir à des conventions strictes si nous voulons que les choses soient claires.

Comme dans de nombreux langages, je suggère d'utiliser des variables tout en majuscules et snake-case pour indiquer qu'il s'agit de constantes. C'est non seulement une convention déjà ancienne, mais elle contraste fortement avec les variables tout en minuscules et séparées par des tirets.

Si vous désirez vraiment utiliser des constantes en Sass, vous devriez lire cet article dédié à ce sujet.

Namespaces

Si vous avez l'intention de distribuer votre code Sass, sous forme de bibliothèque, de framework, de système de grille ou autre, il peut s'avérer intéressant de donner un namespace à vos variables, fonctions, mixins et placeholders de façon à ce qu'ils n'entrent pas en conflit avec le code d'une autre personne.

Par exemple, si vous travaillez sur un projet Sassy Unicorn qui est destiné à être distribué, il est important d'utiliser un namespace, tel que su-, suffisamment spécifique pour éviter toute collision de noms et suffisamment court pour ne pas devenir pénible à écrire.

Kaelig a un super article à propos du namespace global de CSS, si jamais le sujet vous passionne !

Le namespacing automatique est un des objectifs de la redéfinition à venir d' @import à partir de Sass 4.0. Lorsque cela se concrétisera, il sera de moins en moins utile de réaliser manuellement le namespacing, et à terme les bibliothèques conçues de la sorte (avec espaces de noms manuels) pourraient devenir plus difficiles à utiliser.

Architecture

La conception de l'architecture d'un projet CSS est probablement l'une des étapes les plus complexes dans la vie d'un projet. Conserver la cohérence de l'architecture et son sens est encore plus difficile.

Heureusement, l'un des principaux bénéfices de l'utilisation de préprocesseurs est la possibilité d'éclater le code en plusieurs fichiers sans impacter la performance (contrairement à la directive CSS @import). Grâce à la surcharge de la directive @import dans Sass, on peut de manière sûre (et recommandée) utiliser autant de fichiers que nécessaire dans le développement, qui seront tous compilés en une feuille de style unique pour la production.

On n'insistera jamais assez sur la nécessité d'utiliser des dossiers, même sur des projets de dimension modeste. À la maison, vous ne rangez pas tous vos papiers dans la même boîte. Vous utilisez des dossiers : un pour les papiers de la maison, un pour la banque, un pour les factures, etc. Il en va de même lorsqu'on structure un projet CSS. Éclatez votre code en plusieurs dossiers qui font sens, de façon à retrouver ce que vous cherchez quand vous devez revenir sur le code.

Il existe plusieurs architectures populaires pour les projets CSS : OOCSS, Atomic Design, ou inspirées de Bootstrap ou de Foundation ... Elles ont toutes leurs mérites et chacune a du pour et du contre.

Personnellement j'utilise une approche assez similaire à SMACSS de Jonathan Snook, dont l'objectif est de conserver une architecture simple et évidente.

L'expérience m'a appris que l'architecture était la plupart du temps très spécifique au projet. Sentez-vous libre de rejeter complètement ou d'adapter la solution proposée - votre système doit répondre à vos besoins spécifiques.

Composants

Il y a une différence essentielle entre un projet qui marche et un bon projet. Encore une fois, CSS est un langage confus [citation requise]. Moins nous avons de CSS et mieux nous nous portons. Nous ne voulons pas avoir à gérer des mégaoctets de code CSS. Pour conserver des feuilles de styles concises et efficaces - ce ne sera pas une surprise pour vous - il est généralement utile de voir l'interface comme un ensemble de composants.

Les composants peuvent être ce qu'on veut, du moment que :

Par exemple, un formulaire de recherche devrait être traité comme un composant. Il devrait être réutilisable, à différents endroits, sur différentes pages, dans des situations variées. Il ne devrait pas dépendre de sa position dans le DOM (footer, sidebar, main content...).

La plupart des éléments constituant une interface peuvent être pensés comme des composants et je recommande de se tenir à ce paradigme. Non seulement cela réduira le CSS nécessaire à un projet, mais encore ce sera bien plus facile à maintenir qu'un code chaotique et confus.

Anatomie d'un Composant

Idéalement, les composants devraient exister dans leur propre fichier (dans le dossier components/, comme décrit dans la section dédiée au pattern 7-1), par exemple components/_button.scss). Les styles décrits dans chaque composant devraient uniquement traiter :

Si vous souhaitez rendre vos composants personnalisables de façon externe (via un thème provenant du dossier themes/ par exemple), limitez les déclarations aux styles structurels comme les dimensions ( width, height), marges ( padding, margin), alignements, etc. Évitez les styles graphiques comme les couleurs, ombres, fonds, règles de typographie, etc.

Un fichier de composant peut inclure des variables, placeholders et mêmes mixins et fonctions du moment que ceux-ci sont spécifiques au dit composant. Gardez à l'esprit cependant qu'il faut éviter de référencer (@import-er) un composant depuis un autre composant car cela peut rendre le projet extrêmement chaotique.

Voilà un exemple de composant bouton :

Le pattern 7-1

Revenons à l'architecture. J'utilise habituellement ce que j'appelle le pattern 7-1 : 7 dossiers, 1 fichier. Tous vos partiels regroupés dans 7 dossiers différents et un fichier simple à la racine (généralement appelé main.scss) qui les importe tous pour les compiler dans une feuille de style CSS.

Et bien sûr :

Si vous souhaitez utiliser le pattern 7-1, il y a déjà un boilerplate sur GitHub. Il contient tout ce dont vous avez besoin pour démarrer avec cette architecture.

Idéalement, nous pouvons proposer quelque chose comme ceci :

Les fichiers suivent les conventions de nommage décrites précédemment : minuscules et utilisation du trait d'union.

Dossier base

Le dossier base/ contient ce que nous pourrions appeler le code standard ( boilerplate) du projet. On pourrait y trouver par exemple le fichier de reset, quelques règles typographiques, et probablement une feuille de style définissant quelques styles standard pour les éléments HTML les plus employés (que j'ai l'habitude d'appeler _base.scss).

Si votre projet utilise beaucoup d'animations CSS, vous pouvez envisager d'ajouter un fichier _animations.scss contenant les définitions de @keyframes pour toutes vos animations. Si vous n'utilisez les animations que de façon sporadique, laissez leur déclaration près des sélecteurs qui les emploient.

Dossier layout

Le dossier layout/ contient tout ce qui concerne la mise en page du site ou de l'application. Ce dossier pourrait intégrer des feuilles de style pour les principales parties du site (header, footer, navigation, sidebar...), pour le système de grille ou même les styles CSS pour tous les formulaires.

Le dossier layout/ pourrait aussi être appelé partiels/, selon ce que vous préférez.

Dossier composants

Pour les plus petits composants, il y a le dossier components/. Alors que layout/ est macro (c'est-à-dire qu'il définit l' armature globale), components/ est plus centré sur les widgets. Il contient toutes sortes de modules spécifiques tels qu'un slider, un loader, un widget et toutes ces sortes de choses. Il y a en général de nombreux fichiers dans components/ car l'application tout entière devrait être essentiellement constituée de petits modules.

Le dossier components/ pourrait également être appelé modules/, selon ce que vous préférez.

Dossier Pages

Selon votre processus de déploiement, ces fichiers peuvent être appelés individuellement pour éviter de les mélanger aux autres dans la feuille de style finale. Cela dépend vraiment de vous.

Dossier Thèmes

Dans des sites ou applications de grande envergure, il n'est pas rare d'avoir plusieurs thèmes. Il y a certainement bien des façons de traiter les thèmes, mais personnellement j'aime les regrouper dans un dossier themes/.

On est ici dans des considérations très spécifiques aux projets, et il est probable que ce dossier n'existera pas dans bien des cas.

Dossier d'Abstractions

Le dossier abstracts/ regroupe les outils et helpers Sass utilisés à travers le projet. Toutes les variables globales, les fonctions, les mixins et les placeholders devraient se retrouver dans ce dossier.

La règle générale concernant ce dossier est qu'il ne devrait pas retourner une seule ligne de CSS s'il était compilé seul. Ce ne sont ici que des helpers Sass.

Le dossier abstracts/ pourrait également être appelé utilities/ ou helpers/, au choix.

Dossier vendors

Et last but not least, la plupart des projets comportent un dossier vendors/ qui regroupe tous les fichiers CSS provenant de bibliothèques et frameworks externes - Normalize, Bootstrap, jQueryUI, FancyCarouselSliderjQueryPowered, etc. Le fait de les mettre ainsi de côté dans un dossier séparé est une bonne façon d'indiquer qu'ils ne sont pas de vous et ne relèvent pas de votre responsabilité.

Si vous devez remplacer une section d'un fichier vendor, je recommande de créer un 8 e dossier nommé vendors-extensions/ dans lequel vous aurez des fichiers nommés en fonction du vendor qu'ils remplacent.

Par exemple, vendors-extensions/_boostrap.scss serait un fichier contenant toutes les règles CSS qui re-déclarent le CSS par défaut de Bootstrap. Vous éviterez ainsi de modifier les fichiers vendors eux-mêmes, ce qui n'est pas conseillé.

Fichier principal

Les fichiers doivent être importés en fonction du dossier dans lequel ils sont rangés, l'un après l'autre dans l'ordre suivant :

Afin d'assurer une bonne lisibilité, le fichier principal devrait respecter ces recommandations :

un fichier par @import ;

un @import par ligne ;

pas de saut de ligne entre 2 imports provenant du même dossier ;

un saut de ligne après le dernier import d'un dossier ;

les extensions fichiers et les underscores initiaux doivent être omis.

Il existe une autre façon d'importer les partiels, que je considère également valable. D'un côté, elle rend le fichier plus lisible. D'un autre côté, elle rend la mise à jour moins aisée. En tout cas, c'est à vous de décider, ce n'est pas très important. Dans cette façon de faire, le fichier principal doit respecter ces recommandations :

un @import par dossier ;

retour à la ligne après @import ;

chaque fichier sur sa propre ligne ;

un saut de ligne après le dernier import d'un dossier ;

les extensions fichiers et les underscores initiaux doivent être omis.

Pour éviter d'avoir à importer chaque fichier manuellement, il y a une extension de Sass Ruby appelée sass-globbing, qui permet d'utiliser les patterns glob dans Sass @import tels que @import "components/*".

Ceci dit, je ne la recommande pas car elle importe les fichiers par ordre alphabétique ce qui n'est pas souhaitable en général, surtout s'agissant d'un langage dans lequel l'ordre des sources est essentiel.

À propos du "globbing"

En informatique, les "glob patterns" spécifient des collections de noms de fichiers contenant des caractères dits "joker", tels que *.scss. De manière générale, globbing signifie déterminer un ensemble de fichiers à partir d'une expression plutôt que via une liste de noms de fichier. Quand il s'agit de Sass, cela signifie importer des fichiers individuels dans le fichier principal avec un pattern plutôt qu'en les listant un par un. Cela donnerait un fichier principal comme celui-ci :

Sass ne supporte pas le globbing par défaut car cela peut s'avérer dangereux dans la mesure où l'ordre de la source est important en CSS. En important les fichiers de manière dynamique (généralement par ordre alphabétique), on ne peut s'assurer de l'ordre de la source, ce qui peut engendrer des bugs difficiles à analyser.

Ceci étant dit, dans une architecture strictement basée sur les composants où un soin tout particulier est apporté à l'encapsulation des styles, l'ordre ne devrait pas vraiment importer, ce qui rend le globbing possible. Cela permettrait de faciliter l'ajout et le retrait des fichiers sans avoir à maintenir le fichier principal à la main.

Avec Ruby Sass, il existe une Gem Ruby appelée sass-globbing qui autorise ce comportement. Avec node-sass, on peut s'appuyer sur Node.js ou l'outil gérant la compilation des feuilles de styles (Gulp, Grunt, etc.).

Fichier de la honte

Il existe un concept intéressant, popularisé par Harry Roberts, Dave Rupert et Chris Coyier qui consiste à ranger toutes les déclarations CSS, les hacks et tout ce dont on n'est pas vraiment fier dans un fichier de la honte. Ce fichier, pathétiquement dénommé _shame.scss, est importé après tous les autres fichiers, à la toute fin de la feuille de style.

Responsive Web Design et points de rupture

Je ne pense pas qu'il soit nécessaire de présenter le Responsive Web Design qui est maintenant omniprésent. Cependant vous vous demandez peut-être pourquoi diable parler de RWD dans un guide de style Sass ? En fait, Sass peut nous faciliter la vie avec les points de rupture, voici ce qu'on peut faire.

Nommer les points de rupture

Je pense qu'on peut affirmer sans crainte que les media queries ne devraient jamais être liées à tel ou tel terminal. Par exemple, cibler spécifiquement les iPads ou les téléphones Blackberry est une très mauvaise idée. Les media queries doivent s'occuper d'amplitudes de tailles d'écran, jusqu'à ce que le design ne fonctionne plus comme souhaité et que la media query suivante prenne la relève.

Pour ces mêmes raisons, les points de rupture ne doivent pas être nommés en fonction d'un nom de terminal mais plutôt de quelque chose de plus général, d'autant que certains téléphones sont maintenant plus grands que certaines tablettes, certaines tablettes plus grandes que certains écrans d'ordinateurs, etc.

Ici, il est clair que toute convention de nommage clairement déconnectée de toute référence à un device particulier fera l'affaire, du moment qu'elle donne à comprendre l'ordre de grandeur.

L'exemple qui précède utilise des maps imbriquées pour définir les points de rupture, mais tout dépend de la façon dont vous gérez vos points de rupture. On pourrait tout aussi bien choisir des chaînes de caractères plutôt que des maps internes, pour plus de flexibilité (p.ex. '(min-width: 800px)').

Gestion des points de rupture

Une fois vos points de rupture nommés comme vous le souhaitez, il vous faut un moyen de les utiliser dans les media queries. Il y a de nombreuses façons d'y parvenir, mais je dois dire que je suis un fan des fonctions getter pour lire les maps de points. C'est un système à la fois simple et efficace.

Évidemment, c'est un gestionnaire de points de rupture assez simpliste, si vous avez besoin d'un gestionnaire plus permissif, et si vous ne voulez pas réinventer la roue, je vous recommande Sass-MQ, Breakpoint ou include-media qui ont fait leurs preuves.

Si vous souhaitez en savoir davantage sur les façons d'aborder les Media Queries en Sass, SitePoint (via votre serviteur) et CSS-Tricks proposent de très beaux articles.

Il y a peu, un débat faisait rage sur la question de savoir où placer les media queries dans le code : à l'intérieur des sélecteurs (comme le permet Sass) ou ailleurs de façon strictement dissociée ? Je dois dire que je suis un fervent défenseur du système media-queries-dans-les-sélecteurs car il s'accorde bien avec l'idée de composants.

Ce qui conduit au résultat suivant en CSS :

On vous dira que cette convention a pour effet la duplication de media queries en CSS, et c'est absolument vrai, même si des tests ont été réalisés qui montrent que cela n'a pas d'importance une fois que Gzip (ou équivalent) a fait son oeuvre :

... nous avons étudié les implications en termes de performance de la combinaison ou de la dissociation des media queries et nous sommes arrivés à la conclusion que la différence est, au pire, minimale, au mieux inexistante. - Sam Richards, au sujet de Breakpoint

Maintenant, si vous êtes vraiment soucieux d'éviter toute duplication, vous pouvez utiliser un outil pour merger les media queries, comme cette Gem, cependant je dois vous avertir de possibles effets collatéraux liés au déplacement de code - n'oubliez pas que l'ordre des sources est important en CSS.

Variables

Les variables sont l'essence de tout langage de programmation. Elles nous permettent de réutiliser des valeurs sans avoir à les recopier sans cesse. Plus important encore, elles facilitent les mises à jour. Plus besoin de chercher et remplacer, ni de rechercher manuellement.

Cependant, CSS n'est rien d'autre qu'un grand panier contenant tous nos oeufs. Contrairement à de nombreux langages, CSS ne connaît pas vraiment la notion de portée lexicale ( scope). Il nous faut donc être attentifs lorsque nous ajoutons de nouvelles variables, si nous voulons éviter les conflits.

Mon conseil serait de ne créer de variables que lorsque cela fait vraiment sens. Ne créez pas de nouvelles variables juste pour le plaisir, ça n'améliorera en rien votre code. Une nouvelle variable ne devrait être créée que lorsque les critères suivants sont réunis :

Rien ne sert de déclarer une variable qui ne sera jamais mise à jour ou qui n'est utilisée qu'à un seul endroit.

Scoping

Le scoping des variables dans Sass a évolué avec les années. Jusqu'à récemment, les déclarations de variables à l'intérieur d'un jeu de règles et autres portées étaient locales par défaut. Cependant, lorsqu'il y avait déjà une variable globale portant le même nom, la déclaration locale modifiait la variable globale. Depuis la version 3.4, Sass traite correctement le concept de portée et crée une nouvelle variable locale.

La documentation parle de global variable shadowing. Lorsqu'on déclare à un niveau local (sélecteur, fonction, mixin...) une variable qui existe déjà au niveau global, on dit que la variable locale masque la variable globale. Autrement dit, elle prend le pas sur la variable globale au niveau local.

Le petit code qui suit explique le concept de variable shadowing :

Le flag !default

Quand on construit une bibliothèque, un framework, un système de grilles ou n'importe quelle structure Sass destinée à être distribuée et utilisée par des développeurs externes, toutes les variables de configuration doivent être définies avec le flag !default ce qui permet qu'elles soient écrasées.

De cette manière, un développeur peut définir sa propre variable $baseline avant d'importer votre bibliothèque sans risquer de voir sa valeur redéfinie.

Le flag !global

Le flag !global ne doit être utilisé que lorsque l'on veut qu'une variable locale prenne le pas sur une variable globale. Lorsqu'on définit une variable à la racine, le flag !global doit être omis.

Variables multiples ou maps

L'utilisation de maps plutôt que de variables multiples et distinctes présente un certain nombre d'avantages. Le principal réside dans la possibilité d'utiliser des boucles sur une map, ce qui n'est pas possible avec des variables distinctes.

Un autre avantage de l'utilisation de maps est la possibilité de créer des fonctions getter pour fournir une API plus facile d'usage. Par exemple, considérons le code Sass suivant :

Extend

La directive @extend est une fonctionnalité puissante qui est bien souvent mal comprise. En règle générale, elle permet d'indiquer à Sass qu'il doit styler un sélecteur A comme s'il correspondait à un élément B. Il va sans dire que c'est un allié de poids lorsqu'on écrit un CSS modulaire.

Cependant, le vrai rôle de @extend est d'indiquer et de maintenir des relations (contraintes) au sein des sélecteurs étendus entre plusieurs règles. Concrètement, qu'est-ce que cela signifie ?

Les sélecteurs ont des contraintes (p.ex. .bar dans .foo > .bar doit avoir un parent .foo) ;

Ces contraintes sont passées au sélecteur qui étend (p.ex. .baz { @extend .bar; } va produire .foo > .bar, .foo > .baz) ;

Les déclarations du sélecteur étendu sont partagées avec le sélecteur qui étend.

Sachant cela, il est assez évident de voir comment le fait d'étendre des sélecteurs avec des contraintes trop souples peut engendrer une explosion du nombre de sélecteurs. Si .baz .qux étend .foo .bar, le sélecteur résultant peut être .foo .baz .qux ou .baz .foo .qux, dans la mesure où .foo et .baz sont des parents génériques. Ils peuvent être des parents, des grands-parents, etc.

Essayez toujours de définir des relations via les placeholders, plutôt que des classes. Ça permet d'utiliser n'importe quelle convention de nommage, et d'en changer sans problème. De plus, vu que les relations sont définies une fois seulement par les placeholders, il est bien plus rare de générer des sélecteurs non désirés.

Il y a de nombreux scénarios où étendre des sélecteurs peut être pratique et utile. Gardez toujours en tête ces règles afin de pouvoir utiliser @extend sans crainte :

N'étendez que des %placeholders, pas de vrais sélecteurs.

Étendez un même %placeholder aussi peu de fois que possible.

Évitez les sélecteurs parents génériques (p.ex. .foo .bar) ou les voisins génériques (p.ex. .foo ~ .bar). C'est précisément ce qui créé des problèmes de sélecteurs.

Il est souvent dit que @extend aide à réduire la taille des feuilles de styles dans la mesure où il combine les sélecteurs plutôt que de dupliquer les déclarations. C'est vrai, cependant la différence devient négligeable quand Gzip a effectué la compression.

Ceci étant dit, si vous ne pouvez pas utiliser Gzip (ou équivalent), basculer sur une approche utilisant @extend peut être envisageable, surtout si la taille de la feuille de styles constitue un problème de performance.

Vous ne devez étendre que des sélecteurs faisant partie du même cadre de média (directive @media). Considérez les media queries comme une autre contrainte.

Les opinions semblent très divisées vis-à-vis des avantages et inconvénients de @extend, et de nombreux développeurs (moi y compris) préconisent de ne pas l'utiliser, comme vous pouvez le lire dans ces articles :

Ceci étant dit et pour résumer, il est recommandé d'utiliser @extend exclusivement pour maintenir des relations entre les sélecteurs. Si deux sélecteurs ont des caractéristiques similaires, il y a là un cas d'utilisation typique pour @extend. S'ils n'ont rien à voir mais partagent quelques déclarations, un @mixin est probablement plus approprié. Davantage d'information sur leurs différences dans cet article.

Mixins

Les mixins sont l'une des fonctionnalités les plus utilisées de Sass. Elles sont essentielles pour la réutilisabilité et pour les composants DRY. Il y a de bonnes raisons à cela : les mixins permettent aux auteurs de définir des styles qui peuvent être réutilisés dans l'ensemble de la feuille de styles sans avoir à recourir à des classes non sémantiques comme .float-left.

Ils contiennent des règles CSS complètes et tout ce qui est permis n'importe où dans un document Sass. Ils acceptent même des arguments, comme les fonctions. Il va sans dire que les possibilités sont infinies.

Mais je dois vous mettre en garde contre l'abus de mixins. Là encore, le plus important est la simplicité. Il peut être tentant de construire des mixins extrêmement puissants faisant appel massivement à la logique. Cela ressemble à de l'ingénierie excessive et de nombreux développeurs souffrent de cette affection. Ne réfléchissez pas trop et surtout concentrez-vous sur la simplicité. Si un mixin dépasse 20 lignes de code, alors soit il doit être éclaté en parties plus réduites, soit il doit être repensé.

Les bases

Ceci étant dit, les mixins sont extrêmement utiles et vous devriez faire usage de quelques-uns. La règle générale est que si vous repérez un groupe de propriétés CSS qui apparaissent toujours ensemble pour une bonne raison (c'est-à-dire pas par pure coïncidence), vous pouvez les regrouper dans un mixin. Le micro-clearfix hack de Nicolas Gallagher par exemple mérite d'être déclaré dans un mixin (sans argument).

Un autre exemple valable serait un mixin permettant de dimensionner un élément, qui définirait à la fois sa largeur et sa hauteur, en même temps. Non seulement il simplifie la saisie du code mais il en facilite également la lecture.

Argument-less mixins

Parfois les mixins sont utilisés simplement pour éviter de répéter le même groupe de déclarations encore et encore, et par conséquent ne nécessitent pas de paramètres, ou se trouvent avoir des valeurs par défaut suffisamment éloquentes qu'il ne soit pas nécessaire de leur passer d'arguments.

Dans ces cas de figure, on peut tout à fait omettre les parenthèses lorsqu'on appelle un mixin. Le mot-clé @include (ou signe + dans le cas de la syntaxe indentée) fait déjà office d'indicateur qu'il s'agit d'une inclusion de mixin ; les parenthèses sont obsolètes.

Listes d'Arguments

Lorsque vous avez affaire à un nombre inconnu d'arguments dans un mixin, utilisez toujours une arglist plutôt qu'une liste. On peut voir arglist comme le 8 e type de données de Sass, caché et non documenté, qui est implicitement utilisé lorsqu'on passe un nombre arbitraire d'arguments dans un mixin ou une fonction dont la signature contient ....

Quand vous construisez un mixin qui accepte quelques arguments (disons 3 ou plus), pensez à deux fois avant de les merger sous forme de liste ou de map en croyant que ce sera plus facile que de les passer un par un.

Sass gère très intelligemment les mixins et les déclarations de fonction, vous pouvez passer une liste ou une map comme une arglist dans une fonction ou un mixin de façon à ce qu'ils soient traités comme une série d'arguments.

Pour plus d'information sur les différences entre des arguments multiples, une liste, et une liste d'arguments pour un mixin, SitePoint a un très bel article.

Mixins et préfixes constructeurs

Il pourrait être tentant de définir des mixins personnalisés pour traiter les préfixes constructeurs utilisés pour les propriétés CSS partiellement ou non supportées. Mais nous n'allons pas faire cela. D'abord, si vous pouvez utiliser Autoprefixer, faites-le. Il allégera votre code Sass, il sera toujours à jour et fera un bien meilleur boulot que vous pour préfixer ce qui doit l'être.

Malheureusement, Autoprefixer n'est pas toujours une option envisageable. Si vous utilisez Bourbon ou Compass, vous savez sans doute déjà qu'ils proposent tous les deux une collection de mixins qui traitent les préfixes constructeurs pour vous. Utilisez-les.

Si vous ne pouvez utiliser ni Autoprefixer, ni Bourbon, ni Compass, alors - et seulement alors - vous pouvez créer votre propre mixin pour préfixer les propriétés CSS. Attention, ne construisez pas un mixin par propriété en écrivant manuellement chaque préfixe constructeur.

Faites-le plus intelligemment.

L'utilisation de ce mixin devrait être assez simple :

Gardez à l'esprit que c'est une solution assez pauvre. Par exemple, elle ne peut pas traiter les polyfills complexes tels que ceux requis pour Flexbox. En ce sens, Autoprefixer est une bien meilleure solution.

Structures conditionnelles

Vous savez probablement déjà que Sass fournit des structures conditionnelles via les directives @if and @else. Vous n'avez sans doute pas besoin de structures conditionnelles dans vos feuilles de style habituelles, en fait elles existent essentiellement pour les bibliothèques et les frameworks.

Si toutefois vous en avez un jour besoin, voici les recommandations à suivre :

Pas de parenthèses sauf si elles sont nécessaires ;

Toujours un saut de ligne avant @if ;

Toujours un renvoi à la ligne après l'accolade ouvrante ({) ;

@else sur la même ligne que l'accolade fermante qui précède (}) ;

Toujours un saut de ligne après l'accolade fermante finale (}) sauf si la ligne suivante est aussi une accolade fermante (}).

Veillez à toujours mettre la partie variable à gauche de la déclaration et le résultat (in)attendu à droite. Les structures conditionnelles inversées sont souvent plus difficiles à lire, surtout pour les développeurs inexpérimentés.

Lorsqu'on utilise des structures conditionnelles à l'intérieur d'une fonction, toujours s'assurer que la fonction a une déclaration @return en dehors de tout bloc conditionnel.

Boucles

Sass nous offre des structures complexes telles que les listes et les maps, il n'est donc pas surprenant qu'il nous permette d'effectuer des itérations sur ces entités.

Toutefois, la présence de boucles implique généralement une logique légèrement complexe qui ne fait sans doute pas partie de la philosophie de Sass. Avant d'utiliser une boucle, assurez-vous que cela a un sens et que cela résout effectivement un problème.

Each

La boucle @each est certainement la plus utilisée des trois boucles de Sass. Elle fournit une API propre pour itérer sur une liste ou une map.

Lorsque vous effectuez une itération sur une map, utilisez toujours les noms de variables $key et $value pour renforcer la cohérence.

De plus, assurez-vous de respecter ces recommandations qui aideront à préserver la lisibilité :

Toujours un saut de ligne avant @each ;

Toujours un saut de ligne après l'accolade fermante (}) sauf si la ligne suivante est une accolade fermante (}).

For

De plus, assurez-vous de respecter ces recommandations qui aideront à préserver la lisibilité :

Toujours un saut de ligne avant @for ;

Toujours un saut de ligne après l'accolade fermante (}) sauf si la ligne suivante est une accolade fermante (}).

While

La boucle @while n'a pas de cas d'usage dans les projets Sass réels, surtout parce qu'il n'y a aucun moyen de sortir de la boucle de l'intérieur. Ne l'utilisez pas.

Avertissements et erreurs

S'il est une fonctionnalité de Sass souvent délaissée par les développeurs, c'est sa capacité à retourner dynamiquement des messages d'avertissement et d'erreur. Sass vient en effet avec trois directives permettant d'imprimer un contenu dans le système de sortie standard (CLI, compiling app...) :

Il y a bien des possibilités d'avertissements et d'erreurs dans Sass, n'importe quel mixin ou fonction qui attend un argument ou un type spécifique pourrait envoyer une erreur si quelque chose n'allait pas ou afficher un avertissement lorsque vous faites une hypothèse.

Avertissements

Prenez par exemple cette fonction de Sass-MQ qui essaie de convertir une valeur de px à em :

Si la valeur entrée se trouve être sans unité, la fonction suppose qu'elle est exprimée en pixels. Il est toutefois risqué de le faire sans avertir l'auteur que le logiciel a fait quelque chose qui pourrait être inattendu.

Erreurs

Contrairement aux avertissements, les erreurs empêchent le compilateur d'aller plus loin. Elles stoppent la compilation et affichent un message pratique pour le débogage. C'est la raison pour laquelle les erreurs ne devraient être envoyées que lorsqu'il est impossible au programme d'aller plus loin. Si possible, essayez de contourner le problème et d'afficher un avertissement à la place.

Par exemple, admettons que vous construisez une fonction getter pour accéder à des valeurs à partir d'une map spécifique. Vous pourriez envoyer une erreur si la clé requise n'existe pas dans la map.

Pour plus d'information sur une utilisation efficace de @error, cette introduction à la gestion des erreurs devrait vous aider.

Outils

Ce qui est bien avec un préprocesseur CSS aussi populaire que Sass est qu'il est accompagné de tout un écosystème de frameworks, plugins, bibliothèques et outils. Après 8 ans d'existence, nous sommes proches du point où tout ce qui peut être écrit en Sass a été écrit en Sass.

Mon conseil toutefois est de restreindre le nombre de dépendances au strict minimum. La gestion des dépendances est un enfer que vous pouvez vous épargner. De plus, il n'y a pas besoin de beaucoup de dépendances avec un langage comme Sass.

Compass

À titre personnel, je ne l'utilise plus car il ralentit considérablement Sass. Ruby Sass en lui-même est déjà assez lent, et l'ajout de code Ruby et Sass supplémentaire n'arrange pas les choses.

En fait, nous n'utilisons qu'une petite partie du framework. Compass est énorme. Les mixins de compatibilité navigateurs ne sont que la partie visible de l'iceberg. Fonctions mathématiques, helpers pour les images, sprites... il y a tant de choses possibles avec ce formidable outil.

Malheureusement, il s'agit pour l'essentiel de sucre syntactique mais pas de fonctionnalités exceptionnelles. Une exception serait la fonctionnalité de construction de sprites, mais Grunticon et Grumpicon font le même travail aussi bien, avec l'avantage d'être pluggables dans le process de déploiement.

Rien n'interdit d'utiliser Compass, je ne le recommande pas toutefois, d'autant qu'il n'est pas compatible avec LibSass (bien que des efforts aient été faits dans cette direction).

Ruby Sass est actuellement en cours d'optimisation. Sont visés en particulier les styles faisant appel à des doses massives de logique, de fonctions et de mixins. Les performances de Compass et des autres frameworks devraient s'en trouver grandement améliorées et ne devraient plus ralentir Sass.

Systèmes de grilles

Se passer d'un système de grilles n'est pas vraiment une option, maintenant que le Responsive Web Design est partout. Pour donner cohérence et solidité à votre design quelle que soit la taille de l'écran, nous utilisons une grille pour mettre en page les éléments, et quelques brillants esprits ont conçu des grilles réutilisables pour nous éviter d'avoir à coder encore et encore.

Soyons clairs pour commencer : je ne suis pas un grand fan des systèmes de grilles. J'en perçois le potentiel, mais je pense que ce sont souvent des marteaux pour tuer une mouche et qu'ils servent pour l'essentiel à dessiner des colonnes rouges sur fond blanc projetées en diapos dans les conférences de designers nerdy. Quand avez-vous pensé pour la dernière fois Oh mon dieu, heureusement que j'ai cet outil pour construire ma grille 2-5-3.1-π ? C'est vrai, jamais. Parce que dans la plupart des cas, vous voulez simplement utiliser la bonne vieille grille à 12 colonnes.

Si vous utilisez un framework CSS pour votre projet, comme Bootstrap ou Foundation, il y a des chances qu'ils comprennent déjà un système de grilles, auquel cas je vous recommande de l'utiliser pour éviter d'avoir à gérer une dépendance supplémentaire.

Dans le cas contraire, vous serez content de savoir qu'il existe deux gestionnaires de grilles de premier ordre, basé sur Sass : Susy et Singularity. Tous deux font bien plus que ce dont vous aurez jamais besoin, vous pouvez donc choisir celui que vous préférez et être sûr qu'il répondra à vos besoins même les plus complexes. À mon avis, Susy a une communauté plus importante, mais ce n'est jamais que mon opinion.

Vous pouvez également choisir quelque chose de plus simple comme csswizardry-grids. Au bout du compte, votre choix n'aura pas beaucoup d'impact sur votre style de code, donc c'est vraiment selon vos goûts et besoins.

SCSS-lint

Il est important de faire l'analyse statique ( lint) de votre code. Si vous suivez les recommandations d'un guide de style, vous réduirez grandement le nombre d'erreurs mais nul n'est parfait et on peut toujours s'améliorer. On peut donc dire que faire l'analyse statique du code est aussi important que le commenter.

SCSS-lint est un outil qui vous aide à conserver des fichiers SCSS propres et lisibles. Il est entièrement personnalisable et facile à intégrer à vos outils de développement.

Par chance, les recommandations de SCSS-lint sont très similaires à celles de ce document. Si vous voulez configurer SCSS-lint selon les recommandations décrites ici, je vous propose la configuration suivante :

Au cas où vous voudriez intégrer SCSS-lint à votre processus de développement Grunt, il existe un plugin appelé grunt-scss-lint.

De plus, si vous cherchez une application soignée qui fonctionne avec SCSS-lint et autres, les ingénieurs de Thoughtbot (Bourbon, Neat...) travaillent sur Hound.

Too Long; Didn't read

Ces règles de conduite sont assez longues, par conséquent il est de bon ton d'avoir une version plus concise. Voici un résumé.

Principes fondamentaux

L'intérêt principal d'un guide de style est la cohérence. Il est normal de ne pas se trouver en accord avec l'intégralité de Sass Guidelines, du moment que la cohérence est maintenue.

Il est important de garder le code Sass aussi simple qu'il puisse être et éviter de bâtir des systèmes complexes à moins d'y être contraint.

Gardez en tête que bien souvent KISS (Keep It Simple, Stupid) est préférable à DRY (Don't Repeat Yourself).

Syntaxe & Formatage

Indentation à 2 espaces, pas de tabulations.

La longueur des lignes doit être inférieure à 80 caractères autant que faire se peut. N'hésitez pas à diviser les lignes trop longues en plusieurs lignes plus courtes quand cela s'avère nécessaire.

Le code CSS doit être écrit de manière propre et évidente, si possible suivant les CSS Guidelines de Harry Roberts.

Les lignes vides ne coûtent rien ; servez-vous en pour séparer les éléments, règles et déclarations.

Chaînes De Caractères

Déclarer la directive @charset en haut de la feuille de styles est fortement encouragé.

À moins d'être utilisées comme identifiants CSS, les chaînes de caractères doivent être mises entre guillemets simples. De même pour les URLs.

Nombres

Sass ne fait pas de distinction entre les nombres, les entiers, les flottants, par conséquent les zéros (0) inutiles après le point sont à éviter. En revanche, les zéros (0) avant le point dans le cas de nombres entre 0 et 1 sont à écrire dans un souci de lisibilité.

Une longueur valant zéro (0) ne devrait pas avoir d'unité.

Les manipulations d'unités devraient être considérées comme des opérations mathématiques standards, pas comme des manipulations de chaînes de caractères.

Afin d'améliorer la lisibilité du code, les calculs doivent être encerclés de parenthèses. De plus, les opérations mathématiques complexes peuvent être éclatées en plusieurs morceaux.

Les nombres magiques sont problématiques pour la maintenance du code et doivent être évités coûte que coûte. Quand cela n'est pas possible, pensez à expliquer la valeur douteuse dans un commentaire.

Couleurs

Les couleurs devraient être exprimées au format HSL si possible, puis RGB et enfin hexadécimal (bas-de-casse et forme raccourcie quand possible). Les mots clés sont à éviter.

Préférez mix(..) au lieu de darken(..) et lighten(..) pour éclaircir ou obscurcir une couleur.

Listes

Maps

Ordre des déclarations

Le système utilisé pour déterminer l'ordre des déclarations (alphabétique, par type, etc.) importe peu du moment qu'il est cohérent et utilisé partout.

Imbrication des sélecteurs

Conventions de nommage

Il est préférable de s'en tenir aux conventions de nommage de CSS qui sont (à l'exception de quelques erreurs) bas-de-casse et séparation par un tiret

CSS est un langage délicat ; n'hésitez pas à écrire des commentaires approfondis pour expliquer toute chose qui paraît douteuse.

Pour les variables, fonctions, mixins et placeholders constituant une API publique, utilisez les commentaires de SassDoc.

Variables

Utilisez le flag !default pour toute variable faisant partie d'une API publique pouvant être changée sans crainte.

N'utilisez pas le flag !global à la racine car il est possible que cela constitue une violation de la syntaxe Sass à l'avenir.

Extend

Contentez-vous d'étendre des placeholders et évitez d'étendre les sélecteurs CSS existants.

Étendez un même placeholder aussi peu que possible afin d'éviter les effets de bord.

# data[].attributes.attachment_link.description
Je m'appelle Kitty Giraudel, je suis un·e développeur·se front-end français·e basé·e à Berlin (Allemagne) depuis 2015, actuellement en poste à Gorillas. Je suis également l'auteur·e d'un livre français sur CSS intitulé CSS3 Pratique du Design Web (publié aux éditions Eyrolles), ainsi qu'un livre sur Sass (en Anglais) intitulé Jump Start Sass (publié aux éditions Learnable).

# data[].attributes.attachment_link.readable_text
Hello Folks 👋

This is Savio here. 14 year old, building useful products. Helping people with tweets and blogs on web development, frotend tips, and interesting resources.

Today, I'd like to share 7 Free Certification Courses for Developers Let's goooo 🚀

FreeCodeCamp is one of the most popular sites offering free certification. FreeCodeCamp is a non-profit organization that consists of an interactive learning web platform, an online community forum, chat rooms, support etc. FreeCodeCamp is the best place to learn code free and earn certification.

10 certifications available:

Responsive Web Design

JavaScript Algorithms and Data Structures

Front End Development

Data Visualization

Backend Development

Quality Assurance

Python

Data Analysis with Python

Information Security

Machine Learning

There are 26 modules to explore, all created by Google trainers, packed full of practical exercises and real-world examples to help you turn knowledge into action.

Learn leading-edge technologies like Blockchain, Data Science, AI, Cloud, Serverless, Docker, Kubernetes and more... with certification fully free of charge. Build your career with skills employers seek.

Free test automation courses with videos, transcripts, quizzes, credits, rank badges, and certificates! everything free thought by experts.

75 hours long course led by leading developers teching Python, the versatile programming language completely free of charge and with certification.

Course includes:

8 Modules

Practice Labs

Module Quizzes and Module Tests

Summary Tests

Final Exam

A perfect blend of in-depth Python theoretical knowledge and strong practical skills, this Free course for Python introduces real-time Python projects to give you a headstart in learning Python and enables you to bag top Python jobs in the industry.

Course includes:

5 real-time projects and 20 complementary projects

100+ hrs of study material, practical codes, quizzes, interview guides

case studies to gain expertise

certificate

Gain the skills you need to do independent data science projects. They pare down complex topics to their key practical components, so you gain usable skills in a few hours (instead of weeks or months). The courses are free, and could earn certificates.

Certifications available:

Python

Pandas

Data Visualization

Feature Engineering

SQL

Deep Learning

Computer Vision

Time Series

Data Cleaning

AI Ethics

Geospatial Analysis

Machine Learning

Natural Language Processing

Intro Intro to Game AI

Thank you to Denic Marko for the inspiration. This article was made from his wonderful thread.

👀 Wrapping Up

Yeah, that's a wrap. Hope you enjoyed the article. Do not hesitate to share your feedback. I am on Twitter @saviomartin7. Give a follow!

Follow me on Github @saviomartin, Don't miss my amazing projects! 💯

Feedbacks are greatly appreciated! 🙌 Have an amazing day!

🌎 Lets connect

# data[].attributes.attachment_link.title
Free Certification Courses for Developers 🔥

# data[].attributes.attachment_link.description
Hello Folks 👋 This is Savio here. 14 year old, building useful products. Helping people with tweets and blogs on web development, frotend tips, and interesting resources. Today, I'd like to share 7 Fr...

# data[].attributes.attachment_link.readable_text
Welcome to Learn CSS! #

This course breaks down the fundamentals of CSS into digestible, easy to understand pieces. Over the next few modules, you'll learn how the core aspects of CSS work and how to use them effectively in your projects. Use the menu pane by the "Learn CSS" logo to navigate the modules.

You'll learn CSS fundamentals like the box model, cascade and specificity, flexbox, grid and z-index. And, along with these fundamentals, you'll learn about functions, color types, gradients, logical properties and inheritance to make you a well-rounded front-end developer, ready to take on any user interface.

Each module is full of interactive demos and self-assessments for you to test your knowledge. In addition to learning through reading and demos, there is an accompanying podcast episode for each topic as another way to learn and continue expanding your knowledge.

This course is created for beginner and advanced CSS developers alike. You can go through the series from start to finish to get a general understanding of CSS from top to bottom, or you can use it as a reference for specific styling subjects. For those new to web development overall, check out Learn HTML to learn all about how to write markup and link your stylesheets.

Here's what you'll learn:

Everything displayed by CSS is a box. Understanding how the CSS Box Model works is therefore a core foundation of CSS.

To apply CSS to an element you need to select it. CSS provides you with a number of different ways to do this, and you can explore them in this module.

Sometimes two or more competing CSS rules could apply to an element. In this module find out how the browser chooses which to use, and how to control this selection.

This module takes a deeper look at specificity, a key part of the cascade.

Some CSS properties inherit if you don't specify a value for them. Find out how this works, and how to use it to your advantage in this module.

There are several different ways to specify color in CSS. In this module we take a look at the most commonly used color values.

In this module find out how to size elements using CSS, working with the flexible medium of the web.

An overview of the various layout methods you have to choose from when building a component or page layout.

Flexbox is a layout mechanism designed for laying out groups of items in one dimension. Learn how to use it in this module.

CSS Grid Layout provides a two dimensional layout system, controlling layout in rows and columns. In this module discover everything grid has to offer.

Logical, flow relative properties and values are linked to the flow of text, rather than the physical shape of the screen. Learn how to take advantage of this newer approach to CSS.

Find out how to select the best method of spacing elements, taking into consideration the layout method you are using and component that you need to build.

A pseudo-element is like adding or targeting an extra element without having to add more HTML. They have a variety of roles and you can learn about them in this module.

Pseudo-classes let you apply CSS based on state changes. This means that your design can react to user input such as an invalid email address.

A border provides a frame for your boxes. In this module find out how to change the size, style and color of borders using CSS.

There are a number of ways to add shadows to text and elements in CSS. In this module you'll learn how to use each option, and the tasks they were designed for.

Understand the importance of focus in your web applications. You'll find out how to manage focus, and how to make sure the path through your page works for people using a mouse, and those using the keyboard to navigate.

In this module find out how to control the order in which things layer on top of each other, by using z-index and the stacking context.

CSS has a range of inbuilt functions. In this module you will find out about some of the key functions, and how to use them.

In this module you will find out how to use the various types of gradients available in CSS. Gradients can be used to create a whole host of useful effects, without needing to create an image using a graphics application.

Animation is a great way to highlight interactive elements, and add interest and fun to your designs. In this module find out how to add and control animation effects with CSS.

Filters in CSS mean that you can apply effects you might only think possible in a graphics application. In this module, you can discover what is available.

Create compositional effects by mixing two or more layers, and learn how to isolate an image with a white background in this module on blend modes.

A list, structurally, is composed of a list container element filled with list items. In this module, you'll learn how to style all the parts of a list.

In this module, learn how to define transitions between states of an element. Use transitions to improve user experience by providing visual feedback to user interaction.

Overflow is how you deal with content that doesn't fit in a set parent size. In this module, you'll think outside the box, and learn how to style overflowing content.

In this module learn the ways you can style backgrounds of boxes using CSS.

In this module, learn how to style text on the web.

Further resources to help you take your next steps.

So, are you ready to learn CSS? Let's get started.

# data[].attributes.attachment_link.description
An evergreen CSS course and reference to level up your web styling expertise.

# data[].attributes.attachment_link.readable_text
We want to hear from you! We are looking for web developers to participate in user research, product testing, discussion groups and more. Apply now to join our WebDev Insights Community.

A collection of layout patterns built using modern CSS APIs that will help you build common interfaces such as cards, dynamic grid areas, and full-page layouts.

Welcome to our growing collection of CSS layout patterns. Most of these patterns use CSS grid and flexbox to help you achieve common UI patterns such as cards, dynamic grid areas, and full-page layouts, and are supported on all modern browsers.

# data[].attributes.attachment_link.description
We want to hear from you! We are looking for web developers to participate in user research, product testing, discussion groups and more. Apply now to join our WebDev Insights Community. A collection of layout patterns built using modern CSS APIs that will help you build common interfaces such as cards, dynamic grid areas, and full-page layouts.

# data[].attributes.attachment_link.description
JavaScript Tutorial provides you with many practical tutorials that help you learn JavaScript from scratch quickly and effectively.