Frontender Magazine

Используйте MathML с CSS деградацией

Я работаю над слайдами для моего следующего доклада: «Скромный border-radius». Он будет о том, как много труда необходимо вложить в CSS-правила, которые на первый взгляд кажутся такими простыми, как border-radius, например, и про то, что нас ждёт в спецификации CSS Backgrounds & Borders 4 (одним из редакторов которой я являюсь). Это будет прекрасный доклад, и вам стоит прийти и послушать, но сейчас речь не об этом.

Как вам известно, я делаю слайды с помощью HTML, CSS и JavaScript. В определённый момент мне понадобилось вставить формулу, чтобы показать как border-top-left-radius (в качестве примера) пропорционально уменьшается, когда сумма радиусов верхней грани достигает ширины элемента. Я не люблю LaTeX, так как он для решения этой задачи генерирует растровые изображения, они не масштабируются без потерь, и это скверный подход с точки зрения доступности.

Очевидным решением было использованием MathML, который, как и SVG, можно встраивать в HTML5 безо всякой XML-фигни. В жизни не писала MathML, но немного почитав и покопавшись в примерах, смогла написать следующий код:

<math display="block">
    <mrow>
        <msub>
            <mi>r&prime;</mi>
            <mi>top-left</mi>
        </msub>
        <mo>=</mo>
        <mi>min</mi>
        <mo>(</mo>
        <msub>
            <mi>r</mi>
            <mrow>
                <mi>top-left</mi>
            </mrow>
        </msub>
        <mo>,</mo>
        <mi>width</mi>
        <mo>&times;</mo>
        <mfrac>
            <mrow>
                <msub>
                    <mi>r</mi>
                    <mi>top-left</mi>
                </msub>
            </mrow>
            <mrow>
                <msub>
                    <mi>r</mi>
                    <mi>top-left</mi>
                </msub>
                <mo>+</mo>
                <msub>
                    <mi>r</mi>
                    <mi>top-right</mi>
                </msub>
            </mrow>
        </mfrac>
        <mo>)</mo>
    </mrow>
</math>

Я очень собой гордилась. Моё первое MathML выражение! На самом деле там всё достаточно просто, если разобраться: <mi> — идентификаторы, <mo> — операторы, которые используются повсеместно. В более сложных задачах <mfrac> используют для дробей (вместе с <mrow> для обозначения строк), <msqrt> — для квадратного корня и так далее.

Всё это очень мило смотрится в Firefox, особенно после того, как я использовала гарнитуру Cambria Math вместо Times, установленной по умолчанию.

Иллюстрация

Однако скоро я поняла, что как бы ни был прекрасен MathML - не все браузеры достигли просветления. И IE10 вместе с Chrome — наиболее значимые из них. В Chrome это выглядит как нечитабельная каша:

Иллюстрация

Существуют библиотеки, которые позволяют добиться кроссбраузерности, наиболее популярная среди них MathJax. Однако она оказалась тяжеловата для моих нужд, мне нужно всего-навсего одно выражение на одном чёртовом слайде. Всё равно, что использовать бензопилу для нарезки хлеба!

Определить, поддерживается ли MathML, оказалось ни разу не просто, и я решила использовать Modernizr. Затем навесила класс .no-mathml вместе с селекторами, адресующими элементы MathML, и определила их представление обычным CSS. Это ни в коем случае не полная CSS библиотека, я описала в ней то, что было нужно мне для одного конкретного выражения и постаралась написать это максимально абстрактно, чтобы, понадобись они мне в будущем, мне оставалось только добавлять новые правила. Вот скриншот результата в Chrome:

Иллюстрация

Выглядит… скажем, хуже чем в Firefox, но вполне прилично. Можете посмотреть CSS в Dabblet:

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

Если вы заметили ошибку, вы всегда можете отредактировать статью, создать issue или просто написать об этом Антону Немцеву в skype ravencry.

Lea Verou
Автор:
Lea Verou
Сaйт:
http://lea.verou.me/
Twitter:
@leaverou
GitHub:
LeaVerou
Facebook:
leaverou
Антон Немцев
Переводчик:
Антон Немцев
Сaйт:
http://frontender.info/
Twitter:
@silentimp
GitHub:
SilentImp
Skype:
ravencry