Skip to content

Use inline SVG for stretchy elements#807

Merged
k4b7 merged 6 commits intoKaTeX:masterfrom
ronkok:master
Aug 20, 2017
Merged

Use inline SVG for stretchy elements#807
k4b7 merged 6 commits intoKaTeX:masterfrom
ronkok:master

Conversation

@ronkok
Copy link
Collaborator

@ronkok ronkok commented Aug 19, 2017

Replace all background-images with inline SVG code.

Pros:

  • \color works in all browsers, even IE/Edge
  • Better printing
  • Much simpler CSS
    • No links to background-images
    • No mask
    • No browser-detection
  • No external SVG files
  • Faster first rendering

Cons

  • No image caching
  • Heavier HTML load
  • Larger JavaScript file
  • \cancel line is in px units, not em units

ronkok added 2 commits August 19, 2017 09:51
Replace all background-images with inline SVG code.

Pros:

* `\color` works in all browsers, even IE/Edge
* Better printing
* Much simpler CSS
    * No links to background-images
    * No `mask`
    * No browser-detection
* No external SVG files
* Faster first rendering

Cons

* No image caching
* Heavier HTML load
* Larger JavaScript file
* `\cancel` line is in `px` units, not `em` units
@ronkok
Copy link
Collaborator Author

ronkok commented Aug 19, 2017

I've put up a test page.

@k4b7
Copy link
Member

k4b7 commented Aug 19, 2017

The test page looks great! I checked IE11 and it looks great too. I'll regenerate the screenshots later today.

@k4b7
Copy link
Member

k4b7 commented Aug 19, 2017

\cancel line is in px units, not em units

The stroke-width can also be controlled by inline CSS, e.g. <line style="stroke-width: 0.2em;"/>.

overleftarrow : "\u2190",
underleftarrow : "\u2190",
xleftarrow : "\u2190",
widehat: "^",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hadn't noticed the difference in : position before. Thanks for aligned this with the style that's used elsewhere.

stroke='currentcolor'/>`,

cancel: `<line x1='0' y1='100%' x2='100%' y2='0' stroke-width='1.5px'
stroke='currentcolor'/>`,
Copy link
Member

@k4b7 k4b7 Aug 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why doesn't this require a > at the start like many of the innerSVG values?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally wrote both svgSpan and encloseSpan so the the first closing > was in the template string, not in innerSVG. But in svgSpan, I found that some of the SVGs were not nested, so I had to remove the > from of the template string and put it into innerSVG.

In encloseSpan, I left that closing > in the template string. I think it makes more sense that way.

const totalHeight = height + depth;
span.style.height = totalHeight + "em";
if (minWidth > 0) {
span.style.minWidth = minWidth + "em";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this necessary?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In cases where no text argument is given, I am trying to render an element that is the same length as the base glyph. That matches LaTeX behavior.

I did the same thing with the original stretchy elements, but the min-width was in the static CSS.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exception: minWidth for the braces is set large enough to avoid a discontinuity where sloping parts of the brace match up.

m8 0v40h399730v-40zm0 194v40h399730v-40z'/></svg>`,

// doubleleftrightarrow is from glyph U+21D4 in font KaTeX Main
doubleleftrightarrow: `><svg width='50.1%' viewBox='0 0 400000 549'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not width='50%'?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we try for an exact 50%-50% match, then floating point rounding error can sometimes create a 1 screen-pixel vertical white line in the middle of the arrow shaft. Setting one side to 50.1% is enough overlap to avoid this. Except one element, I think the braces, where Firefox needed something larger.

], "firstBaseline", null, options);

const styleSpan = accentBody.children[0].children[0].children[1];
styleSpan.classes.push("svg-align"); // text-align: left;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't find the definition for the svg-align class. Is this still needed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very much needed. If that text-align: left is not applied on just the right span, then the elements render smaller, lower, and off to the right.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry... katex.less was collapsed and I didn't click to expand it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you have to open it to see the glorious sight of 575 lines of deleted code.

@ronkok
Copy link
Collaborator Author

ronkok commented Aug 19, 2017

I'll try experimenting with <line style="stroke-width: 0.2em;"/>. But I am trying to avoid a line that changes stroke-width with the area of the span. That means I have to omit the viewBox attribute. And so I'm not sure what em means in the screen context.

@k4b7
Copy link
Member

k4b7 commented Aug 19, 2017

I checked out the changes and ran make build. The resulting minified JS + CSS is 203K vs 193K. With gzipping the minified files, the difference is 49K vs 44K.

@ronkok
Copy link
Collaborator Author

ronkok commented Aug 19, 2017

Well, I'm content with that size change. It's a better product when the SVG is inline.

Kevin Barabash and others added 2 commits August 19, 2017 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants