1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

How can I contain rotated text within td tag?

Discussion in 'CSS' started by SoftLink, Jul 14, 2022.

  1. #1
    I have a table full of td tags that have labels in them.
    When the text is too long I rotate it 310 deg.
    If I do NOT rotate the text the td tag contains it no matter how long it is.
    If I rotate the text I get an overflow problem.

    So again, how can I keep rotated text contained within the td without it overflowing?
    TDRotatedTxt1.png
     
    SoftLink, Jul 14, 2022 IP
  2. sarahk

    sarahk iTamer Staff

    Messages:
    28,500
    Likes Received:
    4,460
    Best Answers:
    123
    Trophy Points:
    665
    #2
    I found an ingenious solution in an old StackOverflow post using writing-mode:vertical
    th
    {
      vertical-align: bottom;
      text-align: center;
    }
    
    tfoot th span
    {
      -ms-writing-mode: tb-rl;
      -webkit-writing-mode: vertical-rl;
      writing-mode: vertical-rl;
      transform: rotate(200deg);
      white-space: nowrap;
    }
    Code (CSS):
    I've dummied up an example at https://codepen.io/itamer/pen/NWYbyEr

    upload_2022-7-15_11-6-7.png
     
    sarahk, Jul 14, 2022 IP
    qwikad.com likes this.
  3. SoftLink

    SoftLink Active Member

    Messages:
    103
    Likes Received:
    5
    Best Answers:
    0
    Trophy Points:
    60
    #3
    sarahk: Thanks for responding.
    I see it works for you but it doesn't work for me.
    In your codepen I tried changing it so the span tags have classes that are your rotate class:
    
    .lTextSpan
    {
      -ms-writing-mode: tb-rl;
      -webkit-writing-mode: vertical-rl;
      writing-mode: vertical-rl;
      transform: rotate(200deg);
      white-space: nowrap;
    }
    
    Code (markup):
    This worked fine. The text was still rotated and contained within the td tags.

    My css is: "writing-mode: vertical-rl; transform: rotate(310deg); white-space: nowrap;"
    That css is applied to a td tag though, not a span. I don't care if older browsers can't read it.

    I'll try wrapping the text in a span with that css and see if that fixes it.
    Thanks again.

    UPDATE: I've tried span, div and again just the td. Nothing works. It rotates just fine but creates an overflow.
     
    Last edited: Jul 15, 2022
    SoftLink, Jul 15, 2022 IP
  4. SoftLink

    SoftLink Active Member

    Messages:
    103
    Likes Received:
    5
    Best Answers:
    0
    Trophy Points:
    60
    #4
    I've tried everything I can think of: width:auto; height:auto . . .
    No matter what I do the browser will not keep the rotated text inside the td tag.
    It overflows.
    I tested it in Chrome and FireFox. Both of them do it.

    I tried uploading a new pic of the report. Digital Point won't let me.
     
    SoftLink, Jul 15, 2022 IP
  5. qwikad.com

    qwikad.com Illustrious Member Affiliate Manager

    Messages:
    7,151
    Likes Received:
    1,656
    Best Answers:
    29
    Trophy Points:
    475
    #5
    I removed tfoot and span from the css and put in .lTextSpan instead, and then changed <span> to <span class="lTextSpan">

    Seems to be working in the fiddle:

    https://jsfiddle.net/5trwz61o/
     
    qwikad.com, Jul 15, 2022 IP
    sarahk likes this.
  6. SoftLink

    SoftLink Active Member

    Messages:
    103
    Likes Received:
    5
    Best Answers:
    0
    Trophy Points:
    60
    #6
    I can't figure it out.
    This is a report. The html displayed is generated using Javascript .innerHTML.
    I've tried creating all html elements using document.createElement.
    It didn't help.

    Here is a CodePen of the html that was generated.
    I added the styles in my stylesheet that are used in the html.
    The angle is 300 instead of 200 to dramatically show how the text is overflowing into the other td tags.

    https://codepen.io/SLSCoder/pen/abYJOoZ
     
    SoftLink, Jul 18, 2022 IP
  7. qwikad.com

    qwikad.com Illustrious Member Affiliate Manager

    Messages:
    7,151
    Likes Received:
    1,656
    Best Answers:
    29
    Trophy Points:
    475
    #7
    The whole thing is flawed and should be re-written since you're mixing the css and the style. If the text is going to be of the same length, you can simply add padding:50px; after white-space: nowrap; it will eliminate the appearance of overflow, provided the text is going to be short. OR eliminate white-space: nowrap; altogether and add padding:50px; Then the text will break, like in this example. It won't matter how long the text is:

    https://jsfiddle.net/dzpy3ofx/
     
    Last edited: Jul 18, 2022
    qwikad.com, Jul 18, 2022 IP
  8. salvados guira

    salvados guira Peon

    Messages:
    16
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    1
    #8
    ohh youre method its very interesseing send me new message

    no i can
     
    Last edited by a moderator: Jul 19, 2022
    salvados guira, Jul 19, 2022 IP
  9. SoftLink

    SoftLink Active Member

    Messages:
    103
    Likes Received:
    5
    Best Answers:
    0
    Trophy Points:
    60
    #9
    quikad: I appreciate your response but you don't seem to understand.
    This is not static html code.

    This code is generated directly from a live database on the server. It is generated using Javascript.
    The length of a given label can be anywhere from 1 character to 150. Again, it is generated on the server from a database.
    The styles are applied to specific cells under specific circumstances, like if the text is too long.
    There is nothing wrong with adding and removing styles (or classes) to an html element that has a class.

    Trying to add heavy padding is not a solution. The labels are all different lengths.
    I don't want to try to simulate no overflow. I want the browser to keep the text within the borders of the td tags.
    I looked at your fiddle. I didn't touch the code. This is what I saw.
    TDRotatedTxt2.png .

    In the CodePen I posted above, exactly how can I make the text in the labels on the X axis stop overflowing?
     
    SoftLink, Jul 20, 2022 IP
  10. qwikad.com

    qwikad.com Illustrious Member Affiliate Manager

    Messages:
    7,151
    Likes Received:
    1,656
    Best Answers:
    29
    Trophy Points:
    475
    #10
    This is what I meant. Is it not what you want (I took your example this time)?

    https://jsfiddle.net/bj2ps0c6/
     
    qwikad.com, Jul 20, 2022 IP
  11. SoftLink

    SoftLink Active Member

    Messages:
    103
    Likes Received:
    5
    Best Answers:
    0
    Trophy Points:
    60
    #11
    Thanks, I appreciate your effort but no, it's not what I want.
    I honestly don't think it is acceptable for professional coding. I don't have any clients who would accept it.
    First, look at the huge padding to the left of each td.
    Also, I'd like to see it with different length labels (like 100 characters different). I think it would overflow.

    I can't understand why I can't use CSS to just make the text expand the td (or internal span or div) without having to try to simulate it.
     
    SoftLink, Jul 20, 2022 IP
  12. qwikad.com

    qwikad.com Illustrious Member Affiliate Manager

    Messages:
    7,151
    Likes Received:
    1,656
    Best Answers:
    29
    Trophy Points:
    475
    #12
    I guess maybe @deathshadow can rewrite the whole thing for you and make it work like it should. I don't know how to get rid of that overflow for good. If it was me I'd just add a padding (or margin) and forget about it.

    By the way, that padding doesn't have to be the same all around. You should know these things especially if you're working for clients. You can change it anyway you want. For instance: padding: 10px 40px 10px 40px (or something like that) which will make it less at the top and the bottom and more on the sides.

    Hope someone provides a solution for you.
     
    qwikad.com, Jul 20, 2022 IP
    sarahk and SoftLink like this.
  13. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #13
    That's because what you are trying to do is generally considered bad UX and/or UI design. Rotated text causes accessibility issues on screen, and isn't all that great on print either.

    Even just being able to rotate text is a new capability of CSS within the past decade, and its use is increasingly frowned upon when used for anything more than flashy non-content text and/or brief animations.

    Rotate transformations aren't just "new" (relatively speaking), they're more meant for "special effects" and animations than layout, which is why rotated elements behave as if they are position:relative. The rotation doesn't change how the element reports its size or position in "flow" because it would make the layout move around as you rotate things in real time.
    You don't want it to overflow, don't rotate it. If your layout concept isn't compatible with that idea, than your very concept is broken and needs to be pitched.

    And yes, that sucks. But that's what separates design from being "just art". ACTUAL design has to meet things like accessibility minimums, and rotating text violates that just as much as bad colour contrasts or absurdly undersized fonts do. And it's why the "wah wah it's my design" egotists need a quadruple helping of sierra tango foxtrot uniform."

    Much of your problems come from "non-viable" layout concepts that violate accessibility norms. This is only exacerbated by gibberish markup and illogical document order, where you have TD + style doing TH's job, a lack of SCOPE, presentation crapped all over the markup with gibberish classes for nothing, gibberish ID's for nothing, and endless repetitive style="" for Christmas only knows what. Thus your having easily four times the markup needed to create a table like this.

    A table where you have your TR slopped in any old ways without THEAD, TBODY, or TFOOT, where you seem to be putting the column descriptions that belong structurally in the THEAD at the bottom, and a host of other problems with non-semantic gibberish markup. Just like the DIV for nothing around the outside, paragraph that is clearly not tabular data inside the table as the last row, DIV doing the job of either a numbered heading before the table or a CAPTION inside it, etc. etm.

    Basically you've got the old Groucho Marx comedy skit of "doctor, doctor! It hurts when I do this!"

    Well don't do that.

    What you are trying to do and how you're trying to go about it are both things I would not allow any client of mine to deploy. Well... unless it was for print, and even then rotation is a bad idea unless you can 100% predict the size of all content ahead of time, which seems to be your real problem here. The rotation isn't in flow, is unlikely to ever be so, and as such rotations are just flat out incompatible with dynamic content. Because again that's not really what being able to rotate text is even "for" with HTML and CSS.
     
    deathshadow, Jul 20, 2022 IP
    sarahk likes this.
  14. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #14
    Just a quick stab at fixing your markup to what it should be based on the content -- irregardless of what you want for layout:

    
    <table class="stats">
    
    	<caption>What about these techniques? - fit your style - Finger Picking</caption>
    
    	<thead>
    		<tr>
    			<th scope="row">When</th>
    			<th scope="col"><span>08/03/1960 to < 08/03/1961</span></th>
    			<th scope="col"><span>08/03/1971 to < 08/03/1972</span></th>
    			<th scope="col"><span>08/03/1979 to < 08/03/1980</span></th>
    			<th scope="col"><span>08/03/1983 to < 08/03/1984</span></th>
    			<th scope="col"><span>08/03/1989 to < 08/03/1990</span></th>
    			<th scope="col"><span>08/03/1991 to < 08/03/1992</span></th>
    			<th scope="col"><span>08/03/1995 to < 08/03/1996</span></th>
    			<th scope="col"><span>08/03/2001 to < 08/03/2002</span></th>
    			<th scope="col"><span>08/03/2003 to < 08/03/2004</span></th>
    			<th scope="col"><span>08/03/2006 to < 08/03/2007</span></th>
    			<th scope="col"><span>08/03/2009 to < 08/03/2010</span></th>
    			<th scope="col"><span>08/03/2014 to < 08/03/2015</span></th>
    			<th scope="col"><span>08/03/2015 to < 08/03/2016</span></th>
    			<th scope="col"><span>08/03/2021 to < 08/03/2022</span></th>
    			<td></td>
    		</tr>
    	</thead>
    
    	<tbody>
    		<tr class="breakAfter">
    			<th scope="row">no</th>
    			<td>0</td>
    			<td>0</td>
    			<td>0</td>
    			<td>0</td>
    			<td class="value1">1</td>
    			<td>0</td>
    			<td class="value1">1</td>
    			<td>0</td>
    			<td>0</td>
    			<td>0</td>
    			<td>0</td>
    			<td>0</td>
    			<td class="value1">1</td>
    			<td>0</td>
    			<td>3</td>
    		</tr><tr>
    			<th scope="row">sometimes</td>
    			<td class="value1">1</td>
    			<td class="value1">1</td>
    			<td class="value1">1</td>
    			<td class="value1">1</td>
    			<td class="value1">1</td>
    			<td class="value1">1</td>
    			<td>0</td>
    			<td>0</td>
    			<td class="value1">1</td>
    			<td class="value1">1</td>
    			<td class="value1">1</td>
    			<td class="value1">1</td>
    			<td>0</td>
    			<td class="value1">1</td>
    			<td>11</td>
    		</tr><tr>
    			<th scope="row">yes</td>
    			<td class="value1">1</td>
    			<td>0</td>
    			<td>0</td>
    			<td>0</td>
    			<td>0</td>
    			<td>0</td>
    			<td>0</td>
    			<td class="value1">1</td>
    			<td>0</td>
    			<td>0</td>
    			<td>0</td>
    			<td>0</td>
    			<td>0</td>
    			<td class="value2">2</td>
    			<td>4</td>
    		</tr>
    	</tbody>
    
    	<tfoot>
    		<tr>
    			<th scope="row">Grand Totals</th>
    			<td>2</td>
    			<td>1</td>
    			<td>1</td>
    			<td>1</td>
    			<td>2</td>
    			<td>1</td>
    			<td>1</td>
    			<td>1</td>
    			<td>1</td>
    			<td>1</td>
    			<td>1</td>
    			<td>1</td>
    			<td>1</td>
    			<td>3</td>
    			<td>18</td>
    		</tr>
    	</tfoot>
    
    </table>
    
    <p>
    	When did you start playing music?  Annual Intervals
    </p>
    
    Code (markup):
    Though good luck making it look how you want with those rotations since again, rotation isn't accessible or something CSS is even meant to do when it comes to static flow elements. Even so, semantic markup FIRST before you even THINK about applying style or thinking about what things look like. Say what things are in the order HTML says to.

    That's why the know-nothing turds dicking around drawing pretty pictures in Photoshop or Figma are not actually designers, no matter how much they claim otherwise.
     
    deathshadow, Jul 20, 2022 IP
  15. SoftLink

    SoftLink Active Member

    Messages:
    103
    Likes Received:
    5
    Best Answers:
    0
    Trophy Points:
    60
    #15
    Thanks for the critique deathshadow.
    Ya know, if so many of these techniques are 'wrong' then they shouldn't be facilitated.
    I notice lately that often when I ask 'how can I do this' I get the response 'you should not do that' instead of an answer.
    Did you see the table? I can wrap the labels and it looks like that's what I'm going to do but even wrapped the columns are all really wide for numeric values.

    Why are thead, tbody, tfoot, th important? They've never done anything for me. What am I missing?

    You don't like my labels huh? hehe. You're not my target:) My target knows what those labels mean and they're nice and concise.

    So you're not going to answer me? or is the answer "no, you can't do it"?

    Thanks again for responding.
     
    SoftLink, Jul 21, 2022 IP
  16. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #16
    I actually agree with you on that, though in this case I'd say the real problem is that it's poorly documented. There should be some sort of trigger to let us have the rotated size "in flow" when we want it to be, and there simply isn't. There's nothing to make a rotated element report its size after rotation to the layout, it flat out pretends you did nothing to it. Whilst that is handy for people doing animations, it sucks when working with layout. It's the same problem floats often bring to the table. It's also why floats are used with an eye-dropper these days instead of the paint roller we used to before flex and grid came along.

    The reason for that is related to something else you said:
    HTML is a markup language for saying what things ARE and not what they look like! This is important because if you are using HTML you should be developing for all users. NOT JUST the perfectly sighted on screens.

    Have you ever used a screen reader? Aka software that reads the page aloud? A braille reader? TTY? Are you a search engine? Have you used alternative navigation like keyboard, puffer sticks, mouth sticks and the like? Are you aware of the behavior of THEAD and TFOOT when printed and how they are applied (in theory, some browsers suck at this) to every page, not just the first and last respectively?

    Much less the advantages they bring like not having to piss all over the markup with endless pointless "classes for nothing?"

    There's a reason that most of the time you see a stylesheet <link> that isn't setting media="something" such as print or screen, or using the <style> tag, you're looking at developer ignorance, incompetence, and ineptitude. In the case of the latter, outdated web-rot practices that never should have been introduced to HTML in the first place, and should have been stricken in HTML 5. Just as most of the time you see style="" you're looking at trash code in all but the rarest of corner cases... such as tag clouds, HTML generated bar graphs and progress bars, or passing values via "custom properties" -- aka "CSS variables" -- so the stylesheet can optionally use them.

    CSS is separate from HTML for a reason. If people would stop fighting that reason they would generally have an easier time of things. See the "work harder not smarter" idiocy that are frameworks, where through propaganda and preying on ignorance they sucker people into thinking their way is "easier" when it is nothing of the sort.

    https://medium.com/codex/stop-fight...ts-with-these-dumbass-frameworks-91732f5993c7

    What "labels" are you referring to. It's not a form. Do you mean the headings? If so yeah, unless you rotate them 90 degrees they're going to be really wide. There are not a lot of things you can do about that.

    TH means "table heading". It describes the content on a row or column. SCOPE tells the UA which direction -- row or col -- that the heading is being applied. Just as TD means "table data".

    UA meaning "user agent". A browser is a UA, but a UA isn't always a browser. That's part of what I think you're not grasping. There's more out there accessing websites than screen media browsers. If you fail to realize this, and do something like you're doing for business, you're opening the door to getting raked over the coals in both civil lawsuits, and criminal prosecution under laws like the US' ADA, the UK's EQA, Canada's ACA, and dozens of other national and international laws.

    This is why when people say idiotic stuff like "No website would be sued over their layout and design" they're talking out their arses. Just as Beyonce and Dominos.

    Anyhow that's where a lot of your posts seem to lose and/or confuse myself and others, is you don't seem to be using the correct terminology for things. That can be a great barrier to getting meaningful help.

    Thus when you said:

    I don't quite understand or follow what you're referring to as you don't have any "labels".

    I've explained why you can't do it... with just HTML or CSS. It's not how either of them work since again, you rotate that change in appearance does not effect flow -- aka the size reported for layout.

    It's also why some of the answers provided appear to work for some users but not others. The moment you change the content it's busted because sure you can adjust it to the size of one item, but the moment the content is different it's broken again. Those solutions are a lot like the old way of making "sticky" headers and footers using absolute positioning. Fragile, unreliable, and more often than not just plain broken. They're the web development equivalent of playing "whack-a-mole" where every time you fix it in one spot, you break it somewhere else.

    BUT -- and I've been thinking on this for a couple days -- there may be a way to do this reliably if you insist. It's not a good practice, it has a few possible problems, but it should work. If we can't do it with just HTML or CSS, what's left?

    JavaScript.

    If we wait for the page to finish loading, we could pull the size of those inner span, apply the rotation, calculate the new size after rotation -- that part sucks, say hello to trigonometry, specifically sine and cosine -- switch them to position:absolute removing them from flow completely, and then stuff an empty element inside the TD that are the correct size.

    The problem is they would appear on screen as if they weren't rotated at their full size for a moment, and then change their orientation reflowing the layout. This "Flash Of Unstyled Content" -- FOUC -- might not be pretty, though if the elements being rotated end up "below the fold" you might be ok.

    I'm currently working on a lengthy client proposal -- replying whilst taking a break -- but when that's complete I'll squeeze in time to make an example of doing this whilst waiting for them to get back to me.

    As a rule of thumb if you have to use JavaScript for layout you're doing something wrong, but EVERY RULE should have exceptions. Like if you use <style> you're probably doing something horrifically wrong -- but the exception? Using that tag from the JavaScript to apply styling that only applies to scripted elements. If you use style="" you're probably doing something wrong, unless you're setting font-size for a tag cloud, or width on a bar graph element, or passing optional values to CSS. If you have <script> text instead of external scripting you're probably screwing up, unless you're setting values for the external script to use that are unique to the current page or identifying yourself to off-domain scripts. Though these days META tags or data- attributes are better suited to that task.

    But that brings us full circle to part of your problem. Something you said at the start, how they shouldn't provide them in the first place. That's not really the issue, the problem is they have given us tools for very specific uses, but people keep trying to use them for things they were never intended. And why? Because they don't read the specifications or take the time to understand anything. They certainly don't seem to want to try and embrace the rules meant to keep you out of trouble and make your content available and useful to as many people as possible.

    I don't blame people for that ignorance. Again, when I say ignorant I don't mean it as an insult. It just means you don't know any better. You can fix ignorant. We're ALL ignorant about something! The W3C "specifications" are some of the most painfully and badly written legalese out there and worse, they're not even written for us lowly "content creators" -- the term they use for people who make websites. They're written for people who make browsers.

    And as I have done many times in the past, lemme just repeat that. The HTML and CSS specifications -- the documents defining the languages used to build websites -- are not written for people who build websites. Then the W3C wonders why they're derided, looked down upon, and treated like uninvited cousins on Christmas -- forced to sit at the kiddy table -- by other standards bodies like the ECMA.

    I'll be a couple hours before I get to it, but I'll try and see if I can solve the issue with JS since to my knowledge -- and I've actually read and comprehended the specifications -- you can't do this with just HTML and CSS.
     
    Last edited: Jul 21, 2022
    deathshadow, Jul 21, 2022 IP
  17. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #17
    Ok, I got the rewrite done since:

    1) sitting here with insomnia

    2) Waiting with thumb up backside for client to get back to me.

    It's a little embarrassing how long it took for me to get the math right on this. To be fair, it's been 15+ years since I've written rotational geometric / trig math since these days we just let the GPU handle it... it's scary how much I forgot.

    https://codepen.io/jason-knight/pen/rNdweMX?editors=1111

    On the HTML side I ditched the excess "scripting / style only" span and generate them instead from the scripting. I use data attributes to set how much rotation should be applied for the scripting to pick up. The values of width and height of the generated containers is applied via CSS variables so the rotation does not get applied when the stylesheet isn't present, and the scripting only style is loaded via the script, that way it's not screwing with us on non-visual media.

    I did switch the markup to us a heading instead of CAPTION just because of how display:grid helps solve a lot of the layout arrangement issues since that final paragraph isn't tabular data.

    
    <h1>
    	Scripted Flow Rotation Demo
    </h1>
    
    <section class="stats">
    
    	<h2 data-script-rotate="90">
    		What about these techniques? - fit your style - Finger Picking
    	</h2>
    
    	<table>
    
    		<tbody>
    			<tr class="breakAfter">
    				<th scope="row">no</th>
    				<td>0</td>
    				<td>0</td>
    				<td>0</td>
    				<td>0</td>
    				<td class="value1">1</td>
    				<td>0</td>
    				<td class="value1">1</td>
    				<td>0</td>
    				<td>0</td>
    				<td>0</td>
    				<td>0</td>
    				<td>0</td>
    				<td class="value1">1</td>
    				<td>0</td>
    				<td>3</td>
    			</tr><tr>
    				<th scope="row">sometimes</td>
    				<td class="value1">1</td>
    				<td class="value1">1</td>
    				<td class="value1">1</td>
    				<td class="value1">1</td>
    				<td class="value1">1</td>
    				<td class="value1">1</td>
    				<td>0</td>
    				<td>0</td>
    				<td class="value1">1</td>
    				<td class="value1">1</td>
    				<td class="value1">1</td>
    				<td class="value1">1</td>
    				<td>0</td>
    				<td class="value1">1</td>
    				<td>11</td>
    			</tr><tr>
    				<th scope="row">yes</td>
    				<td class="value1">1</td>
    				<td>0</td>
    				<td>0</td>
    				<td>0</td>
    				<td>0</td>
    				<td>0</td>
    				<td>0</td>
    				<td class="value1">1</td>
    				<td>0</td>
    				<td>0</td>
    				<td>0</td>
    				<td>0</td>
    				<td>0</td>
    				<td class="value2">2</td>
    				<td>4</td>
    			</tr>
    		</tbody>
    
    		<tfoot>
    			<tr>
    				<th scope="row">Grand Totals</th>
    				<td>2</td>
    				<td>1</td>
    				<td>1</td>
    				<td>1</td>
    				<td>2</td>
    				<td>1</td>
    				<td>1</td>
    				<td>1</td>
    				<td>1</td>
    				<td>1</td>
    				<td>1</td>
    				<td>1</td>
    				<td>1</td>
    				<td>3</td>
    				<td>18</td>
    			</tr><tr>
    				<th scope="row">When</th>
    				<th scope="col" data-script-rotate="-65">
              08/03/1960 to &lt; 08/03/196<br>
              Longer Text to test<br>
              That our rotation<br>
              containment works
            </th>
    				<th scope="col" data-script-rotate="-65">08/03/1971 to &lt; 08/03/1972</th>
    				<th scope="col" data-script-rotate="-65">08/03/1979 to &lt; 08/03/1980</th>
    				<th scope="col" data-script-rotate="-65">08/03/1983 to &lt; 08/03/1984</th>
    				<th scope="col" data-script-rotate="-65">08/03/1989 to &lt; 08/03/1990</th>
    				<th scope="col" data-script-rotate="-65">08/03/1991 to &lt; 08/03/1992</th>
    				<th scope="col" data-script-rotate="-65">08/03/1995 to &lt; 08/03/1996</th>
    				<th scope="col" data-script-rotate="-65">08/03/2001 to &lt; 08/03/2002</th>
    				<th scope="col" data-script-rotate="-65">08/03/2003 to &lt; 08/03/2004</th>
    				<th scope="col" data-script-rotate="-65">08/03/2006 to &lt; 08/03/2007</th>
    				<th scope="col" data-script-rotate="-65">08/03/2009 to &lt; 08/03/2010</th>
    				<th scope="col" data-script-rotate="-65">08/03/2014 to &lt; 08/03/2015</th>
    				<th scope="col" data-script-rotate="-65">08/03/2015 to &lt; 08/03/2016</th>
    				<th scope="col" data-script-rotate="-65">08/03/2021 to &lt; 08/03/2022</th>
    				<th scope="col" data-script-rotate="-65">All Time Totals</th>
    			</tr>
    		</tfoot>
    
    	</table>
    	
    	<footer>
    		<p>
    			When did you start playing music?  Annual Intervals
    		</p>
    	</footer>
    	
    <!-- .stats --></section> 
    Code (markup):
    I used a FOOTER as one might have more than one paragraph there, and that is the footer for said SECTION. I also moved the rotated headings to the TFOOT since you want them at the bottom and the ORDER property would only work if we made the table not behave as a table.

    You can see how data-script-rotate sets the rotation. This violates the "don't say what things look like in the markup" rule, but as we're setting a data attribute and not actually setting the appearance, it means non-scripted and non-screen users don't get screwed by it. Again, say hello to those all-important exceptions.

    The scripting:
    
    {
    
    	const
    		targets = document.querySelectorAll("[data-script-rotate");
    
    	if (targets) {
    
    		for (let parent of targets) {
    			let div = document.createElement("div");
    			while (parent.firstChild) div.appendChild(parent.firstChild);
    			parent.appendChild(div);
    			parent.appendChild(document.createElement("span"));
    		}
    
    		document.head.appendChild(
    			Object.assign(
    				document.createElement("style"),
    				{
    					media : "screen, print",
    					textContent : `
    
    						[data-script-rotate] {
    							position:relative;
    							--scriptWidth:0;
    							--scriptHeight:0;
    							--scriptRotate:0;
    						}
    
    						[data-script-rotate] > div {
    							position:absolute;
    							top:50%;
    							left:50%;
    							white-space:nowrap;
    							transform-origin:center;
    							transform:translate(-50%, -50%) rotate(var(--scriptRotate));
    						}
    
    						[data-script-rotate] > span {
    							display:inline-block;
    							width:var(--scriptWidth);
    							height:var(--scriptHeight);
    						}
    
    					`
    				}
    			)
    		);
    
    		window.addEventListener("load", (e) => {
    
    			const
    				deg2rad = Math.PI / 180;
    
    			for (let parent of targets) {
    
    				let
    					div = parent.firstElementChild,
    					span = parent.lastElementChild,
    					bounds = div.getBoundingClientRect(),
    					radians = parent.dataset.scriptRotate * deg2rad,
    					sin = Math.sin(radians),
    					cos = Math.cos(radians),
    					x0 = bounds.width * cos,
    					y0 = bounds.width * sin,
    					x1 = bounds.height * sin,
    					y1 = bounds.height * cos,
    					x2 = x0 + x1,
    					y2 = y0 + y1;
    					
    				div.style.setProperty(
    					"--scriptRotate",
    					parent.dataset.scriptRotate + "deg"
    				);
    				
    				span.style.setProperty(
    					'--scriptHeight',
    					Math.ceil(Math.max(y0, y1, y2) - Math.min(y0, y1, y2)) + "px"
    				);
    				
    				span.style.setProperty(
    					"--scriptWidth",
    					Math.ceil(Math.max(x0, x1, x2) - Math.min(x0, x1, x2)) + "px"
    				);
    
    			}
    
    		} );
    
    	}
    
    }
    
    Code (markup):
    Is a fat bloated mess that again, I'd personally say to hell with that and rotating things, but it does fix the problem.

    I start out with an outer {} to isolate the scope of the script. Thus all variables set with let or const inside the script are invisible to other scripting. This supplants what we used to "waste" IIFE on and finally makes let/const serve a legit purpose.

    The "targets" constant is a list of all elements on the page that have data-scripted-rotate on them. As this list is used twice -- once before load and once after -- we can speed up the page load by grabbing it only once. I put an if statement on there so that if we don't have any matching targets because someone loads the script on a page where it doesn't do anything, we don't waste time trying to go any further.

    Then we have a loop that goes through all those "parent" elements and moves their contents into a newly formed DIV. I do this on the DOM as innerHTML can be slower and uses more memory / processing time. Bypassing the parser by moving objects is almost always the better choice. Thankfully whenever you appendChild a DOM element, it is removed from its original location. The DIV is then inserted into the parent, and a spare SPAN is added.

    The stylesheet that gets applied by the script kind of explains why the DIV and SPAN are needed. We relative position the 'parent" so that absolute positioning inside it is relative to it and not the page. I also set all the values to zero since some browsers choke if you try to var() a value that hasn't been assigned.

    The DIV is absolute positioned and centered with no white-space wrapping. This allows our script to extract how big the content is before we rotate it. Because it is absolute positioned it is removed from flow, the "parent" element will have no idea what size the content is.

    The dummy span will then be assigned that width and height forcing the "parent" to the correct size!

    Then when the window is done with its initial load -- meaning we'll have the size of all elements present -- we calculate the size of each of those child DIV and plug them into the span. I did this with a child span instead of the parent element so that things like padding on the parent would/could be obeyed without extra math.

    Calculating the size of a rotated element is serious "math geek" territory.

    
    	bounds = div.getBoundingClientRect(),
    	radians = parent.dataset.scriptRotate * deg2rad,
    	sin = Math.sin(radians),
    	cos = Math.cos(radians),
    	x0 = bounds.width * cos,
    	y0 = bounds.width * sin,
    	x1 = bounds.height * sin,
    	y1 = bounds.height * cos,
    	x2 = x0 + x1,
    	y2 = y0 + y1;
    
    Code (markup):
    Thankfully changing degrees -- convenient and easy -- into radians -- what sin/cos want and a pain in the ass -- is a simple matter of "degrees * PI / 180". I stored that in a constant given that we use it inside the element loop. Any time you can move math or lookups outside the loop? Do it!

    Most people would calculate all four corners based off the center, but rotation is rotation irregardless of the origin, so why not just use one corner as 0:0? Then you only need to calc three points. The X and Y of their respective 0 axis points then only need width or height calculated since the other value is zero, leaving the third point to simply be a combination of the two. From there rotation is a simple matter of multiplying by sine or cosine based on the width and height.

    If you know geometry and trigonometry this is easy stuff. If you don't it's utter gibberish.

    Plug that in and you're good to go, doing our calculation via Math.max minus Math.min to get the max height and width.

    
    div.style.setProperty(
    	"--scriptRotate",
    	parent.dataset.scriptRotate + "deg"
    );
    				
    span.style.setProperty(
    	'--scriptHeight',
    	Math.ceil(Math.max(y0, y1, y2) - Math.min(y0, y1, y2)) + "px"
    );
    		
    span.style.setProperty(
    	"--scriptWidth",
    	Math.ceil(Math.max(x0, x1, x2) - Math.min(x0, x1, x2)) + "px"
    );
    Code (markup):
    Thankfully with max and min doing the filtering, we don't have to get Math.abs involved. I set the values to the ceiling as the very long floating point numbers generated by this math can when assigned to style occasionally makes Firefox wig-out and round down instead of up, cropping off our text by a pixel or two. There was a bugzilla about this, but I can't find it now. Probably got purged same time they went full jackass and marked a bunch of major issues -- including the infamous 915 -- as "don't care, won't fix".

    And yeah, it sucks it took 2k of JavaScript to "polyfill" making this work... but it gets the job done if you insist on this approach.

    That help any? I know it's a LOT to take in. The key points of this approach is so that scripting off the text is presented normally, the page has navigable semantics / landings for non-visual users, and anything that compromises accessibility is avoided.
     
    Last edited: Jul 22, 2022
    deathshadow, Jul 22, 2022 IP
  18. SoftLink

    SoftLink Active Member

    Messages:
    103
    Likes Received:
    5
    Best Answers:
    0
    Trophy Points:
    60
    #18
    WOW! That's a lot; looks like a lot of work. Thank You!
    Your code is exquisite.

    You're saying that handicap/special case readers depend on all those 'useless' tags to be able to identify them?
    Except for accessibility (which I admittedly haven't seriously considered) I can't think of a use for tags like th, thead, footer, section, aside, article, . . .
    It's not so much that I don't know what they are, I don't know why they are. I suppose accessibility would be a reason.

    Labels lol. Nope, not label elements. They are the 'labels' of the X axis in the chart. On the server they are in a variable called $XLabels.

    "I've explained why you can't do it... with just HTML or CSS." I see, thanks.

    What is wrong with a style tag? In the most critical part of my app I dynamically create a style on the server based on what the interface needs.
    There could be 2 completely different styles on the same page.
    I add it to the header using a style tag in javascript. I suppose I could save a file on the server and make it a link but why?
    I could potentially end up with 20M of stylesheet files on the server at a time.

    WHY not use <script> tags? I've got hundreds of them.
    I write php and generally my php, javascript and html are all on the same page, for my convenience. Also, that allows the javascript to 'run server side code' WHAT?
    I just mean I can embed server side code within the javascript which I cannot do with a .js file.
    I'm going to guess that using scripts as html templates is also bad?
    <script type="text/template" id="tmplDivMKQuestionBlock">
    Code (markup):
    .
    I use a lot of those too.

    rotational geometric / trig math - way over my head man. I'm impressed.
    I thought I was something with standard deviation - lol

    I copied you codepen to a file in my code snippets. Thanks
    But I fear I've committed a cardinal sin. I've put your css into a style tag!

    "to hell with that and rotating things" Yea, I think wrap will have to suffice. That's an awful lot to just rotate text; impressive though.

    "I start out with an outer {} . . . " I wondered. That makes sense.

    If I understood correctly, you wrote the css for the rotate using Javascript so that browsers/readers that can't execuute Javascript won't see it and will still function. Yes?
    This app *requires* the use of Javascript. A browser/reader that can't read Javascript gets redirected to "you can't use this app" before the first page loads.

    I didn't know I could set css for elements having specific attributes like this:
    
    [data-script-rotate] {
         position:relative;
         --scriptWidth:0;
         --scriptHeight:0;
         --scriptRotate:0;
    }
    
    Code (markup):
    and set CSS variables like this.
    
    div.style.setProperty(
        "--scriptRotate",
        parent.dataset.scriptRotate + "deg"
    );
    
    Code (markup):
    very cool

    So, it appears that I'm going to have to do some research about all those 'useless' tags and accessibility. I sure don't want to get sued. Seriously, I don't want to make the app unusable for anyone with disabilities where at all possible.

    Thanks again for your detailed, informative response.

     
    SoftLink, Jul 22, 2022 IP
  19. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #19
    Try not to think of it as handicapped / special case. Accessibility is actually for everyone and can pay benefits in ways you never thought of. Many perfectly sighted users use browser extensions or keyboard navigation so they can do other stuff at the same time. See the guy who has website text read to him aloud on the drive to work. Or the artist busy with the mouse in one hand whilst navigating something else on the keyboard.

    From day one the very purpose of HTML was "device neutral delivery of content". We were NEVER supposed to have been saying "what things look like" with HTML and instead had all these predefined tags that lined up with professional writing norms. This is because when TBL created it the plethora of devices to be supported ranged from teletype daisy wheel printers, to 40, 80 or 132 column text-only terminals / micro's, the 21x22 text-only VIC=20 Linus Torvalds cut his teeth on, right up to the 1120x832 high res 4 scale monochrome display Tim Berners-Lee was sitting at when creating it!

    Nothing at all like today where everyone is using the exact same 24" IPS 1440p panels at the same seating distance with all of us magically having the exact same perfect eyesight. In case you missed it, that was sarcasm.

    We got away from that during the '90's browser wars as idiocy like FONT, CENTER, ALIGN, BGCOLOR and so forth got slopped into the specification, and it's why such things were stricken from HTML in 4 Strict when CSS was introduced.

    Thus why I advocate for the progressive enhancement approach to site development. You start out with your content or a reasonable facsimile of future content (aka text, the first class citizen of the web) as if even HTML and screen appearance doesn't even exist. You plug it into a flat text editor in a logical order.

    Then you mark it up semantically. Saying what things are based on writing norms that you should have learned in grade school. Or what was grade school for me in the '70's. So I figure that's what, College English Major fifth year by now? If you choose any of the markup at this stage based on what you want things to look like, you're doing it all wrong! You may add some ID for hash landings at this point or classes for what things ARE if the HTML is insufficient to convey that, but neither should be chosen based on appearance.

    Then and only then do you create your screen media layout in an external stylesheet, so you aren't sending screen layout to devices and users that don't give a shit. That's why saying media="screen" on your <link> or <style> is so important if your style is only relevant for screen. This is when you start adding classes you didn't think of, but even then you should not be saying what things look like in the markup in all but the rarest of corner cases. Or if you can find a way -- like custom properties / CSS variables -- to pass the information in an OPTONAL manner.

    That's one of the biggest problems with style="", it had zero mechanism for saying "this is only for screen", and now that it does putting a media query inside it is just more code bloat rubbish.

    Ask yourself this, which would you rather maintain, or have to slice up into your back-end code?

    <td class="text-center font-bold color-red-400">[code]
    
    [code]<td align="center"><b><font color="#800">
    Code (markup):
    <th scope="col">
    Code (markup):
    Not only is having scope making the table heading accessibile, it's cleaner, clearer, simpler code. More so if you have say... ten of these for one table, as you are saying all that presentation once in the stylesheet:

    
    .myTable th[scope="col"] {
      text-align:center;
      color:#800;
    }
    
    Code (markup):
    (th defaults to bold)

    Instead of over and over and over again in the markup. It also means to change the appearance you don't have to screw around with the markup you can just go to the separate stylesheet. It's a lot easier to change style when you don't have a metric shit-ton of markup -- or server side / template code -- to wade through.

    Which plays to this question of yours:

    Missed caching or pre-caching opportunity. If you have pages with dynamic content, pages that share the same styles, and so forth the HTML generally isn't cached, so anything you put into the HTML isn't either. If you put all your CSS into a monolithic stylesheet that CSS can be cached across visits to the same page, or pre-cache the appearance of other pages the user will likely visit. You don't get that if you shit all over the markup with style="" or presentational classes.

    That's why... well, I wrote an article how "put above the fold CSS in the markup" is placebo bullshit that does more harm than good.

    https://levelup.gitconnected.com/pu...load-faster-at-best-a-half-truth-4103f9150128

    Just as throwing classes at everything instead of using one or two grouping classes and leveraging selectors is incompetent nonsense. See BEM... which I wanted to like, and is well thought out in terms of organization, but sadly what it does / is for is mind-numbingly dumbass.

    https://levelup.gitconnected.com/bem-is-dumb-dont-use-mostly-borked-8fa859423ee5

    Another reason is functionality they bring to the table. THEAD and TFOOT for example have an interesting behavior in print. They are automatically put at the top and bottom of each and every page if it goes multi-page so you can know what the columns and result are.

    They also can mean less pissing in classes as well. Take the "I only need TD" attitude one often finds with such numbnuttery as HTML 3.2 or frameworks. Let's do the 4 tranny plus framework halfwit approach as an example.

    
    <table cellpadding="4" cellspacing="0" border="1">
    	<tr>
    		<td colspan="4" class="bg-darkBlue font-bold text-center text-white">Shopping Cart/td>
    	</tr><tr>
    		<td class="bg-skyblue font-bold">Item</td>
    		<td class="bg-skyblue font-bold text-center">Qty</td>
    		<td class="bg-skyblue font-bold text-right">Unit Price</td>
    		<td class="bg-skyblue font-bold text-right">Total</td>
    	</tr><tr>
    		<td class="font-bold color-darkblue">Cecilio Eb Alto Sax</td>
    		<td class="text-center color-darkblue">1</td>
    		<td class="text-right color-darkblue">399.99</td>
    		<td class="text-right color-darkred">399.99</td>
    	</tr><tr>
    		<td class="font-bold color-darkblue">Yamaha 5C Alto Sax Mouthpiece</td>
    		<td class="text-center color-darkblue">1</td>
    		<td class="text-right color-darkblue">39.99</td>
    		<td class="text-right color-darkred">39.99</td>
    	</tr><tr>
    		<td class="font-bold color-darkblue">Rovner Alto Sax Ligature</td>
    		<td class="text-center color-darkblue">1</td>
    		<td class="text-right color-darkblue">29.99</td>
    		<td class="text-right color-darkred">29.99</td>
    	</tr><tr>
    		<td class="font-bold color-darkblue">Eb Alto Sax Reeds (pack of 5)</td>
    		<td class="text-center color-darkblue">2</td>
    		<td class="text-right color-darkblue">19.99</td>
    		<td class="text-right color-darkred">39.98</td>
    	</tr><tr>
    		<td class="bg-lightgray text-right colspan="3">Shipping</td>
    		<td class="bg-lightgray color-darkred text-right">38.40</td>
    	</tr><tr>
    		<td class="bg-skyblue font-bold text-right colspan="3">Grand Total</td>
    		<td class="font-bold color-darkred text-right>548.25</td>
    	</tr>
    </table>
    
    Code (markup):
    Compared to using the correct and proper semantic markup that provides not just accessibility, but efficiency.
    
    <table class="cart">
    	<caption>Shopping Cart</caption>
    	<thead>
    		<tr>
    			<th scope="col">Item</th>
    			<th scope="col">Qty</th>
    			<th scope="col">Unit Price</th>
    			<th scope="col">Total</td>
    		</tr>
    	</thead><tbody>
    		<tr>
    			<th scope="row">Cecilio Eb Alto Sax</th>
    			<td>1</td>
    			<td>399.99</td>
    			<td>399.99/td>
    		</tr><tr>
    			<th scope="row">Yamaha 5C Alto Sax Mouthpiece</th>
    			<td>1</td>
    			<td>39.99</td>
    			<td>39.99</td>
    		</tr><tr>
    			<th scope="row">Rovner Alto Sax Ligature</th>
    			<td>1</td>
    			<td>29.99</td>
    			<td>29.99</td>
    		</tr><tr>
    			<th scope="row">Eb Alto Sax Reeds (pack of 5)</th>
    			<td>2</td>
    			<td>19.99</td>
    			<td>39.98</td>
    		</tr>
    	</tbody><tfoot>
    		<tr>
    			<th scope="row" colspan="3">Shipping</th>
    			<td>38.40</td>
    		</tr><tr>
    			<th scope="row" colspan="3">Grand Total</th>
    			<td>548.25</td>
    		</tr>
    	</tfoot>
    </table>
    
    Code (markup):
    It's half the markup. Sure it would need CSS along these lines:

    
    .cart caption {
    	border-collapse:collapse;
    	padding:0.5em;
    	font-weight:bold;
    	text-align:center;
    	background:#005;
    	border:0.0625rem solid #000;
    	color:#FFF;
    }
    
    .cart tr > * {
    	padding:0.25em;
    	text-align:right;
    }
    
    .cart tr > *:first-child {
    	text-align:left;
    }
    
    cart tr > *:nth-child(2) {
    	text-align:center;
    }
    
    .cart tbody td:last-child,
    .cart tfoot td:last-child {
    	color:#800;
    }
    
    .cart tfoot tr > * {
    	background:#DDD;
    }
    
    .cart thead th,
    .cart tfoot tr:last-child > * {
    	background:#ACE;
    }
    
    .cart tfoot tr:last-child td {
    	font-weight:bold;
    }
    Code (markup):
    But even combined it's two-thirds the code. And the difference only gets worse the more data rows you have. You want to change the alignment of all your columns you do it in the stylesheet without having to even worry about where the markup is. You want to change colours? Same.

    And that CSS if in an external sheet can be cached across page-loads or pre-cached before you even need it. I've seen websites have their bandwidth use on sites like forums and blogs have their bandwidth use cut 40% or more just from this simple change, even when their media elements (images/videos) are ten to twenty times larger than the code! If you piss it into the markup, it's not as likely to be cached and it certainly isn't re-used.

    In fact that's where many of the numbnuts out there diving for SPA are just throwing good code after bad. It goes back to what I'm always saying:

    "If people would stop writing 100k of markup to do 16k's job, 500k of CSS doing 48k or less' job, and two megabytes or more of client-side JavaScript in cases where little to no scripting should even be present? MAYBE they wouldn't have so many problems."

    And it's why I keep saying the people who ignore HTML semantics and the separation of presentation from content generally write two to ten times the code needed to do the job!

    Meaning whoever decided to call them that would have failed 4th or 5th grade English in New England in the '70's. They're headings as they describe the content of the entire row or column, not a single corresponding cell. We have tags for headings, it's called "table heading" -- TH.

    Then that app is probably garbage with an inconsistent UI. And/or doing something that has no business being done with web technologies.

    Apologies if that sounds harsh, but without seeing the app in question that's what it sounds like. Well, unless you're creating the <style> tag from the client-side scripting being an App. There is no reason for the <style> tag to ever appear in your markup under normal circumstances since if it's static enough to put into a tag, it's static enough to put into your external stylesheet.

    Because otherwise you're violating the separation of concerns, and pissing on caching models.

    Now it your app is legitimately SPA where there are no pageloads because of the whackjob "pageloads r teh evuls" rubbish, <style> is less of a worry since there's nothing to pre-cache... but I still wouldn't do it without great reason. Generally speaking if your server-side code is generating CSS, you're doing something horrifically and possibly criminally wrong.

    That's the exception I mentioned. Just remember that crapplets are inaccessible garbage since they have no scripting off graceful degradation. Unless this a legitimate application, have a non-scripted fallback available. Many things -- shopping carts / purchasing, logins, etm. -- have zero business being 100% scripting reliant if it's web-facing. That's why web apps are one of the things that continues to get the clients coming to me for help in trouble as they're accessibility shit! And why in so many cases we have to either throw the app in the trash, or develop a conventional website alternative to sit alongside it.

    Apps and websites live by different rules and exceptions. It's not a one-size fits all answer.

    The majority of the time -- again in all but the rarest cases -- if you need more than 48k of CSS per media target for a website or application, you either have a painfully and agonizingly inconsistent UI flipping the bird at UX, or you don't know enough about HTML, CSS, or actual design to be building anything using web technologies.

    Again sounds harsh, but that's the truth of it. Again, see my quote above about people using 500k of CSS to do 48k or less' job... and that's me "Mr. Scotting" the numbers with overprovisioning. In reality it's closer to 32k as the upper limit.

    Again, caching. If it's in the markup it's not cached on reload, revisits, or subpages.

    Another aspect to consider is that if you have a server-side language gluing things together, it's just more crap in the damned way and harder to maintain. Worse it's more code for the server-side code to waste time building, consuming more memory, more time gzipping without caching.

    You'll hear the half-truth that "database is the real bottleneck", but that is repeatedly put to lie. See how going from PHP 5 to PHP 7 magically increased the speed of Laravel and Wordpress on the same SQL databases from 40 to 60%. I do the same thing to client's React and Vue crap by pitching those frameworks in the trash and replacing 90%+ of the code with http "write" of normal everyday markup.

    The more bloated crap you do on the back-end for no legitimate reason, the slower it's going to be. Shrinking the amount of stuff in the markup can reduce server load!

    And what's going to be faster, some goofy trick to make things "faster" client side that results in choking out the server, or something the server can deliver quickly? This is where so many artificial "tests" of page speed miss the mark. They use a static HTML or page on servers without load to test JUST client side speed, taking zero concern for what their "solutions" are doing server-side! Or they look at just client-side stuff that doesn't include the actual render time. JS fanboys love that latter one as it helps card-stack their bullshit.

    How is that more convenient? It's bad enough wading through PHP to work with your markup, without getting scriptttardery in there too.

    It makes it sound like you're doing a lot of things in all the wrong places. Again though that's just a guess.

    The WHAT? There shouldn't be any server-side code to be passed, just values. And these days with data- attributes even that doesn't warrant a <script> tag anymore.

    Realistically if you have more than one or two <script> in a page, and they're not right before </body> or set to async, you're probably going about things a difficult, inefficient, and convoluted manner.

    It's why we now have the template tag, though given that such rubbish often dodges using the DOM and tends to go with insecure trash like innerHTML, yeah... that's trash too.

    Particularly since it's one of those "scripting only solutions". You do it in a standalone app for something like Electron or through Visual Studio, fine... but you pull that stunt on a website or anything web-facing you're rolling the dice on flipping off litigious users. Especially if you're doing anything that can be done just fine and dandy without JavaScript.

    Thus:
    "

    Is something I'd never allow on a website, and would require a great deal of logic, reason, and justification to allow on a web facing app. But again I'm an accessibility and efficiency consultant, so "web apps" with their script-tard only solutions are my mortal enemy. :p

    Back in the '90's I not only wrote double entry accounting systems, I also wrote 3d code for the likes of EA back when it all had to be done on the CPU. I'm the nutjob who fought against matrix multiplies and did projections with arctangent instead of sin/cos/depth divide.

    Exactly that. Whenever possible scripting off, CSS off, images blocked, and every other enhancement to a page should be accounted for. It's why I have such a loathing of "scripting only" solutions like web crapplets... at least when there's no legitimate reason for what's being done to be an application.

    In that way, the problem isn't apps, it's people using apps for what should be normal everyday websites. The hot and trendy "PWA" stuff having a legitimate use, but is being slathered on with a paint roller at everything, telling large swaths of users to go f*** themselves in the process!

    And that's why knowing if it's an app or a website is important. You didn't really specify which, and I coded it how I would for a website. Once you cross the line to "JavaScript users only screw everyone else" you've violated a rule of web accessibility, and therefor a lot of good practices become irrelevant.

    Redirected? naughty, naughty. At that point the page should have a <noscript> in your <maion>, and everything that requires scripting being loaded via the scripting. But then in a lot of codebases I see people dicking around with redirects instead of just doing things. I don't get it. Complete waste of code and time.

    Assuming you're doing something that actually requires a scripting-only solution. Again, something I wouldn't be using web technologies for in the first place. At that point man the **** up and write a real application.

    One of the "problems" with HTML, CSS, and JavaScript is they are "moving targets". New stuff is being added all the time, old stuff is deprecated and/or removed outright, and it's hard to keep up. Attribute selectors are very powerful and a welcome addition. See something like:

    
    th[scope="row"] { }
    
    Code (markup):
    So you don't have to piss a class on it.

    setProperty was always there, and we were SUPPOSED to use it to set styles on elements instead of Element.style.whatever. The problem is the latter is too "convenient" when the property being set isn't valid in the JS namespace. Those leading hyphens of custom properties (aka CSS variables) being an example of this. Same for things like browser prefixes such as -webkit or -moz.

    It's akin to the difference between Element properties and getAttribute and/or setAttribute which a lot of JS dev's don't understand. Take href for example, if you had this:

    <a href="#test" id="test">
    Code (markup):
    This scripting shows the difference.

    
    let a = document.getElementById("test");
    console.log(a.href); // outputs "http://youruri.com/path/file#test"
    console.log(a.getAttribute("href")); // outputs just "#test"
    
    Code (markup):
    It's why we're SUPPOSED to use getAttribute and setAttribute, not the property assignments. Most people don't, even when it could make a difference. It's important to know when/where they can go bits up. Usually on write you're ok, but on read? You can get some really unexpected values.

    A LOT of Node and Element methods exist like that, and most people don't take the time to research them. IT's why I'm always pointing people at MDN and simply saying "read the object reference so you at least know what methods are available." You don't have to memorize what they do and how to call them, just know they exist so you can look it up as needed, instead of ending up brute force coding things that already exist.

    I've lost count of the number of times I've come across five or six k of brute force code for things I can do in three lines.

    Like this crap codebase I rewrote for a client years ago where they had this 9k PHP file containing an "encode" function, that after I rewrote it I realized was nothing more than a base64 encoder. Because of course PHP can't do that on its own. WORSE it was being used to send XML of their e-mail address and un/pw/hostnames client-side in their form. Couldn't figure out if I should laugh or cry on that one!
     
    Last edited: Jul 23, 2022
    deathshadow, Jul 23, 2022 IP
  20. qwikad.com

    qwikad.com Illustrious Member Affiliate Manager

    Messages:
    7,151
    Likes Received:
    1,656
    Best Answers:
    29
    Trophy Points:
    475
    #20
    The book of deathshadow's replies:

    [​IMG]
     
    qwikad.com, Jul 24, 2022 IP
    sarahk likes this.