One place for hosting & domains

      помощью

      Создание стилей панелей прокрутки с помощью CSS


      Введение

      В сентябре 2018 г. комитет W3C в документе CSS Scrollbars определил спецификации настройки внешнего вида панелей прокрутки с помощью CSS.

      В 2020 году 96% пользователей Интернета запускали браузеры, поддерживающие стили панелей прокрутки CSS. Однако, чтобы реализовать поддержку Blink, WebKit и браузеров Firefox, нужно написать два набора правил CSS.

      В этом учебном модуле вы научитесь использовать CSS, чтобы настраивать панели прокрутки для поддержки современных браузеров.

      Предварительные требования

      Для понимания этой статьи вам потребуется:

      Создание стилей панелей прокрутки для Chrome, Edge и Safari

      Для создания стилей панелей прокрутки для Chrome, Edge и Safari требуется псевдоэлемент -webkit-scrollbar с префиксом поставщика.

      Вот пример с использованием псевдоэлементов ::-webkit-scrollbar, ::-webkit-scrollbar-track и ::webkit-scrollbar-thumb:

      body::-webkit-scrollbar {
        width: 12px;               /* width of the entire scrollbar */
      }
      
      body::-webkit-scrollbar-track {
        background: orange;        /* color of the tracking area */
      }
      
      body::-webkit-scrollbar-thumb {
        background-color: blue;    /* color of the scroll thumb */
        border-radius: 20px;       /* roundness of the scroll thumb */
        border: 3px solid orange;  /* creates padding around scroll thumb */
      }
      

      Это снимок экрана панели прокрутки, созданной с помощью этих правил CSS:

      Снимок экрана примера веб-страницы с персонализированной синей панелью прокрутки на оранжевом фоне.

      Данный код работает с последними версиями браузеров Chrome, Edge и Safari.

      К сожалению, данная спецификация была формально отменена W3C, и, вероятно, со временем ее перестанут использовать.

      Создание стилей панелей прокрутки в Firefox

      Для создания стилей панелей прокрутки для Firefox используются новые CSS Scrollbars.

      В этом примере используются свойства scrollbar-width и scrollbar-color:

      body {
        scrollbar-width: thin;          /* "auto" or "thin" */
        scrollbar-color: blue orange;   /* scroll thumb and track */
      }
      

      Это снимок экрана панели прокрутки, созданной с помощью этих правил CSS:

      Снимок экрана примера веб-страницы с персонализированной синей панелью прокрутки на оранжевом фоне.

      Эта спецификация похожа на спецификацию -webkit-scrollbar способом контроля цвета панели прокрутки. Однако в настоящее время отсутствует поддержка заполнения и округления курсора.

      Создание готовых к будущему стилей панели прокрутки

      Вы можете писать код CSS так, чтобы он поддерживал и спецификацию -webkit-scrollbar, и спецификацию CSS Scrollbars.

      В этом примере используются свойства scrollbar-width, scrollbar-color, ::-webkit-scrollbar, ::-webkit-scrollbar-track, ::webkit-scrollbar-thumb:

      /* Works on Firefox */
      * {
        scrollbar-width: thin;
        scrollbar-color: blue orange;
      }
      
      /* Works on Chrome, Edge, and Safari */
      *::-webkit-scrollbar {
        width: 12px;
      }
      
      *::-webkit-scrollbar-track {
        background: orange;
      }
      
      *::-webkit-scrollbar-thumb {
        background-color: blue;
        border-radius: 20px;
        border: 3px solid orange;
      }
      

      Браузеры Blink и WebKit игнорируют правила, которые они не распознают, и применяют правила -webkit-scrollbar. Браузеры Firefox игнорируют правила, которые они не распознают, и применяют правила CSS Scrollbars. Когда в браузерах Blink и WebKit полностью перестанет использоваться спецификация -webkit-scrollbar, они постепенно перейдут на новую спецификацию CSS Scrollbars.

      Заключение

      В это статье мы кратко рассказали об использовании CSS для создания стилей панелей прокрутки и о том, как обеспечить распознавание этих стилей большинством современных браузеров.

      Также существует возможность моделирования панели прокрутки. Для этого нужно скрыть панель прокрутки по умолчанию и использовать JavaScript для определения высоты и положения прокрутки. Однако эти подходы связаны с ограничениями в таких случаях, как инерционная прокрутка (например, замедление движения при прокрутке с использованием трекпада).

      Если вы хотите узнать больше о CSS, на нашей странице тем по CSS вы найдете полезные упражнения и проекты по программированию.



      Source link

      Развертывание масштабируемого и защищенного приложения Django с помощью Kubernetes


      Введение

      В этом учебном модуле мы развернем контейнеризованное приложение Django polls в кластере Kubernetes.

      Django — это мощная веб-структура, позволяющая быстро развернуть ваше приложение Python с нуля. Она включает ряд удобных функций, в том числе реляционную карту объектов, аутентификацию пользователей и настраиваемый административный интерфейс для вашего приложения. Также она включает систему кэширования и помогает проектировать оптимизированные приложения с помощью диспетчера URL и системы шаблонов.

      В учебном модуле Создание приложения Django и Gunicorn с помощью Docker мы изменили приложение Polls из учебного модуля Django согласно методологии Двенадцать факторов, предназначенной для построения масштабируемых веб-приложений, оптимизированных для работы в облаке. Для масштабирования и защиты контейнера использовался обратный прокси-сервер Nginx и подписанный Let’s Encrypt сертификат TLS (см. описание в учебном модуле Масштабирование и защита приложения Django с помощью Docker, Nginx и Let’s Encrypt). В этом последнем учебном модуле из серии От контейнеров к Kubernetes с Django мы покажем, как развернуть модернизированное приложение Django polls в кластере Kubernetes.

      Kubernetes — мощная система оркестрации контейнеров с открытым исходным кодом, помогающая автоматизировать развертывание, масштабирование и управление контейнеризованными приложениями. Такие объекты Kubernetes как ConfigMaps и Secrets позволяют централизовать конфигурацию и отсоединить ее от контейнеров, а такие контроллеры как Deployments автоматически перезагружают неработающие контейнеры и позволяют быстро масштабировать реплики контейнеров. Шифрование TLS активируется с помощью объекта Ingress и контроллера ingress-nginx с открытым исходным кодом. Надстройка Kubernetes cert-manager проверяет и выпускает сертификаты, используя бесплатный центр сертификации Let’s Encrypt.

      Предварительные требования

      Для данного обучающего модуля вам потребуется следующее:

      • Кластер Kubernetes версии 1.15 или выше с включенным контролем доступа на основе ролей (RBAC). В нашем примере будет использоваться кластер DigitalOcean Kubernetes, но вы можете создать кластер с помощью другого метода.
      • Инструмент командной строки kubectl, установленный на локальном компьютере и настроенный для подключения к вашему кластеру. Дополнительную информацию об установке kubectl можно найти в официальной документации. Если вы используете кластер DigitalOcean Kubernetes, ознакомьтесь с руководством Подключение к кластеру DigitalOcean Kubernetes, чтобы узнать, как подключиться к кластеру с помощью kubectl.
      • Зарегистрированное доменное имя. В этом учебном модуле мы будем использовать имя your_domain.com. Вы можете получить бесплатный домен на Freenom или зарегистрировать доменное имя по вашему выбору.
      • Контроллер ingress-nginx и диспетчер сертификатов TLS cert-manager должны быть установлены в вашем кластере и настроены на использование сертификатов TLS. Чтобы узнать, как установить и настроить Ingress с помощью cert-manager, воспользуйтесь руководством Настройка Nginx Ingress с помощью Cert-Manager в кластере DigitalOcean Kubernetes.
      • Запись DNS A для your_domain.com, указывающая на публичный IP-адрес балансировщика нагрузки Ingress. Если вы используете DigitalOcean для управления записями DNS вашего домена, руководство Управление записями DNS поможет вам научиться создавать записи класса A.
      • Хранилище объектов S3, например пространство DigitalOcean, для хранения статических файлов проекта Django и набор ключей доступа к этому пространству. Чтобы узнать, как создать пространство, ознакомьтесь с документом Как создавать пространства. Чтобы узнать, как создать ключи доступа, ознакомьтесь со статьей Предоставление доступа к пространству с помощью ключей доступа. Внеся незначительные изменения, вы можете использовать любой сервис хранения, который поддерживает плагин django-storages.
      • Экземпляр сервера PostgreSQL, база данных и пользователь для приложения Django. Внеся незначительные изменения, вы можете использовать любую базу данных, которую поддерживает Django.
      • Учетная запись Docker Hub и публичный репозиторий. Более подробную информацию по их созданию можно найти в разделе Repositories (Репозитории) в документации по Docker.
      • Система Docker, установленная на локальном компьютере. Более подробную информацию можно найти в руководстве Установка и использование Docker в Ubuntu 18.04.

      Проверив наличие этих компонентов, вы можете начать прохождение этого обучающего модуля.

      Шаг 1 — Клонирование и настройка приложения

      На этом шаге мы клонируем код приложения с GitHub и настроим такие параметры, как учетные данные БД и ключи хранения объектов.

      Код приложения и файл Dockerfile можно найти в ветви polls-docker репозитория Django Tutorial Polls App на GitHub. Этот репозиторий содержит код приложения Polls, используемого в документации по Django в качестве образца, на примере которого показывается, как создать приложение для опросов с нуля.

      Ветвь polls-docker содержит размещенную в контейнере Docker версию приложения Polls. Более подробную информацию об изменениях, внесенных в приложение Polls для эффективной работы в контейнеризированной среде, можно найти в руководстве Создание приложения Django и Gunicorn с помощью Docker.

      Для начала используйте git, чтобы клонировать ветвь polls-docker репозитория Django Tutorial Polls App на GitHub на локальном компьютере:

      • git clone --single-branch --branch polls-docker https://github.com/do-community/django-polls.git

      Перейдите в каталог django-polls:

      В этом каталоге содержится код Python приложения Django, файл Dockerfile, который Docker будет использовать для построения образа контейнера, а также файл env, содержащий список переменных среды для передачи в рабочую среду контейнера. Проверьте файл Dockerfile:

      Output

      FROM python:3.7.4-alpine3.10 ADD django-polls/requirements.txt /app/requirements.txt RUN set -ex && apk add --no-cache --virtual .build-deps postgresql-dev build-base && python -m venv /env && /env/bin/pip install --upgrade pip && /env/bin/pip install --no-cache-dir -r /app/requirements.txt && runDeps="$(scanelf --needed --nobanner --recursive /env | awk '{ gsub(/,/, "nso:", $2); print "so:" $2 }' | sort -u | xargs -r apk info --installed | sort -u)" && apk add --virtual rundeps $runDeps && apk del .build-deps ADD django-polls /app WORKDIR /app ENV VIRTUAL_ENV /env ENV PATH /env/bin:$PATH EXPOSE 8000 CMD ["gunicorn", "--bind", ":8000", "--workers", "3", "mysite.wsgi"]

      В качестве базы в файле Dockerfile используется официальный образ Docker Python 3.7.4, который устанавливает требуемые пакеты Python для Django и Gunicorn в соответствии с файлом django-polls/requirements.txt. Затем он удаляет некоторые ненужные файлы сборки, копирует код приложения в образ и устанавливает параметр выполнения PATH. И в заключение заявляет, что порт 8000 будет использоваться для принятия входящих подключений контейнера, и запускает gunicorn с тремя рабочими элементами, прослушивающими порт 8000.

      Дополнительную информацию о каждом этапе в Dockerfile см. в шаге 6 руководства Создание приложения Django и Gunicorn с помощью Docker.

      Теперь создайте образ с помощью docker build:

      Назовем образ polls, используя флаг -t, и передадим в текущий каталог как контекст сборки набор файлов для справки при построении образа.

      После того как Docker создаст и отметит образ, перечислите доступные образы, используя docker images:

      Вы должны увидеть образ polls:

      OutputREPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
      polls               latest              80ec4f33aae1        2 weeks ago         197MB
      python              3.7.4-alpine3.10    f309434dea3a        8 months ago        98.7MB
      

      Перед запуском контейнера Django нам нужно настроить его рабочую среду с помощью файла env, присутствующего в текущем каталоге. Этот файл передается в команду docker run, которая используется для запуска контейнера, после чего Docker внедрит настроенные переменные среды в рабочую среду контейнера.

      Откройте файл env с помощью nano или своего любимого редактора:

      django-polls/env

      DJANGO_SECRET_KEY=
      DEBUG=True
      DJANGO_ALLOWED_HOSTS=
      DATABASE_ENGINE=postgresql_psycopg2
      DATABASE_NAME=polls
      DATABASE_USERNAME=
      DATABASE_PASSWORD=
      DATABASE_HOST=
      DATABASE_PORT=
      STATIC_ACCESS_KEY_ID=
      STATIC_SECRET_KEY=
      STATIC_BUCKET_NAME=
      STATIC_ENDPOINT_URL=
      DJANGO_LOGLEVEL=info
      

      Заполните недостающие значения для следующих ключей:

      • DJANGO_SECRET_KEY: задает уникальное, непрогнозируемое значение, как описано в документации Django. Один метод генерирования этого ключа представлен в разделе Изменение настроек приложения руководства Масштабируемое приложение Django.
      • DJANGO_ALLOWED_HOSTS: эта переменная защищает приложение и предотвращает атаки через заголовки хоста HTTP. С целью тестирования установите * как подстановочный символ, подходящий для всех хостов. В производственной среде следует использовать значение your_domain.com. Дополнительную информацию об этой настройке Django см. в разделе Core Settings (Базовые настройки) документации Django.
      • DATABASE_USERNAME: задает пользователя базы данных PostgreSQL, созданного на предварительных этапах.
      • DATABASE_NAME: задает polls или имя базы данных, созданной на предварительных этапах.
      • DATABASE_PASSWORD: задает пароль пользователя базы данных PostgreSQL, созданного на предварительных этапах.
      • DATABASE_HOST: задает имя хоста базы данных.
      • DATABASE_PORT: укажите порт вашей базы данных.
      • STATIC_ACCESS_KEY_ID: укажите ключ доступа своего пространства или хранилища объектов.
      • STATIC_SECRET_KEY: укажите секретный ключ своего пространства или хранилища объектов.
      • STATIC_BUCKET_NAME: укажите имя своего пространства или корзину хранилища объектов.
      • STATIC_ENDPOINT_URL: укажите URL соответствующего пространства или конечного пункта хранилища объектов, например https://your_space_name.nyc3.digitaloceanspaces.com, если ваше пространство находится в области nyc3.

      После завершения редактирования сохраните и закройте файл.

      На следующем шаге мы запустим настроенный контейнер в локальной среде и создадим схему базы данных. Также мы выгрузим в хранилище объектов статические ресурсы, такие как таблицы стилей и изображения.

      Шаг 2 — Создание схемы базы данных и выгрузка ресурсов в хранилище объектов

      После построения и настройки контейнера используйте docker run, чтобы заменить заданную команду CMD в файле Dockerfile и создайте схему базы данных, используя команды manage.py makemigrations и manage.py migrate:

      • docker run --env-file env polls sh -c "python manage.py makemigrations && python manage.py migrate"

      Мы запускаем образ контейнера polls:latest, передаем в только что измененный файл переменной среды и переопределяем команду Dockerfile с помощью sh -c "python manage.py makemigrations && python manage.py migrate", которая создаст схему базы данных, определяемую кодом приложения.

      Если запускаете эти команды впервые, вы должны увидеть следующее:

      Output

      No changes detected Operations to perform: Apply all migrations: admin, auth, contenttypes, polls, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying auth.0010_alter_group_name_max_length... OK Applying auth.0011_update_proxy_permissions... OK Applying polls.0001_initial... OK Applying sessions.0001_initial... OK

      Это означает, что схема базы данных успешно создана.

      При последующем запуске команды migrate Django не будет выполнять никаких операций, если схема базы данных не изменилась.

      Затем мы запустим еще один экземпляр контейнера приложения и используем внутри него интерактивную оболочку для создания административного пользователя проекта Django.

      • docker run -i -t --env-file env polls sh

      Вы получите строку оболочки внутри работающего контейнера, которую сможете использовать для создания пользователя Django:

      • python manage.py createsuperuser

      Введите имя пользователя, адрес электронной почты и пароль для пользователя, а после создания пользователя нажмите CTRL+D для выхода из контейнера и его удаления.

      В заключение мы создадим статические файлы приложения и загрузим их в пространство DigitalOcean с помощью collectstatic. Обратите внимание, что для завершения процесса может потребоваться время.

      • docker run --env-file env polls sh -c "python manage.py collectstatic --noinput"

      После создания и загрузки файлов вы получите следующий вывод.

      Output

      121 static files copied.

      Теперь мы можем запустить приложение:

      • docker run --env-file env -p 80:8000 polls

      Output

      [2019-10-17 21:23:36 +0000] [1] [INFO] Starting gunicorn 19.9.0 [2019-10-17 21:23:36 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1) [2019-10-17 21:23:36 +0000] [1] [INFO] Using worker: sync [2019-10-17 21:23:36 +0000] [7] [INFO] Booting worker with pid: 7 [2019-10-17 21:23:36 +0000] [8] [INFO] Booting worker with pid: 8 [2019-10-17 21:23:36 +0000] [9] [INFO] Booting worker with pid: 9

      Мы запустим определенную в Dockerfile команду по умолчанию gunicorn --bind :8000 --workers 3 mysite.wsgi:application и откроем порт контейнера 8000, чтобы установить соответствие порта 80 на локальном компьютере и порта 8000 контейнера polls.

      Теперь у вас должна появиться возможность открыть приложение polls в браузере, для чего нужно ввести http://localhost в адресную строку. Поскольку маршрут для пути / не определен, скорее всего, вы получите ошибку 404 Страница не найдена.

      Введите в адресную строку http://localhost/polls, чтобы увидеть интерфейс приложения Polls:

      Интерфейс приложения «Опросы»

      Чтобы открыть интерфейс администрирования, введите адрес http://localhost/admin. Вы должны увидеть окно аутентификации администратора приложения «Опросы»:

      Страница аутентификации администратора приложения

      Введите имя администратора и пароль, которые вы создали с помощью команды createsuperuser.

      После аутентификации вы сможете получить доступ к административному интерфейсу приложения «Опросы»:

      Основной интерфейс администратора приложения

      Обратите внимание, что статические активы приложений admin и polls поступают напрямую из хранилища объекта. Чтобы убедиться в этом, ознакомьтесь с материалами Тестирование доставки статических файлов пространства.

      После завершения изучения данных нажмите CTRL+C в окне терминала, где запущен контейнер Docker, чтобы удалить контейнер.

      Когда образ Docker приложения Django будет протестирован, статичные ресурсы будут выгружены в хранилище объектов, а схема базы данных будет настроена и готова к выгрузке образа приложения Django в реестр образов, например в Docker Hub.

      Шаг 3 — Размещение образа приложения Django в Docker Hub

      Чтобы развернуть приложение в Kubernetes, необходимо будет выгрузить образ приложения в реестр, например, в Docker Hub. Kubernetes извлечет образ приложения из репозитория, а затем развернет его в кластере.

      Вы можете использовать частный реестр Docker, например, реестр контейнеров DigitalOcean Container Registry, предварительная версия которого в настоящее время предоставляется бесплатно, или публичный реестр Docker, такой как Docker Hub. Docker Hub также позволяет создавать частные репозитории Docker. Публичный репозиторий позволяет любому пользователю видеть и извлекать образы контейнеров, а в частном репозитории доступ имеется только у вас и у членов вашей команды.

      В этом учебном модуле мы разместим образ Django в публичном репозитории Docker Hub, созданном на этапе предварительных требований. Также вы можете перенести образ в частный репозиторий, однако извлечение образов из частного репозитория в этой статье не описывается. Чтобы получить более подробную информацию об аутентификации Kubernetes с Docker Hub и извлечении образов из частного репозитория, ознакомьтесь со статьей Pull an Image from a Private Registry (Извлечение образа из частного реестра) в документации по Kubernetes.

      Для начала выполните вход в Docker Hub на локальном компьютере:

      Output

      Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username:

      Введите имя пользователя и пароль Docker Hub для входа в систему.

      Образ Django сейчас помечен тегом polls:latest. Чтобы поместить его в ваш репозиторий Docker Hub, измените теги образа, указав свое имя пользователя Docker Hub и имя репозитория:

      • docker tag polls:latest your_dockerhub_username/your_dockerhub_repo_name:latest

      Разместите образ в репозитории:

      • docker push sammy/sammy-django:latest

      В этом учебном модуле мы используем имя пользователя Docker Hub sammy и имя репозитория sammy-django. Вам следует заменить эти значения своим именем пользователя Docker Hub и именем репозитория.

      По мере размещения слоев образа в Docker Hub вы будете видеть на экране определенные сообщения.

      Теперь ваш образ доступен Kubernetes в репозитории Docker Hub, и вы можете начать его развертывание в своем кластере.

      Шаг 4 — Настройка ConfigMap

      При локальном запуске контейнера Django мы передали файл env в docker run для вставки переменных конфигурации в среду исполнения. Для вставки переменных конфигурации в Kubernetes используются элементы ConfigMap и Secret.

      Элементы ConfigMap следует использовать для сохранения неконфиденциальной информации о конфигурации, такой как параметры приложения, а элементы Secret следует использовать для хранения важной информации, такой как ключи API и учетные данные для входа в базу данных. Они вставляются в контейнеры примерно одинаково, но у элементов Secret имеются дополнительные функции контроля доступа и безопасности, такие как шифрование в состоянии покоя. Элементы Secret хранят данные в формате base64, а элементы ConfigMap хранят данные в формате обычного текста.

      Для начала необходимо создать каталог yaml, где мы будем хранить наши манифесты Kubernetes. Перейдите в каталог.

      Откройте файл polls-configmap.yaml в nano или в другом предпочитаемом текстовом редакторе:

      • nano polls-configmap.yaml

      Вставьте в него следующий манифест ConfigMap:

      polls-configmap.yaml

      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: polls-config
      data:
        DJANGO_ALLOWED_HOSTS: "*"
        STATIC_ENDPOINT_URL: "https://your_space_name.space_region.digitaloceanspaces.com"
        STATIC_BUCKET_NAME: "your_space_name"
        DJANGO_LOGLEVEL: "info"
        DEBUG: "True"
        DATABASE_ENGINE: "postgresql_psycopg2"
      

      Мы извлекли неконфиденциальные данные конфигурации из файла env, измененного на шаге 1, и передали их в манифест ConfigMap. Объект ConfigMap носит имя polls-config. Скопируйте те же самые значения, введенные в файл env на предыдущем шаге.

      Для тестирования оставьте для DJANGO_ALLOWED_HOSTS значение *, чтобы отключить фильтрацию на основе заголовков хоста. В производственной среде здесь следует указать домен вашего приложения.

      Когда вы завершите редактирование файла, сохраните и закройте его.

      Создайте в своем кластере элемент ConfigMap, используя kubectl apply:

      • kubectl apply -f polls-configmap.yaml

      Output

      configmap/polls-config created

      Мы создали элемент ConfigMap, а на следующем шаге мы создадим элемент Secret, который будет использоваться нашим приложением.

      Шаг 5 — Настройка элемента Secret

      Значения Secret должны иметь кодировку base64, то есть создавать объекты Secret в кластере немного сложнее, чем объекты ConfigMaps. Вы можете повторить описанную на предыдущем шаге процедуру, выполнив кодирование значений Secret в формате base64 вручную и вставив их в файл манифеста. Также вы можете создавать их, используя файл переменных среды, kubectl create и флаг --from-env-file, что мы и сделаем на этом шаге.

      Мы снова используем файл env из шага 1, удалив переменные, вставленные в ConfigMap. Создайте копию файла env с именем polls-secrets в каталоге yaml:

      • cp ../env ./polls-secrets

      Отредактируйте файл в предпочитаемом редакторе:

      polls-secrets

      DJANGO_SECRET_KEY=
      DEBUG=True
      DJANGO_ALLOWED_HOSTS=
      DATABASE_ENGINE=postgresql_psycopg2
      DATABASE_NAME=polls
      DATABASE_USERNAME=
      DATABASE_PASSWORD=
      DATABASE_HOST=
      DATABASE_PORT=
      STATIC_ACCESS_KEY_ID=
      STATIC_SECRET_KEY=
      STATIC_BUCKET_NAME=
      STATIC_ENDPOINT_URL=
      DJANGO_LOGLEVEL=info
      

      Удалите все переменные, вставленные в манифест ConfigMap. Когда вы закончите, содержимое файла должно выглядеть следующим образом:

      polls-secrets

      DJANGO_SECRET_KEY=your_secret_key
      DATABASE_NAME=polls
      DATABASE_USERNAME=your_django_db_user
      DATABASE_PASSWORD=your_django_db_user_password
      DATABASE_HOST=your_db_host
      DATABASE_PORT=your_db_port
      STATIC_ACCESS_KEY_ID=your_space_access_key
      STATIC_SECRET_KEY=your_space_access_key_secret
      

      Обязательно используйте те же значения, что и на шаге 1. Закончив, сохраните и закройте файл.

      Создайте в кластере объект Secret, используя kubectl create secret:

      • kubectl create secret generic polls-secret --from-env-file=poll-secrets

      Output

      secret/polls-secret created

      Здесь мы создадим объект Secret с именем polls-secret и передадим в него созданный нами файл secrets.

      Вы можете проинспектировать объект Secret, используя kubectl describe:

      • kubectl describe secret polls-secret

      Output

      Name: polls-secret Namespace: default Labels: <none> Annotations: <none> Type: Opaque Data ==== DATABASE_PASSWORD: 8 bytes DATABASE_PORT: 5 bytes DATABASE_USERNAME: 5 bytes DJANGO_SECRET_KEY: 14 bytes STATIC_ACCESS_KEY_ID: 20 bytes STATIC_SECRET_KEY: 43 bytes DATABASE_HOST: 47 bytes DATABASE_NAME: 5 bytes

      Мы сохранили конфигурацию вашего приложения в кластере Kubernetes, используя типы объектов Secret и ConfigMap. Мы готовы развернуть приложение в кластере.

      Шаг 6 — Развертывание приложения Django с помощью контроллера Deployment

      На этом шаге мы создадим Deployment для вашего приложения Django. Kubernetes Deployment — контроллер, который можно использовать для управления приложениями без состояния в вашем кластере. Контроллер — это контур управления, регулирующий рабочие задачи посредством вертикального масштабирования. Контроллеры также перезапускают и очищают неисправные контейнеры.

      Контроллеры Deployment контролируют один или несколько подов. Под — это наименьшая развертываемая единица в кластере Kubernetes. Поды содержат один или несколько контейнеров. Чтобы узнать о различных типах рабочих задач, ознакомьтесь с учебным модулем Введение в Kubernetes.

      Для начала откройте файл polls-deployment.yaml в предпочитаемом текстовом редакторе:

      • nano polls-deployment.yaml

      Вставьте в него следующий манифест Deployment:

      polls-deployment.yaml

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: polls-app
        labels:
          app: polls
      spec:
          replicas: 2
        selector:
          matchLabels:
            app: polls
        template:
          metadata:
            labels:
              app: polls
          spec:
            containers:
              - image: your_dockerhub_username/app_repo_name:latest
                name: polls
                envFrom:
                - secretRef:
                    name: polls-secret
                - configMapRef:
                    name: polls-config
                ports:
                  - containerPort: 8000
                    name: gunicorn
      

      Введите соответствующее имя образа контейнера, ссылаясь на образ Django Polls, который вы разместили в Docker Hub на шаге 2.

      Здесь мы определяем контроллер Kubernetes Deployment с именем polls-app и присваиваем ему пару ключ-значение app: polls. Мы указываем, что хотим запустить две реплики пода, определенного под полем template.

      Используя envFrom с secretRef и configMapRef, мы указываем, что все данные из объектов polls-secret и polls-config следует вставить в контейнеры как переменные среды. Ключи ConfigMap и Secret становятся именами переменных среды.

      В заключение мы откроем порт containerPort 8000 и назовем его gunicorn.

      Чтобы узнать больше о настройке контроллеров Kubernetes Deployment, ознакомьтесь с разделом Deployments в документации по Kubernetes.

      Когда вы завершите редактирование файла, сохраните и закройте его.

      Создайте в кластере контроллер Deployment, используя kubectl apply -f:

      • kubectl apply -f polls-deployment.yaml
      • deployment.apps/polls-app created

      Убедитесь, что контроллер Deployment развернут правильно, используя kubectl get:

      • kubectl get deploy polls-app

      Output

      NAME READY UP-TO-DATE AVAILABLE AGE polls-app 2/2 2 2 6m38s

      Если вы столкнетесь с ошибкой или что-то не будет работать, вы можете использовать kubectl describe для проверки неработающего контроллера Deployment:

      Чтобы проинспектировать два пода, используйте kubectl get pod:

      Output

      NAME READY STATUS RESTARTS AGE polls-app-847f8ccbf4-2stf7 1/1 Running 0 6m42s polls-app-847f8ccbf4-tqpwm 1/1 Running 0 6m57s

      В кластеры запущены и работают две реплики вашего приложения Django. Чтобы получить доступ к приложению, вам нужно создать Kubernetes Service, и мы сделаем это на следующем шаге.

      Шаг 7 — Предоставление внешнего доступа с использованием Service

      На этом шаге мы создаем Service для нашего приложения Django. Kubernetes Service — это абстракция, позволяющая предоставить доступ к набору работающих подов как к сетевой службе. Используя Service, вы можете создать для вашего приложения стабильный конечный пункт, который не будет изменяться по мере уничтожения и воссоздания подов.

      Существует несколько типов служб Service, в том числе службы ClusterIP, открывающие доступ к Service через внутренний IP-адрес кластера, службы NodePort, открывающие доступ к Service на каждом узле статического порта NodePort, и службы LoadBalancer, предоставляющие облачный балансировщик нагрузки для управления внешним трафиком подов вашего кластера (через порты NodePort, которые он создает автоматически). Чтобы узнать больше об этом, ознакомьтесь с разделом Service в документации по Kubernetes.

      На заключительном шаге настройки мы используем службу ClusterIP Service, доступ к которой открыт через Ingress и контроллер Ingress, настроенный на этапе подготовки к этому учебному модулю. Сейчас мы убедимся, что все элементы работают корректно. Для этого мы создадим временную службу NodePort Service для доступа к приложению Django.

      Для начала создайте файл с именем polls-svc.yaml в предпочитаемом редакторе:

      Вставьте в него следующий манифест Service:

      polls-svc.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: polls
        labels:
          app: polls
      spec:
        type: NodePort
        selector:
          app: polls
        ports:
          - port: 8000
            targetPort: 8000
      

      Здесь мы создаем службу NodePort под названием polls и присваиваем ей ярлык app: polls. Мы выберем поды серверной части с ярлыком app: polls и установим в качестве цели порты 8000.

      Когда вы завершите редактирование файла, сохраните и закройте его.

      Разверните Service с помощью команды kubectl apply:

      • kubectl apply -f polls-svc.yaml

      Output

      service/polls created

      Убедитесь, что служба была создана с использованием kubectl get svc:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE polls NodePort 10.245.197.189 <none> 8000:32654/TCP 59s

      Этот вывод показывает внутренний IP-адрес кластера службы и номер порта NodePort (32654). Чтобы подключиться к службе, нам потребуется внешний IP-адрес для нашего узла кластера:

      Output

      NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME pool-7no0qd9e0-364fd Ready <none> 27h v1.18.8 10.118.0.5 203.0.113.1 Debian GNU/Linux 10 (buster) 4.19.0-10-cloud-amd64 docker://18.9.9 pool-7no0qd9e0-364fi Ready <none> 27h v1.18.8 10.118.0.4 203.0.113.2 Debian GNU/Linux 10 (buster) 4.19.0-10-cloud-amd64 docker://18.9.9 pool-7no0qd9e0-364fv Ready <none> 27h v1.18.8 10.118.0.3 203.0.113.3 Debian GNU/Linux 10 (buster) 4.19.0-10-cloud-amd64 docker://18.9.9

      Откройте в браузере приложение Polls, используя внешний IP-адрес и порт NodePort любого узла. С учетом приведенного выше вывода URL приложения будет выглядеть так: http://203.0.113.1:32654/polls.

      Вы должны увидеть тот же интерфейс приложения Polls, который вы открыли локально на шаге 1:

      Интерфейс приложения «Опросы»

      Вы можете повторить ту же проверку, используя маршрут /admin: http://203.0.113.1:32654/admin. Вы увидите тот же интерфейс администрирования, что и раньше:

      Страница аутентификации администратора приложения

      Мы развернули две реплики контейнера приложения Django Polls, используя Deployment. Также мы создали стабильный конечный пункт сети для этих двух реплик и обеспечили внешний доступ к ним через службу NodePort.

      Заключительный шаг этого учебного модуля заключается в том, чтобы защитить внешний трафик нашего приложения, используя HTTPS. Для этого мы используем контроллер ingress-nginx, установленный на этапе предварительных требований, и создадим объект Ingress для перенаправления внешнего трафика в службу Kubernetes polls.

      Шаг 8 — Настройка HTTPS с использованием Nginx Ingress и cert-manager

      Сущности Ingress в Kubernetes обеспечивают гибкую маршрутизацию внешнего трафика кластера Kubernetes среди служб внутри кластера. Это достигается с помощью ресурсов Ingress, которые определяют правила маршрутизации трафика HTTP и HTTPS для служб Kubernetes, и контроллеров Ingress, которые реализуют правила посредством балансировки нагрузки трафика и его перенаправления на соответствующие службы серверной части.

      На этапе предварительных требований мы установили контроллер ingress-nginx и надстройку cert-manager для автоматизации сертификатов TLS. Также мы настроили испытательную и производственную среду ClusterIssuers для вашего домена, используя центр сертификации Let’s Encrypt, и создали объект Ingress для проверки выдачи сертификатов и шифрования TLS для двух фиктивных серверных служб. Прежде чем продолжить выполнение этого шага, удалите объект echo-ingress, созданный в подготовительном учебном модуле:

      • kubectl delete ingress echo-ingress

      При желании вы также можете удалить фиктивные службы и развертывания, используя команды kubectl delete svc и kubectl delete deploy, но для прохождения этого учебного модуля это не обязательно.

      Также вы должны были создать запись DNS типа A для your_domain.com, указывающую на публичный IP-адрес балансировщика нагрузки Ingress. Если вы используете балансировщик нагрузки DigitalOcean, вы можете найти этот IP-адрес в разделе Load Balancers панели управления. Если вы также используете DigitalOcean для управления записями DNS вашего домена, руководство Управление записями DNS поможет вам научиться создавать записи класса A.

      Если вы используете DigitalOcean Kubernetes, убедитесь, что вы внедрили обходное решение, описанное в шаге 5 учебного модуля Настройка Nginx Ingress с помощью Cert-Manager в DigitalOcean Kubernetes.

      Когда у вас будет запись A, указывающая на балансировщик нагрузки контроллера Ingress, вы можете создать Ingress для your_domain.com и службы polls.

      Откройте файл с именем polls-ingress.yaml в предпочитаемом текстовом редакторе:

      Вставьте следующий манифест Ingress:

      [polls-ingress.yaml]
      apiVersion: networking.k8s.io/v1beta1
      kind: Ingress
      metadata:
        name: polls-ingress
        annotations:
          kubernetes.io/ingress.class: "nginx"
          cert-manager.io/cluster-issuer: "letsencrypt-staging"
      spec:
        tls:
        - hosts:
          - your_domain.com
          secretName: polls-tls
        rules:
        - host: your_domain.com
          http:
            paths:
            - backend:
                serviceName: polls
                servicePort: 8000
      

      Мы создаем объект Ingress под именем polls-ingress и добавляем к нему аннотацию, чтобы уровень управления использовал контроллер ingress-nginx и размещение ClusterIssuer. Также мы включаем TLS для домена your_domain.com и сохраняем сертификат и закрытый ключ в объекте Secret с именем polls-tls. В заключение мы определяем правило перенаправления трафика для хоста your_domain.com в службу polls через порт 8000.

      Когда вы завершите редактирование файла, сохраните и закройте его.

      Создайте в кластере объект Ingress, используя kubectl apply:

      • kubectl apply -f polls-ingress.yaml

      Output

      ingress.networking.k8s.io/polls-ingress created

      Вы можете использовать kubectl describe для отслеживания состояния только что созданного объекта Ingress:

      • kubectl describe ingress polls-ingress

      Output

      Name: polls-ingress Namespace: default Address: workaround.your_domain.com Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>) TLS: polls-tls terminates your_domain.com Rules: Host Path Backends ---- ---- -------- your_domain.com polls:8000 (10.244.0.207:8000,10.244.0.53:8000) Annotations: cert-manager.io/cluster-issuer: letsencrypt-staging kubernetes.io/ingress.class: nginx Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 51s nginx-ingress-controller Ingress default/polls-ingress Normal CreateCertificate 51s cert-manager Successfully created Certificate "polls-tls" Normal UPDATE 25s nginx-ingress-controller Ingress default/polls-ingress

      Также вы можете запустить команду describe для сертификата polls-tls, чтобы убедиться, что он был успешно создан:

      • kubectl describe certificate polls-tls

      Output

      . . . Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Issuing 3m33s cert-manager Issuing certificate as Secret does not exist Normal Generated 3m32s cert-manager Stored new private key in temporary Secret resource "polls-tls-v9lv9" Normal Requested 3m32s cert-manager Created new CertificateRequest resource "polls-tls-drx9c" Normal Issuing 2m58s cert-manager The certificate has been successfully issued

      Это подтверждает, что сертификат TLS успешно выдан, и шифрование HTTPS для домена your_domain.com активно.

      Поскольку мы использовали тестовую версию ClusterIssuer, большинство браузеров не будут доверять поддельному сертификату Let’s Encrypt, который она выдает, и поэтому при переходе по адресу your_domain.com появится страница с сообщением об ошибке.

      Чтобы отправить тестовый запрос, мы используем wget из командной строки:

      • wget -O - http://your_domain.com/polls

      Output

      . . . ERROR: cannot verify your_domain.com's certificate, issued by ‘CN=Fake LE Intermediate X1’: Unable to locally verify the issuer's authority. To connect to your_domain.com insecurely, use `--no-check-certificate'.

      Мы используем предлагаемый флаг --no-check-certificate, чтобы пропустить проверку сертификата:

      • wget --no-check-certificate -q -O - http://your_domain.com/polls

      Output

      <link rel="stylesheet" type="text/css" href="https://your_space.nyc3.digitaloceanspaces.com/django-polls/static/polls/style.css"> <p>No polls are available.</p>

      В этом выводе показан код HTML для страницы интерфейса /polls, а также подтверждается выдача таблицы стилей из хранилища объектов.

      Мы успешно проверили выдачу сертификата с помощью тестовой версии ClusterIssuer и теперь можем изменить Ingress для использования производственной версии ClusterIssuer.

      Снова откройте файл polls-ingress.yaml для редактирования:

      Измените аннотацию cluster-issuer:

      [polls-ingress.yaml]
      apiVersion: networking.k8s.io/v1beta1
      kind: Ingress
      metadata:
        name: polls-ingress
        annotations:
          kubernetes.io/ingress.class: "nginx"
          cert-manager.io/cluster-issuer: "letsencrypt-prod"
      spec:
        tls:
        - hosts:
          - your_domain.com
          secretName: polls-tls
        rules:
        - host: your_domain.com
          http:
            paths:
            - backend:
                serviceName: polls
                servicePort: 8000
      

      Внесите необходимые изменения, после чего сохраните и закройте файл. Обновите Ingress, используя kubectl apply:

      • kubectl apply -f polls-ingress.yaml

      Output

      ingress.networking.k8s.io/polls-ingress configured

      Вы можете использовать команды kubectl describe certificate polls-tls и kubectl describe ingress polls-ingress для отслеживания статуса выдачи сертификата:

      • kubectl describe ingress polls-ingress

      Output

      . . . Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 23m nginx-ingress-controller Ingress default/polls-ingress Normal CreateCertificate 23m cert-manager Successfully created Certificate "polls-tls" Normal UPDATE 76s (x2 over 22m) nginx-ingress-controller Ingress default/polls-ingress Normal UpdateCertificate 76s cert-manager Successfully updated Certificate "polls-tls"

      Приведенный выше вывод подтверждает, что новый производственный сертификат успешно выдан и сохранен в объекте Secret polls-tls.

      Откройте в браузере адрес your_domain.com/polls, чтобы убедиться, что шифрование HTTPS включено, и все работает ожидаемым образом. Вы должны увидеть интерфейс приложения Polls:

      Интерфейс приложения «Опросы»

      Убедитесь, что в браузере включено шифрование HTTPS. Если вы используете Google Chrome, то если вышеуказанная страница откроется без ошибок, это будет означать, что все работает правильно. Кроме того, на панели URL должно быть изображение замка. Нажав на замок, вы сможете просмотреть детали сертификата Let’s Encrypt.

      Для окончательной очистки вы можете переключить тип службы polls с NodePort на внутренний тип ClusterIP.

      Отредактируйте файл polls-svc.yaml в текстовом редакторе:

      Измените type с NodePort на ClusterIP:

      polls-svc.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: polls
        labels:
          app: polls
      spec:
        type: ClusterIP
        selector:
          app: polls
        ports:
          - port: 8000
            targetPort: 8000
      

      Когда вы завершите редактирование файла, сохраните и закройте его.

      Разверните изменения с помощью команды kubectl apply:

      • kubectl apply -f polls-svc.yaml --force

      Output

      service/polls configured

      Убедитесь, что служба Service была изменена, используя kubectl get svc:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE polls ClusterIP 10.245.203.186 <none> 8000/TCP 22s

      Этот вывод показывает, что тип Service — ClusterIP. Для доступа можно использовать только домен и Ingress, созданный на этом шаге.

      Заключение

      В этом учебном модуле мы развернули масштабируемое приложение Django с защитой HTTPS в кластере Kubernetes. Статичный контент выдается напрямую из хранилища объектов, а количество работающих подов можно быстро увеличивать или уменьшать, используя поле replicas в манифесте Deployment polls-app.

      Если вы используете пространство DigitalOcean Space, вы также можете включить доставку статичных ресурсов через сеть доставки контента и создать настраиваемый субдомен для своего пространства. Дополнительную информацию можно найти в разделе Включение CDN учебного модуля Настройка масштабируемого приложения Django с управляемыми базами данных и пространствами DigitalOcean.

      С остальными частями серии можно ознакомиться на странице От контейнеров к Kubernetes с Django.



      Source link

      Предотвращение разрывов строки с помощью CSS


      Введение

      Разработчики обычно предпочитают применять на веб-страницах перенос по словам. Перенос по словам ограничивает текст и помогает предотвратить проблемы с дизайном. Также перенос текста по словам позволяет предотвратить необходимость горизонтальной прокрутки. Однако иногда бывает так, что нужно оставить блок текста на одной строке вне зависимости от ее длины. Вы можете предотвращать разрывы строк и перенос текста по словам для определенных элементов, используя свойство CSS white-space.

      В этом учебном модуле мы определим стили одного и того же блока текста четырьмя разными способами, один раз с разрывами строки, а три раза без разрывов строки:

      Medusafish banded killifish convict blenny saury threadsail beluga sturgeon. Indian mul mora cisco masu salmon, roosterfish requiem shark longnose lancetfish bluefish red snapper Sacramento splittail giant danio.

      Medusafish banded killifish convict blenny saury threadsail beluga sturgeon. Indian mul mora cisco masu salmon, roosterfish requiem shark longnose lancetfish bluefish red snapper Sacramento splittail giant danio.

      Medusafish banded killifish convict blenny saury threadsail beluga sturgeon. Indian mul mora cisco masu salmon, roosterfish requiem shark longnose lancetfish bluefish red snapper Sacramento splittail giant danio.

      Medusafish banded killifish convict blenny saury threadsail beluga sturgeon. Indian mul mora cisco masu salmon, roosterfish requiem shark longnose lancetfish bluefish red snapper Sacramento splittail giant danio.

      Это даст вам несколько способов выбрать, нужно ли переносить текст по словам.

      Предварительные требования

      Для данного обучающего руководства вам потребуется следующее:

      Шаг 1 — Предотвращение и форсирование разрывов строки в CSS

      На этом шаге мы создадим таблицу стилей с тремя разными классами. Каждый из них будет по разному обрабатывать разрывы строк: первый класс будет разбивать текст на строки стандартным способом, а второй и третий классы запретят создание новой строки и разрыва строки.

      Для начала создайте новый файл с именем main.css, используя nano или предпочитаемый редактор:

      Добавьте в файл следующий код, после чего у вас появятся три класса CSS, использующие несколько свойств, в том числе white-space:

      ./main.css

      .sammy-wrap {
          border-radius: 6px;
          background-color: aliceblue;
          border: 2px dashed gray;
          max-width: 70%;
          padding: 1em;
          margin-bottom: .4em;
      }
      .sammy-nowrap-1 {
          border-radius: 6px;
          background-color: aliceblue;
          border: 2px dashed gray;
          max-width: 70%;
          padding: 1em;
          margin-bottom: .4em;
          white-space: nowrap;
      }
      .sammy-nowrap-2 {
          border-radius: 6px;
          background-color: aliceblue;
          border: 2px dashed gray;
          max-width: 70%;
          padding: 1em;
          margin-bottom: .4em;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
      }
      

      Наш первый класс — .sammy-wrap. Он определяет шесть общих свойств CSS, в том числе border-radius, background-color, border max-width, padding и margin-bottom. Этот класс создает визуальное поле, но при этом не определяет каких-либо специальных свойств переноса текста. Это означает, что строки будут разбиваться по умолчанию.

      Наш второй класс — .sammy-nowrap-1. Он определяет то же поле, что и .sammy-wrap, но добавляет новое свойство: white-space. Свойство white-space имеет множество опций, и все эти опции определяют обработку пробелов внутри заданного элемента. Здесь мы задаем для свойства white-space значение nowrap, предотвращающее разрывы строк.

      Наш третий класс — .sammy-nowrap-2. Он добавляет свойство white-space и еще два дополнительных свойства: overflow и text-overflow. Свойство overflow обрабатывает переполнение с прокруткой, когда содержимое элемента выходит за границы этого элемента. Свойство overflow может сделать этот контент доступным для прокрутки, видимым или скрытым. Мы зададим для свойства overflow значение hidden, а затем используем свойство text-overflow для дополнительной настройки. Свойство text-overflow помогает сообщить пользователю, что часть текста остается скрытой. Мы установили для него значение ellipsis так, что строка не разрывается и не выходит за пределы поля. CSS скрывает лишний текст и использует значок ... для обозначения скрытого текста.

      Сохраните и закройте файл.

      Теперь у нас имеется таблица стилей и мы готовы создать небольшой файл HTML с примерами текста. Далее мы загрузим веб-страницу в браузер и посмотрим, как код CSS может предотвратить появление разрывов строки.

      Шаг 2 — Создание файла HTML

      После определения классов CSS вы можете применить их к образцам текста.

      Создайте и откройте файл с именем index.html в предпочитаемом редакторе. Обязательно поместите его в ту же папку, что и файл main.css:

      Добавьте в файл следующий код, который установит main.css как вашу таблицу стилей, а затем применит классы к полю с образцом текста:

      ./index.html

      <!DOCTYPE HTML>
      <html>
      <head>
      <meta charset="UTF-8">
      <title>How To Prevent Line Breaks with CSS</title>
      <link href="https://www.digitalocean.com/community/tutorials/main.css" rel="stylesheet">
      </head>
      
      <body>
      <p class="sammy-wrap"    > Medusafish banded killifish convict blenny saury threadsail beluga sturgeon. Indian mul mora cisco masu salmon, roosterfish requiem shark longnose lancetfish bluefish red snapper Sacramento splittail giant danio.</p>
      
      <p class="sammy-nowrap-1"> Medusafish banded killifish convict blenny saury threadsail beluga sturgeon. Indian mul mora cisco masu salmon, roosterfish requiem shark longnose lancetfish bluefish red snapper Sacramento splittail giant danio.</p>
      
      <p class="sammy-nowrap-2"> Medusafish banded killifish convict blenny saury threadsail beluga sturgeon. Indian mul mora cisco masu salmon, roosterfish requiem shark longnose lancetfish bluefish red snapper Sacramento splittail giant danio.</p>
      
      <p class="sammy-wrap"    > Medusafish&nbsp;banded&nbsp;killifish&nbsp;convict&nbsp;blenny&nbsp;saury&nbsp;threadsail&nbsp;beluga&nbsp;sturgeon.&nbsp;Indian&nbsp;mul&nbsp;mora&nbsp;cisco&nbsp;masu&nbsp;salmon,&nbsp;roosterfish&nbsp;requiem&nbsp;shark&nbsp;longnose&nbsp;lancetfish&nbsp;bluefish&nbsp;red&nbsp;snapper&nbsp;Sacramento&nbsp;splittail&nbsp;giant&nbsp;danio.</p>
      </body>
      </html>
      

      Мы назначили стандартный стиль переноса по словам для первого блока текста, стиль nowrap — для второго, и стиль nowrap со свойством hidden и многоточием — для третьего. Для четвертого образца мы назначили стиль sammy-wrap, но здесь мы обходим перенос строк по умолчанию, вставляя в код HTML неразрывные пробелы (&nbsp;). Если вам нужно предотвратить разрывы строки в одном частном случае, неразрывные пробелы могут помочь сделать это быстро.

      Откройте файл index.html в браузере и посмотрите результаты. Наши четыре текстовых блока будут выглядеть следующим образом:

      Medusafish banded killifish convict blenny saury threadsail beluga sturgeon. Indian mul mora cisco masu salmon, roosterfish requiem shark longnose lancetfish bluefish red snapper Sacramento splittail giant danio.

      Medusafish banded killifish convict blenny saury threadsail beluga sturgeon. Indian mul mora cisco masu salmon, roosterfish requiem shark longnose lancetfish bluefish red snapper Sacramento splittail giant danio.

      Medusafish banded killifish convict blenny saury threadsail beluga sturgeon. Indian mul mora cisco masu salmon, roosterfish requiem shark longnose lancetfish bluefish red snapper Sacramento splittail giant danio.

      Medusafish banded killifish convict blenny saury threadsail beluga sturgeon. Indian mul mora cisco masu salmon, roosterfish requiem shark longnose lancetfish bluefish red snapper Sacramento splittail giant danio.

      Мы успешно настроили свойства CSS четырьмя разными способами так, чтобы допускать или не допускать разрывы строк.

      Заключение

      В этом учебном модуле мы использовали CSS, чтобы предотвратить разрывы строк в текстовом блоке. Мы задали стиль текста внутри поля и добавили свойство white-space, чтобы заменить правила переноса текста по умолчанию. Чтобы узнать больше о переносе текста по словам и пробелах, изучите свойство white-space CSS в полном объеме.



      Source link