Почему в CSS и SVG допустимо большое количество магических чисел?


63

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

Когда я смотрю на это, я думаю: «Тьфу! Какой уродливый блок кода. Надеюсь, я никогда не увижу подобные вещи в своем проекте ». Тем не менее, я вижу эти типы вопросов и ответов довольно часто и с большим количеством откликов, поэтому сообщество явно не считает их плохими.

Но почему это приемлемо? Исходя из моего внутреннего опыта это не имеет смысла для меня. Так почему же это нормально для CSS / SVG?


38
Что такое рисунок, если не случайный набор магических чисел (например, штрихи между 2 (x, y) точками или массивы пикселей и т. Д.), Которые выглядят хорошо?

68
Есть ли в CSS переменные? Есть ли SVG?
Одед

36
Вот почему многие крупные проекты имеют CSS-препроцессор, такой как SASS или LESS, который поддерживает переменные.
Ixrec

2
@Oded Для CSS, глобальная поддержка переменных составляет около 40% (поэтому не рекомендуется, если вы не хотите сказать всем своим посетителям Microsoft, что они не приветствуются). Microsoft, вероятно, будет следовать тенденции в Edge, и мобильные устройства в конечном итоге догонят. В SVG, с другой стороны, есть понятие переменных в каком-то заброшенном проекте документа о статусе, но они, вероятно, никогда не будут реализованы.
phyrfox

12
Почему? Потому что они не магические числа. CSS хранит данные, в отличие от программы, которая содержит инструкции. Хотя CSS, вероятно, завершен, он не является языком программирования.
Дерек 朕 會 功夫

Ответы:


117

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

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

x += 23;

Вы спросите «почему 23»? В чем причина? Переменная может уточнить намерение:

x += defaultHttpTimeoutSeconds;

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

background-color: #ffffff;
font-size: 16px;

Высота и цвет не волшебны, потому что значение совершенно ясно из контекста. И причина выбора значения spefic проста, потому что дизайнеры думали, что это будет хорошо выглядеть. Введение переменной ничего не поможет, так как в любом случае вы просто дадите ей имя " defaultBackgroundColor" и " defaultFontSize".


16
Некоторые ценности действительно выбраны просто потому, что «они хорошо выглядят». Но пример, связанный с OP, содержит одно и то же значение несколько раз, но не ясно, представляют ли они одно и то же или имеют одно и то же значение по совпадению. Также он использует значение, 198pxкоторое является разницей размера чего-то другого ( 200px) и 2pxграницы.
CodesInChaos

1
@CodesInChaos: Да, в некоторых случаях переменные или какие-то выражения зависимостей были бы классными.
JacquesB

21
Обратите внимание , что CSS делает переменную поддержку
phihag

28
@phihag В спецификациях, да, но в дикой природе , не так много (я не считаю 40% глобальной поддержки на момент написания этого комментария "широко поддерживаемой". Однако вы правы, говоря, что в В будущем у нас будут CSS-переменные. И я узнал кое-что новое сегодня, так что спасибо за это.
phyrfox

2
@JaredSmith Это хорошо для относительно крупномасштабного веб-приложения, однако для обычных (возможно, статических) страниц, включая огромный полифилл, это излишне.
Дерек 朕 會 功夫

80

Это приемлемо, потому что эти форматы не код , а данные . Если бы вы удалили все «магические числа», вы бы по сути продублировали каждую метку и в итоге получили бы смешные файлы, такие как:

mainkite_width = 200px
...
.mainkite {
  width: mainkite_width;
  ...

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


22
+1 потому что: «Это приемлемо, потому что эти форматы не код, а данные».
Питер Б

1
«Конечно, есть ситуации, когда хорошо избегать дублирования, например, если у вас часто повторяется цвет, и вы можете захотеть изменить его, чтобы сменить тему». - Вероятно, лучше все-таки сделать с классами: .main_color { color: .. }и использование этого класса - метод дедупликации
Изката

1
Код, который определяет внешний вид приложения, по-прежнему является кодом, а не данными.
ESR

25

Запрет на магические числа является изначальной версией этого принципа дизайна:

Принимайте решения в одном месте .

Но это не магические числа . По крайней мере, не так, как в любом известном мне руководстве по стилю кодирования.

ширина: 200 пикселей;
высота: 200 пикселей;

Они четко обозначены. Конечно, цифры оказываются одинаковыми. Но ширина - это ширина, а высота - это высота. Они разработаны, чтобы варьироваться независимо.

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

Я бы не назвал их магическими числами, если бы они были помечены, но я бы все же побил тебя палкой косвенного обращения.


4
Если у вас было достаточно объектов, чтобы нуждаться в переменной, у вас достаточно объектов для создания нового класса.
Jaketr00

1
Это лучший ответ, поскольку он показывает точку зрения: это не магические числа.
TheBlastOne

2
«5 объектов, которые должны были иметь одинаковую ширину и каждый независимо жестко закодировать их ширину, я бы побил тебя палкой». Добро пожаловать в увлекательный мир веб-дизайна.
whatsisname

2
Магические числа проблематичны не только из-за «Принимать решения в одном месте» (иначе СУХОЙ), но и потому, что их трудно понять.
Слеське

Есть ли альтернатива избиению палкой?
Джечлин

10

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

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

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

Сначала мы вводим тонны магических чисел в наш код. Ширина поля, высота текста, отступы и т. Д. И т. Д.

jump(100) // The margin
drawTable(500, 500)
writeText("Hello World", 12)

Итак, мы извлекаем магические числа и помещаем их поверх нашего файла.

int margin = 100
int table = 500
int text_size = 12
jump(margin) // The margin
drawTable(table, table)
writeText("Hello World", text_size)

Теперь это немного некрасиво. Мы скорее читаем наши переменные номера из файла конфигурации.

margin 100
table 500
text size 12

Мм, это немного неясно ... Что означают эти цифры? Что означают эти имена? Давайте немного формализуем это.

margin_left 10em
table_width 500px
table_height 500px
font_size 12px

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


Вы чувствуете, куда это идет, в конечном итоге вы получаете CSS. (И браузер, чтобы сделать это.)

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

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

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

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

В конце концов, вам не нужно слишком много магических чисел в вашем конфигурационном файле :-)


Почему это важно, где избыточность? Не будет ли техническое обслуживание проблемой, независимо от того, где оно находится?
Питер Мортенсен

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

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

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

5

Почему [куча, казалось бы, случайных жестко запрограммированных значений] подходит для CSS / SVG?

Это не хорошо Это можно писать и поддерживать простые файлы «.css», но в конечном итоге случайные жестко закодированные значения станут распространенным бременем.

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.