Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use inline SVG for stretchy elements #807

Merged
merged 6 commits into from
Aug 20, 2017
Merged

Use inline SVG for stretchy elements #807

merged 6 commits into from
Aug 20, 2017

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

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.

@kevinbarabash
Copy link
Member

kevinbarabash commented Aug 19, 2017

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

@kevinbarabash
Copy link
Member

\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.

src/stretchy.js Outdated
stroke='currentcolor'/>`,

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

@kevinbarabash kevinbarabash 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.

accentBody = buildCommon.makeVList([
{type: "elem", elem: body},
{type: "elem", elem: accentBody},
], "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.

@kevinbarabash
Copy link
Member

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.

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.

None yet

2 participants