A world-class math input for the web
at main 224 lines 4.7 kB view raw
1html, 2body, 3#app { 4 width: 100%; 5 height: 100%; 6 margin: 0; 7 padding: 0; 8 overflow: hidden; 9} 10 11#app { 12 display: grid; 13 grid-template-columns: 1fr 1fr; 14 grid-template-rows: 1fr 1fr; 15 grid-template-areas: 16 "input-area parsed-area" 17 "tokens-area parsed-area"; 18} 19 20#input-area, 21#tokens-area, 22#parsed-area, 23#parsed-diagram-area { 24 border: 1px solid black; 25 padding: 10px; 26 overflow: auto; 27} 28 29#input-area { 30 grid-area: input-area; 31 overflow: hidden; 32} 33#tokens-area { 34 grid-area: tokens-area; 35} 36#parsed-area { 37 grid-area: parsed-area; 38} 39#parsed-diagram-area { 40 grid-area: parsed-diagram-area; 41} 42 43.math { 44 font-family: Symbola, "Times New Roman", serif; 45 font-size: 24px; 46 font-weight: 400; 47 padding: 0.25em 0.5em; 48 /* font-size: 75px; */ 49 50 display: inline-block; 51 border: 1px solid black; 52 53 /* No wrapping */ 54 box-sizing: border-box; 55 white-space: nowrap; 56 max-width: 100%; 57 overflow-x: auto; 58} 59 60.strand > * { 61 margin: 0 0.08em; 62} 63 64.cursor { 65 margin: 0 -0.04em; 66 display: inline-block; 67 border-left: 1px solid black; 68 vertical-align: baseline; 69 animation: blink 1s steps(1) infinite; 70 71 /* 72 The cursor contains a zero-width space for styling purposes (so it has a natural character height but no width). 73 If users accidentally copy & pasate this character, it can be very confusing, so we disable selecting it. 74 */ 75 user-select: none; 76} 77 78@keyframes blink { 79 0%, 80 50% { 81 border-left-color: black; 82 } 83 50.01%, 84 100% { 85 border-left-color: transparent; 86 } 87} 88 89.selected { 90 background-color: rgba(0, 120, 215, 0.3); 91} 92 93.fraction { 94 display: inline-block; 95 text-align: center; 96 font-size: 0.85em; 97 vertical-align: 0.33em; /* 4. Move the fraction up slightly relative to the surrounding text. This adjusts the fraction so that the fraction bar is inline with the center of the surrounding text rather than the surrounding text's baseline. */ 98} 99 100.fraction .fraction .fraction { 101 font-size: 1em; /* Stop shrinking font size after third level */ 102} 103 104.numerator { 105 display: block; 106 overflow: hidden; /* 3. When an element's overflow property is not "visible", its baseline becomes the bottom edge of the element rather than the baseline of the text within it. This is good because it aligns the center of the fraction (the bottom of the numerator) with the baseline of the surrounding text. */ 107 108 /* Avoid clipping cursor on right edge of numerator due to overflow: hidden */ 109 padding: 0 1px; 110 margin: 0 -1px; 111} 112 113.denominator { 114 display: block; 115 float: left; /* 1. This causes the denominator to be taken out of the text flow, making the baseline of the numerator align with the overall baseline. (This is then adjusted to center the fraction bar.) */ 116 width: 100%; /* 2. Floating this element causes it to stop being full width, but we want it to be full width just like the numerator is so that centering the text works. */ 117} 118 119.denominator::before { 120 user-select: none; 121 content: ""; 122 display: block; 123 height: 0.06em; 124 background: currentColor; 125 width: 100%; 126 border-radius: 0.03em; 127} 128 129.numerator:empty::after, 130.denominator:empty::after { 131 display: inline-block; 132 content: ""; 133 width: 0.6em; 134 height: 0.6em; 135 background: #ddd; 136} 137 138.subsup { 139 display: inline-block; 140 font-size: 0.6em; 141 vertical-align: 0.33em; 142} 143 144.subscript { 145 display: block; 146 float: left; 147 width: 100%; 148} 149 150.superscript { 151 display: block; 152 overflow: hidden; 153 154 padding: 0 1px; 155 margin: 0 -1px; 156} 157 158.radical { 159 display: inline-flex; 160 align-items: flex-start; 161 position: relative; 162} 163 164.radical-index { 165 font-size: 0.75em; 166} 167 168.radicand { 169 position: relative; 170 display: inline-block; 171 border-top: 0.1em solid currentColor; 172 border-left: 0.1em solid currentColor; 173} 174 175.radicand::before { 176 content: ""; 177 position: absolute; 178 width: 0.35em; 179 height: 0.35em; 180 bottom: 0em; 181 left: -0.1em; 182 transform-origin: center center; 183 transform: translateX(-50%) translateY(-20%) rotate(-45deg); 184 border-left: 0.1em solid currentColor; 185 box-sizing: border-box; 186 font-size: 1em; 187} 188 189.matrix { 190 display: inline-table; 191 position: relative; 192 font-size: 0.9em; 193 text-align: center; 194 vertical-align: middle; 195} 196 197.matrix-square { 198 padding-left: 0.2em; 199 padding-right: 0.2em; 200} 201 202.matrix-square::before { 203 content: ""; 204 position: absolute; 205 left: 0; 206 top: 0; 207 width: 0.25em; 208 height: 100%; 209 border-top: 0.1em solid currentColor; 210 border-left: 0.1em solid currentColor; 211 border-bottom: 0.1em solid currentColor; 212} 213 214.matrix-square::after { 215 content: " "; 216 position: absolute; 217 right: 0; 218 top: 0; 219 width: 0.25em; 220 height: 100%; 221 border-top: 0.1em solid currentColor; 222 border-right: 0.1em solid currentColor; 223 border-bottom: 0.1em solid currentColor; 224}