Синтаксис css. подключение внешних таблиц. создаем первый стиль

Что такое SCSS

SCSS это отдельный формат файла, в котором пишутся стили для сайта. Он очень похож на CSS, но в добавок имеет множество улучшений. Буквально SCSS расшифровывается как Super CSS — то есть CSS c супер-силой.

SCSS пишется в отдельных файлах с расширением , например .

SCSS не подключается в браузер напрямую. Браузеры не умеют с ним работать. SCSS компилируется (собирается) в привычный для браузера CSS код, и уже CSS файл подключается на страницу.

Для того чтобы скомпилировать SCSS в CSS нужно использовать компилятор. Это может быть специальная программа: Koala, Prepros, или другая. Либо плагин для редактора. Или инструмент для сборки проекта: Gulp, Webpack или другой.

На начальном этапе я рекомендую собирать SCSS именно специальными программами, в частности Koala, я вижу это как лучшее решение для старта. Такие программы просты в установке и использовании. Плагины в редакторах — всегда требуют дополнительной настройки от проекта к проекту, могу конфликтовать с другими плагинами. Сборщики вроде Gulp и других — хорошее решение, но подходят для профессионалов, так как требуют дополнительной настройки и ряда дополнительных технологий (npm , node js).

Особенности SCSS

  • Это отдельный формат файла
  • Пишется в отдельных файлах с расширением
  • SCSS не подключается в браузер напрямую
  • SCSS надо компилировать в CSS
  • Дает возможность использовать переменные, вложенные селекторы и медиазапросы, собирать несколько файлов в один, миксины, наследования и многое другое чтобы структурировать работу с CSS кодом

Отличие Sass от SCSS

Sass и SCSS очень похожи, но в них есть пару различий. Sass не использует точки с запятой и не имеет фигурных скобок. Вложенность в Sass определяется отступами.

Пример SCSS кода:

body {
    font-family: sans-serif;
    font-size: 18px;
}

Пример Sass кода:

body 
    font-family: sans-serif
    font-size: 18px

Далее мы продолжим разбирать SCSS синтаксис.

Nesting permalinkNesting

Imports are usually written at the top level of a stylesheet, but they don’t have to be. They can nested within style rules or plain CSS at-rules as well. The imported CSS is nested in that context, which makes nested imports useful for scoping a chunk of CSS to a particular element or media query. Note that top-level mixins, functions, and variables defined in the nested import are still defined globally, though.

Fun fact:

Nested imports are very useful for scoping third-party stylesheets, but if you’re the author of the stylesheet you’re importing, it’s usually a better idea to write your styles in a mixin and include that mixin in the nested context. A mixin can be used in more flexible ways, and it’s clearer when looking at the imported stylesheet how it’s intended to be used.

️ Heads up!

The CSS in nested imports is evaluated like a mixin, which means that any parent selectors will refer to the selector in which the stylesheet is nested.

БЭМ не нужен

Нам не нужен БЭМ, если мы используем CSS-модули. По двум причинам:

  1. Простота чтения. Код вроде так же понятен для разработчика,
    как и из БЭМ. Его даже проще читать, чем разросшиеся
    БЭМ-селекторы.

  2. Локальная область видимости. Допустим, в одном из модулей у нас есть
    класс и он увеличивает на некоторую величину.
    В другом модуле у нас есть точно такой же класс , который
    увеличивает и на другую величину.
    И это не имеет никакого значения! Они не будут конфликтовать,
    так как у стилей различаются области видимости. Даже если модуль импортирует обе
    таблицы стилей, у классов будет своё уникальное имя, созданное в процессе сборки
    специально для них.

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

Круто, да?

И это только некоторые из достоинств использования CSS-модулей.

Если вам интересно узнать больше, Глен Маден (Glen Madden) много пишет
на эту тему.

В следующей статье из этой серии мы рассмотрим как поднять проект используя Webpack и
CSS-модули. Мы будем использовать для этого новейшие возможности ES2015 и
рассмотрим в процессе несколько примеров, чтобы в полной мере разобраться в
происходящем.

Примеры

Пример 1: известен заранее

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

Пример: файлу в проекте нужно импортировать функцию из .

Решение: (или любой другой эквивалентный синтаксис импорта).

Пример 2: мог измениться

Зачастую нам требуется как запускать скрипт напрямую из командной строки, так и импортировать его как модуль в другом скрипте. Как вы увидите далее, здесь могут возникнуть проблемы, особенно в Python 3.

Пример: пусть нужно импортировать , которому нужно импортировать . Предположим, что всегда запускается напрямую, а не импортируется. Также мы хотим иметь возможность запускать напрямую.

Звучит просто, не так ли? Нам всего лишь нужно выполнить два импорта: один в и другой в .

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

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

С импортом в немного сложнее. Когда мы запускаем напрямую, содержит , поэтому в импорт будет выглядеть как . Однако если запустить напрямую, то в уже будет . Теперь импорт вызовет ошибку, так как не является папкой внутри .

Вместо этого мы могли бы попробовать . Это решает проблему при запуске напрямую, однако теперь создаёт проблему при запуске . В Python 3 это приведёт к ошибке, потому что не находится в (в Python 2 это не вызовет проблемы из-за поддержки неявных относительных импортов).

Обобщим информацию:

Запускаем
Нет проблем В Py2 нет проблем, в Py3 ошибка ( не в )
Ошибка ( не в ) Нет проблем

Использование относительного импорта будет иметь тот же эффект, что и .

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

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

  1. В консоли смените директорию на  .
  2. Запустите .

2. Использовать абсолютные импорты относительно директории (средняя колонка в таблице). Это гарантирует, что запуск напрямую всегда сработает. Чтобы запустить напрямую, можно изменить в , чтобы включить перед импортом .

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

3. Использовать только Python 2 и неявные относительные импорты (последняя колонка в таблице).

4. Использовать абсолютные импорты относительно директории и добавить её в переменную среды . Это решение не переносимо, поэтому лучше не использовать его. О том, как добавить директорию в , читайте в этом ответе.

Пример 3: мог измениться (вариант 2)

А вот ещё одна проблема посложнее. Допустим, модуль никогда не надо запускать напрямую, но он импортируется и , которые запускаются напрямую.

В этом случае первое решение из примера выше не сработает. Тем не менее, всё ещё можно использовать остальные решения.

Пример 4: импорт из родительской директории

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

Например, если бы нам пришлось запустить , то этот модуль не смог бы ничего импортировать из без вмешательства в или .

На первый взгляд может показаться, что относительные импорты (например ) помогут решить эту проблему. Однако запускаемый скрипт (в данном случае ) считается «модулем верхнего уровня». Попытка импортировать что-либо из директории над этим скриптом приведёт к ошибке .

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

cssnano набор плагинов

Для полной и многосторонней CSS оптимизации, набор плагинов cssnano от Ben Briggs очень мощный инструмент, но не смотря на это его лишь достаточно подключить и начать работать с ним. Он предоставляет двадцать пять плагинов и может осуществить огромное количество всевозможных оптимизаций.

Помимо большого списка оптимизаций, он может:

  • Убрать пробелы и точку с запятой
  • Убрать комментарии
  • Оптимизировать шрифты
  • Убрать повторяющиеся правила
  • Оптимизировать
  • Минифицировать селекторы
  • Минифицировать длинные свойства
  • Соединить правила

Мы обработаем данным плагином, код из нашего проекта, тем самым на примере увидим применение всех оптимизаций.

Добавьте код в файл «src/style.css»:

После чего скомпилируйте файл.

Обратите внимание: вам стоит закомментировать код который уже имеется, чтобы наглядно увидеть оптимизацию в конечном результате. В файле «dest/style.css» вы должны увидеть оптимизированный код:

В файле «dest/style.css» вы должны увидеть оптимизированный код:

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

  • Пробелы и комментарии, также как и точки с запятой исчезли.
  • и были сконвертированы в и
  • Повторяющиеся правило также исчезло из таблицы стилей
  • Свойство стало статичным значением
  • Селектор были минифицированы в
  • Длинные свойства были сконвертированы в
  • Для стилей и общее свойство было объединено

Чтобы узнать больше о доступных оптимизациях cssnano взгляните на: http://cssnano.co/optimisations/

Конфигурация опций и отключение модулей

Есть несколько независимых плагинов, которые работают с набором cssnano, скорее всего вы захотите настроить их, или отключить некоторые из них.

Чтобы отключить плагин, добавьте название плагина к опциям cssnano с опцией «false». К примеру если нет необходимости оптимизировать шрифты добавьте следующее в Gulpfile/Gruntfile:

Таким же образом можно сконфигурировать опции плагина, добавьте название плагина затем установите необходимую опцию.

Например установить количество десятичных знаков, которые использует плагин calc. По умолчанию выдаст результат равный . Если хотите уменьшить количество десятичных знаков до двух, вы можете сделать это следующим образом:

Результат calc будет равен .

Узнать больше об опциях cssnano можно, посетив: http://cssnano.co/options

Импорт в HTML

Чтобы воспользоваться правилом @import в HTML-файле , добавьте следующий код в шапку страницы:

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

В качестве альтернативного способа применения import url CSS в HTML можно сослаться на таблицу стилей следующим образом:

Эта ссылка работает по принципу @import , и позволяет управлять всем CSS-кодом с помощью отдельного файла. Данный метод предпочтительнее с точки зрения параллельной загрузки. Если вам все еще хочется распределить CSS по отдельным файлам, то можно воспользоваться @import внутри основного стилевого файла.

Импорт в CSS

Применение
в приведенном выше примере позволит внедрить файл « default.css » в HTML-страницу . Внутри этого CSS-файла находятся различные правила стилизации. Эти стили можно разместить как на одной странице, так и разбить их на отдельные фрагменты. А также импортировать в основной файл CSS .

Предположим, что мы используем четыре отдельных CSS-файла : один для разметки, второй для шрифтов и третий для картинок. Четвертым будет основной файл, в котором указаны ссылки на все остальные файлы. В самом верху основного файла ( так как правила импорта должны размещаться над всем остальным содержимым ) добавьте следующий код CSS import :

Уже после этих правил можно добавлять любой CSS-код для оформления страниц.

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

Используем @import в медиа-запросах

Разделение основного CSS-файла может пригодиться при адаптации сайта под мобильные устройства, где для разных разрешений и размеров экрана применяются различные стили. Главная проблема заключается в том, что подключения CSS import расположены в самом верху страницы, поэтому медиа-запросы будут загружены после стилей

При разработке адаптивных дизайнов важно учитывать производительность сайта. Рекомендуется не разделять CSS адаптивного сайта и использовать @import для их загрузки на ресурс

Поддержка браузерами

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

Данная публикация представляет собой перевод статьи « Using @import in Cascading Style Sheets » , подготовленной дружной командой проекта Интернет-технологии.ру

Основы import и sys.path

Вот как оператор производит поиск нужного модуля или пакета согласно документации Python:

Технически документация не совсем полна. Интерпретатор будет искать не только файл (модуль) , но и папку (пакет) .

Обратите внимание, что Python сначала производит поиск среди встроенных модулей — тех, которые встроены непосредственно в интерпретатор. Список встроенных модулей зависит от дистрибутива Python, а найти этот список можно в ( и )

Обычно в дистрибутивах есть модули (всегда включён в дистрибутив), , , и прочие.

В отличие от встроенных модулей, которые при поиске проверяются первыми, остальные (не встроенные) модули стандартной библиотеки проверяются после директории запущенного скрипта. Это приводит к сбивающему с толку поведению: возможно «заменить» некоторые, но не все модули стандартной библиотеки. Допустим, модуль является встроенным модулем, а — нет. Таким образом, в импортирует модуль из стандартной библиотеки, а не наш файл из той же директории. В то же время, в импортирует наш файл .

Lead Software Engineer, Infrastructure

Cube Dev, Удалённо, От 8000 $

tproger.ru

Вакансии на tproger.ru

Кроме того, импорты в Python регистрозависимы: и — разные вещи.

Функцию ( и ) можно использовать, чтобы получить список всех модулей, которые можно импортировать из заданного пути:

Примечание. Возможные проблемы и их решения

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

Такой вариант не подойдет: Такой путь будет работать:

Если имя пользователя в Windows у вас на кириллице, тогда чтобы не переименовывать его, не создавать нового или не переустанавливать систему, просто размещайте все проекты на каком-либо диске, избегая рабочий стол, например:

Plain CSS @imports permalinkPlain CSS @imports

Dart Sass
LibSass
partial
Ruby Sass

By default, LibSass handles plain CSS imports correctly. However, any will incorrectly apply to plain-CSS rules, making it possible for those rules to load Sass files.

Because is also defined in CSS, Sass needs a way of compiling plain CSS s without trying to import the files at compile time. To accomplish this, and to ensure SCSS is as much of a superset of CSS as possible, Sass will compile any s with the following characteristics to plain CSS imports:

  • Imports where the URL ends with .
  • Imports where the URL begins or .
  • Imports where the URL is written as a .
  • Imports that have media queries.

Interpolation

Although Sass imports can’t use interpolation (to make sure it’s always possible to tell where mixins, functions, and variables come from), plain CSS imports can. This makes it possible to dynamically generate imports, for example based on mixin parameters.

Создание стилей CSS. Синтаксис каскадных таблиц стилей — правила, свойства, селекторы.

Далее рассмотрим синтаксис написания правил CSS. Обычный формат определения CSS правила выглядит так:

Т.е. правило стиля включает в себя селектор стиля и список свойств стиля с их значениями в фигурных скобках(«{» и «}»):

  • селектор используется для привязки к элементам web-страницы, на которые он должен распространять свое действие;
  • пары «Свойство: Значение» разделяются символом точкой с запитой(«;») и их может быть сколь угодно много;
  • между последней парой «Свойство: Значение» и закрывающей фигурной скобкой символ точка с запитой можно не ставить;
  • свойство  стиля представляет из себя один из параметров элемента html страницы: цвет текста, гарнитура шрифта, величина отступов;
  • пробелы и переводы строк при написании правил css не критичны, браузер их игнорирует, поэтому можно оформлять код так как вам захочется;
  • так же код не чувствителен к регистру символов.

Чтобы было понятней рассмотрим несколько примеров.

 Разберем данное CSS правило:

  • body — это селектор, который представляет из себя имя тега body;
  • background — свойство стиля, с помощью которого задаются параметры фона;
  • #0000FF — значение свойства стиля background, которой представляет из себя код цвета в формате RGB.

В итоге данный стиль применится к элементу body web страницы и окрасит фон страницы в заданный цвет. Рассмотренный стиль называется стилем переопределения тега, потому что в качестве селектора указано имя тега без символов .

Рассмотрим еще пример:

Этот стиль говорит о том, что браузер выведет любой текст помещенный в теги h1 зеленым цветом и задаст ему размер шрифта 24 пикселя.

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

.yellowtext {color:yellow}

Имя класса должно состоять из букв латинского алфавита, цифр и дефисов и начинаться должно с буквы. А в определении CSS правила перед именем класса должна стоять точка, означающая что определяется стилевой класс. Данный стиль будет применен ко всем  тегам, у которых будет задан атрибут class и его значение будет равно имени стилевого класса без точки:

В примере мы привязали к тегу «Р» css правило с помощью имени класса yellowtext. В результате текст в данном абзаце будет отображен оранжевым цветом.

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

В этом примере к тегу «Р» мы привязали сразу два класса: yellowtext и cursivtext. В результате содержимое тега отобразится желтым цветом и курсивным шрифтом.

Кроме классов в качестве селектора правила css можно использовать идентификатор, который определяет уникальное имя элемента. Здесь все также как и в случае со стилевыми классами, только есть несколько отличий:

  • в селекторе правила CSS, также задается имя идентификатора, только вместо точки перед его именем ставят символ решетки «#»;
  • привязка к html элементу осуществляется через атрибут id, в качестве значения которого устанавливают имя стиля без знака решетки;
  • значение атрибута id должно быть уникальным в пределах страницы, то есть в html коде может только один элемент с заданным значение атрибута id, иначе код будет не валидным.

Рассмотрим пример для ясности:

К элементу p (абзац) с помощью атрибута id привязывается правило css, которое выравнивает текст по центру страницы. На странице больше не допускается создавать элементы с таким значением атрибута id, иначе html код будет не валидным.

Кроме рассмотренных способов описания стилей, css позволяет создавать комбинированные стили и задавать сразу несколько одинаковых стилей. Посмотрим пример:

h1.redtext, p strong {color: red}

В примере через запятую указано два селектора: «h1.redtext» и «p strong». Первый селектор говорит о том, что во всех элементах h1 у которых значение атрибута class буде эквивалентно redtext, текст будет отображаться красным цветом. Во втором селекторе произойдет тоже самое для всех элементов strong, которые вложены в тег p:

Советы по CSS модулям

CSS Модули — вычесть существующие CSS. В погоне заПростой и управляемыйАвтор рекомендует следующие принципы:

  • Нет селекторов, только имена классов для определения стилей
  • Не складывайте несколько классов, используйте только один класс для определения всех стилей
  • Все стили пройденыСочетание для достижения повторного использования
  • Не вложенный

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

Важно знать, что вышесказанное называется рекомендацией, поскольку модули CSS не заставляют вас делать это. Это звучит немного противоречиво: поскольку большинство CSS-проектов имеют глубокие исторические проблемы, слишком много ограничений означают увеличение затрат на миграцию и затрат на внешнее сотрудничество

Определенные компромиссы определенно необходимы при первоначальном использовании. К счастью, CSS-модули делают это хорошо:

Что если я использую несколько классов для элемента?

Нет проблем, стиль все еще в силе.

Как использовать одно и то же имя класса в файле стиля?

Нет проблем, эти скомпилированные классы с одинаковыми именами могут быть случайными кодами, но они по-прежнему имеют одинаковые имена.

Что если я использую псевдоклассы, селекторы тегов и т. Д. В файле стиля? Нет проблем, все эти селекторы не будут преобразованы и будут отображаться в скомпилированном CSS. Другими словами, CSS-модули будут преобразовывать только стили, связанные с именами классов и имен селекторов идентификаторов.

Но обратите внимание, что вышеупомянутые три «если» стараются не произойти

Простой CSS @import permalinkПростой CSS @import

Dart Sass
LibSass
partial
Ruby Sass

По умолчанию LibSass правильно обрабатывает простой импорт CSS. Однако любые будут неправильно применяться к правилам простого CSS , что позволяет этим правилам загружать файлы Sass.

Поскольку также определен в CSS, Sass нужен способ компиляции простого CSS без попытки импортировать файлы во время компиляции. Чтобы добиться этого и гарантировать, что SCSS является как можно большей частью надмножества CSS, Sass будет компилировать любой со следующими характеристиками в простой импорт CSS:

  • Импортирует, где URL заканчивается на .
  • Импортирует, где URL начинается с или .
  • Импортирует, где URL-адрес записан как .
  • Импорт с медиа-запросами.

Интерполяция

Хотя при импорте Sass нельзя использовать интерполяцию (чтобы всегда можно было определить, откуда берутся примеси, функции и переменные), простой импорт CSS может. Это позволяет динамически генерировать импорт, например, на основе параметров миксина.

Синтаксис CSS-правил

Давайте разберем основу основ CSS, а именно, синтаксис написания CSS-правил. Сделаем это на примере правила для тега
<h1> , которое мы написали выше.

Посмотрите на картинку:

Объявление стиля (или CSS-правило) состоит из 2-х частей:

  1. Селектор, в нашем случает h1 (о селекторах позже поговорим подробнее)
  2. Блок объявлений (находится после селектора в фигурных скобках)

В блоке объявлений, может находится множество объявлений. Каждое объявление состоит из:

  • Свойства, которое определяет что будет сделано (в примере text-align – т.е. текст будет выровнен);
  • Двоеточия «:» – разделяет свойство и значение;
  • Значение, которое описывает как браузер должен обработать свойство (в примере center – т.е. текст будет выровнен по центру)

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

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

Вот справочный указатель на портале mdn: https://developer.mozilla.org/ru/docs/Web/CSS/Reference

Также мне нравится справочник: https://webref.ru/css

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

Практический алгоритм действий.

Предположим, стоит задача сделать красный текст на желтом фоне.

Мы понимаем, что надо:

  • Сделать цвет шрифта красным
  • Сделать желтый фон

Ищем подходящие свойства – это color и background-color. В итоге:

{
    color: red;
    background-color: yellow;
}

1
2
3
4

{

colorred;

background-coloryellow;

}

Пример сложнее. Скажем, вам требуется, в каком-то блоке, фоном которого является картинка, написать текст. Вы пишите его и понимаете, что фоновая картинка слишком пестрая и текст на ней не читается.

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

Но! Вот проблема: вы в принципе не понимаете, как это сделать, какие свойства искать, как к этому подступиться.

Выход простой – в большинстве случаев это кто-то уже делал, идете в поисковик и ищите. Главное правильно сформулировать запрос. Если с первого раза не нашли, переформулируйте запрос.

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

Посмотрите поисковую выдачи, вы найдете ответ на свой запрос, и даже, с примерами.

Если вам не совсем понятны примеры, то смотрите из каких свойств состоят правила, ищите эти свойства в справочнике и читайте описания.

Рейтинг
( Пока оценок нет )
Editor
Editor/ автор статьи

Давно интересуюсь темой. Мне нравится писать о том, в чём разбираюсь.

Понравилась статья? Поделиться с друзьями:
Люкс-хост
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: