line-spacing.html (6931B)
1 <!DOCTYPE html> 2 <link rel="help" href="https://drafts.csswg.org/css-ruby/#line-height"> 3 <link rel="stylesheet" href="/fonts/ahem.css"> 4 <style> 5 body { 6 font: 16px/1 Ahem; 7 } 8 9 body > div { 10 border: 1px solid lime; 11 } 12 13 .over_emp { 14 -webkit-text-emphasis: 'x'; 15 -webkit-text-emphasis-position: over left; 16 text-emphasis: 'x'; 17 text-emphasis-position: over left; 18 } 19 20 .under_emp { 21 -webkit-text-emphasis: 'x'; 22 -webkit-text-emphasis-position: under left; 23 text-emphasis: 'x'; 24 text-emphasis-position: under left; 25 } 26 27 #log { 28 font-family: sans-serif; 29 } 30 </style> 31 <body> 32 <script src="/resources/testharness.js"></script> 33 <script src="/resources/testharnessreport.js"></script> 34 <script> 35 setup({ explicit_done: true }); 36 37 function renderRuby(source) { 38 document.body.insertAdjacentHTML('afterbegin', source); 39 const firstChild = document.body.firstChild; 40 const container = firstChild.tagName == 'RUBY' ? null : firstChild; 41 const ruby = firstChild.tagName == 'RUBY' ? firstChild : firstChild.querySelector('ruby'); 42 return {container: container, ruby: ruby, rt: ruby.querySelector('rt')} 43 } 44 45 function renderRubyAndGetBoxes(source) { 46 const {container, ruby, rt} = renderRuby(source); 47 return { 48 container: container ? container.getBoundingClientRect() : null, 49 ruby: ruby ? ruby.getBoundingClientRect() : null, 50 rt: rt ? rt.getBoundingClientRect() : null 51 }; 52 } 53 54 document.fonts.load("16px Ahem").then(() => { 55 test(() => { 56 const {container, ruby, rt} = renderRubyAndGetBoxes( 57 '<div><ruby>base<rt>annotation</rt></ruby></div>'); 58 assert_true(container.top <= rt.top); 59 assert_true(rt.top < ruby.top); 60 }, 'Over ruby doesn\'t overflow the block'); 61 62 test(() => { 63 const {container, ruby, rt} = renderRubyAndGetBoxes( 64 '<div>before <span style="vertical-align:32px;">' + 65 '<ruby>base<rt>annotation</rt></ruby>' + 66 '</span> after</div>'); 67 assert_true(container.top <= rt.top); 68 assert_true(rt.top < ruby.top); 69 }, 'Over ruby + vertical-align doesn\'t overflow the block'); 70 71 test(() => { 72 const {container, ruby, rt} = renderRubyAndGetBoxes( 73 '<div><ruby style="ruby-position:under">base<rt>annotation</rt></ruby></div>'); 74 assert_true(container.bottom >= rt.bottom); 75 assert_true(rt.bottom > ruby.bottom); 76 }, 'Under ruby doesn\'t overflow the block'); 77 78 test(() => { 79 const {container, ruby, rt} = renderRubyAndGetBoxes( 80 '<div>before <ruby style="vertical-align:-32px; ruby-position:under">' + 81 'base<rt>annotation</rt></ruby> after</div>'); 82 assert_true(container.bottom >= rt.bottom); 83 assert_true(rt.bottom > ruby.bottom); 84 }, 'Under ruby + vertical-align doesn\'t overflow the block'); 85 86 test(() => { 87 const {container, ruby, rt} = renderRuby( 88 '<div><ruby style="ruby-position:under">base<rt>annotation</rt></ruby>' + 89 '<div>n</div></div>'); 90 const nextBlockBox = container.querySelector('div').getBoundingClientRect(); 91 const rtBox = rt.getBoundingClientRect(); 92 assert_greater_than_equal(nextBlockBox.top, rtBox.bottom); 93 }, 'Under ruby doesn\'t overwrap with the next block'); 94 95 test(() => { 96 const {container, ruby, rt} = renderRuby( 97 '<div><span>before</span><br><ruby>base<rt style="font-size:16px"' + 98 '>annotation</rt></ruby></div>'); 99 const firstLine = container.querySelector('span').getBoundingClientRect(); 100 assert_true(ruby.getBoundingClientRect().top - firstLine.bottom > 1); 101 }, 'Expand inter-lines spacing'); 102 103 test(() => { 104 const {container, ruby, rt} = renderRuby( 105 '<div style="line-height:1.5;">' + 106 '<span>First line</span><br>' + 107 '<span>Second line</span><br>' + 108 '<ruby>base<rt style="font-size:50%">' + 109 'annotation</rt></ruby></div>'); 110 const firstLine = container.querySelector('span').getBoundingClientRect(); 111 const secondLine = container.querySelectorAll('span')[1].getBoundingClientRect(); 112 const rubyLine = ruby.getBoundingClientRect(); 113 assert_approx_equals(secondLine.top - firstLine.top, rubyLine.top - secondLine.top, 1); 114 }, 'Consume half-leading of the previous line'); 115 116 test(() => { 117 const {container, ruby, rt} = renderRuby( 118 '<div style="line-height:1.5;">' + 119 '<span>First line</span><br>' + 120 '<span class="under_emp">Second line</span><br>' + 121 '<ruby>base<rt style="font-size:50%">' + 122 'annotation</rt></ruby></div>'); 123 const firstLine = container.querySelector('span').getBoundingClientRect(); 124 const secondLine = container.querySelectorAll('span')[1].getBoundingClientRect(); 125 const rubyLine = ruby.getBoundingClientRect(); 126 const RUBY_EMPHASIS_SIZE = 8; 127 assert_greater_than_equal(rubyLine.top - secondLine.top, 128 secondLine.top - firstLine.top + RUBY_EMPHASIS_SIZE); 129 }, 'Don\'t Consume half-leading of the previous line with text-emphasis'); 130 131 test(() => { 132 const {container, ruby, rt} = renderRuby( 133 '<div style="line-height:1.5;">' + 134 '<span>First line</span><br>' + 135 '<ruby style="ruby-position:under">base<rt style="font-size:50%">' + 136 'annotation</rt></ruby><br>' + 137 '<span>Third line</span></div>'); 138 const firstLine = container.querySelector('span').getBoundingClientRect(); 139 const rubyLine = ruby.getBoundingClientRect(); 140 const thirdLine = container.querySelectorAll('span')[1].getBoundingClientRect(); 141 assert_approx_equals(rubyLine.top - firstLine.top, thirdLine.top - rubyLine.top, 1); 142 }, 'Consume half-leading of the next line'); 143 144 test(() => { 145 const {container, ruby, rt} = renderRuby( 146 '<div style="line-height:1.5;">' + 147 '<span>First line</span><br>' + 148 '<ruby style="ruby-position:under">base<rt style="font-size:50%">' + 149 'annotation</rt></ruby><br>' + 150 '<span class="over_emp">Third line</span>' + 151 '</div>'); 152 const firstLine = container.querySelector('span').getBoundingClientRect(); 153 const rubyLine = ruby.getBoundingClientRect(); 154 const thirdLine = container.querySelectorAll('span')[1].getBoundingClientRect(); 155 const RUBY_EMPHASIS_SIZE = 8; 156 assert_greater_than_equal(thirdLine.top - rubyLine.top, 157 rubyLine.top - firstLine.top + RUBY_EMPHASIS_SIZE); 158 }, 'Don\'t Consume half-leading of the next line with text-emphasis'); 159 160 // crbug.com/336592423 161 test(() => { 162 const {container, ruby, rt} = renderRuby( 163 '<div style="line-height:1;">' + 164 '<span style="display:inline-block; width:1em; height:4em; vertical-align:top"></span><br>' + 165 '<ruby>base<rt>annotation</rt></ruby></div>'); 166 const firstLine = container.querySelector('span').getBoundingClientRect(); 167 const rtBox = rt.getBoundingClientRect(); 168 assert_greater_than_equal(rtBox.top, firstLine.bottom); 169 }, 'An atomic-inline should not overlap with an annotation in the next line'); 170 171 done(); 172 }); 173 </script> 174 </body>