Naar de inhoud

Blog ·

Een balk smaller dan zijn venster

Een kopbalk klapte om op vensterbreedte terwijl een zijbalk er een derde van opat, en de taal die nul pixels overliep was juist de taal die stuk was.

Door Provibr

Elke pagina van ons paneel schoof zijwaarts bij een vensterbreedte van 768 pixels. Acht pixels te breed in het Engels, achtendertig in het Roemeens. Dat was al een tijd zo, in negen talen, op elke route. Die getallen komen uit een sweep in twee muntschrijfwijzen; een eerdere losse meting van dezelfde kopbalk kwam op drie uit.

De oorzaak is een zin waar je makkelijk bij knikt en die niet klopt: de kopbalk klapte zijn inhoud om op de breedte van het venster.

Het venster is de balk niet

Vanaf het middelste breekpunt staat de zijbalk naast de kopbalk in plaats van achter een hamburger, en hij kost zestien rem. Bij een venster van 768 pixels is de contentbox van de kopbalk dus 464 pixels. Niet 768, en ook geen 736.

De twee regels die de overloop hadden moeten voorkomen, het verbergen van de accountnaam en het inkrimpen van de verbindingspil tot een stipje, stonden allebei op het kleine breekpunt: 640 pixels venster. Dat is 128 pixels eerder dan het punt waarop de zijbalk verschijnt en zijn zestien rem meeneemt. Tussen die twee getallen ligt een band waarin de kopbalk denkt dat hij ruimte zat heeft en in werkelijkheid minder heeft dan bij elke smallere breedte, want op 640 was de zijbalk nog verborgen.

Dit is geen Tailwind-probleem en geen breekpunt dat één stap te laag stond. Het is een categoriefout. Een mediaquery beantwoordt de vraag hoe groot het kijkvenster is. De vraag die de kopbalk beantwoord wil hebben is hoeveel ruimte hij heeft gekregen, en tot er containerquery's waren was er geen manier om die te stellen.

Meet wat de rij vraagt, niet wat hij doet

De verleiding is om op dit punt het breekpunt een tikje op te hogen en te kijken wat er gebeurt. Dat levert een getal op dat werkt op de machine van degene die het tikje gaf.

Een flexrij krimpt zijn kinderen tot hun min-content voordat er iets overloopt, dus wat je op het scherm ziet is het eindsymptoom en niet de meting. Een rij kan ver over zijn budget zitten en er toch goed uitzien, precies tot één kind niet verder kan krimpen. Het getal waarop je stuurt is wat de rij vraagt als niets hem beperkt: kloon hem, zet hem op max-content, en lees hem af, in elke taal.

Gedaan op 768 pixels in de bredere muntschrijfwijze, over negen talen, komen de posten er zo uit.

PostBreedste meting
Drie pictogramknoppen (meldingen, taken, feedback)3 × 36 = 108 px
Vijf tussenruimtes tussen de posten60 px
De verbindingspil, breedste taal104,8 px
Dezelfde status als stipje6 px
De taalknop, breedste taal83,4 px
De accountknop zonder naam132,9 px
De accountknop mét naam, op zijn budget234,6 px
Tussenruimte naar de linkergroep, plus reserve2 × 16 px

Daaruit volgen twee drempels, en allebei staan ze op de contentbox van de kopbalk in plaats van op het venster. De accountnaam tonen vraagt 524 pixels, dus hij begint op 34 rem, met twintig pixels speling. De pil in plaats van het stipje vraagt 622,8, dus die begint op 40 rem, met zeventien. Onder de naamdrempel vraagt de rij 422,3 pixels, en dat past ruim in de 464 die hij krijgt.

Het prettige aan een containervraag in plaats van een venstervraag is wat er daarna gebeurt zonder één regel extra. Klapt de zijbalk in tot een rail, dan houdt datzelfde venster van 768 pixels 656 pixels kopbalk over, en komen de naam en de pil vanzelf terug. Niets weet iets van die rail; de balk heeft zichzelf gewoon opnieuw gemeten.

De taal met nul pixels overloop

De sweep die deze klasse defecten opving meet documentbreedte tegen vensterbreedte. Over negen talen meldde hij overal overloop, van acht tot achtendertig pixels, behalve in het Frans, dat nul meldde.

Frans mankeerde wel degelijk iets. De verbindingspil was naar een tweede regel gewikkeld in een balk van vierenzestig pixels hoog met zijn posten gecentreerd, dus de tekst stond stilletjes half buiten zijn eigen doos terwijl het document precies zo breed bleef als het venster. Geen enkele overloopsweep ziet dat, want er liep niets over.

Dit is dezelfde vorm als een eerder defect op onze marketingsite, waar een eenwoordig opschrift in een gekrompen tegel over zijn buurman heen schilderde en de paginabreedte nooit veranderde. Tekst die zijn doos verlaat maakt het document niet breder. De controle moet dus de andere zijn: de rechterrand van de tekst tegen de binnenrand van de doos waar hij in hoort, plus het aantal regelvakken dat hij bezet. In een balk met een vaste hoogte is meer dan één regelvak op zichzelf al een defect.

Twee manieren waarop de meting tegen je liegt

Het meetgereedschap kostte twee pogingen, en beide mislukkingen wezen dezelfde kant op: naar een groene uitslag die niets betekent.

Een kloon op max-content moet binnen de container gemeten worden. De onze werd aan de body van het document gehangen, en dat is helemaal buiten de kopbalk, dus de containerquery matchte nooit en de kloon rendeerde in zijn smalle gedaante: 394,8 pixels waar de echte rij 515,3 vroeg. Gelezen als een voor- en nameting ziet dat er precies uit als een geslaagde reparatie. Het is dezelfde val als meten in euro's terwijl de klant dollars ziet, of een pagina meten waarvan de data nooit landde: het getal is niet fout, het is een antwoord op een andere vraag.

De tweede is doffer en toch het weten waard. Een syntaxcontrole op het sweepscript loopt over een niet-ontsnapte backtick in een sjabloonstring heen, dus een probe kan subtiel niet de probe zijn die je schreef terwijl het bestand netjes ontleedt.

Daarom kreeg de sweep een bewijsstand die bewust kapotte elementen in de kopbalk hangt, een blok dat te breed is voor de balk, een knop die te smal is voor zijn opschrift en een regel tekst die buiten zijn eigen doos loopt, en eist dat de probe ze allemaal meldt. Hij eist ook dat de accountknop er überhaupt is. Een scanner die niets vindt is niet te onderscheiden van een scanner die niet kijkt, en de enige manier om die twee uit elkaar te houden is hem iets te geven om te vinden.

Tegen de ongerepareerde code leverde de sweep vierenzeventig rode uitslagen op van achtennegentig controles. Tegen de reparatie, in beide munten, 2033 van 2033.

Afkappen zonder de knop te breken

Drie kleinere besluiten in de reparatie zijn precies het soort dat iemand later bij het opruimen terugdraait, dus ze staan opgeschreven waar de klassen staan.

Het afkappen zit op een span ín de knop, niet op de knop. overflow: hidden op de knop zelf knipt zijn eigen klikvlak en zijn focusring af, en dat maakt van een cosmetische reparatie een defect in de toetsenbordtoegankelijkheid.

De toegankelijke naam blijft volledig. Afkappen is een presentatiekeuze; een schermlezer hoort de hele organisatienaam te krijgen, dus het label draagt hem voluit.

En precies één ding in die rij mag krimpen. Zonder de pictogramknoppen vast te zetten verdeelt flexbox de krimp over alle knoppen, en dan krijg je drie samengeknepen pictogramknoppen in plaats van één naam die netjes afkapt. Krimpen is een besluit over wie er wijkt, en neem je dat niet, dan neemt de layoutmotor het voor je, gelijkmatig, wat vrijwel nooit is wat iemand wil.

Nog iets om te weten voor je hiernaar grijpt: een container maakt ook een insluitingsgrens voor layout, en daarmee wordt hij het bevattende blok voor alles wat eronder vast gepositioneerd is. Hier verandert dat niets, omdat de menu's en laden die erbij horen native dialogen in de bovenste laag zijn, en omdat de balk al een achtergrondfilter droeg dat exact dezelfde uitwerking heeft. Dat is nagekeken door ze te openen en niet beredeneerd, en was het antwoord anders geweest, dan had de container ergens anders moeten staan.

Daarmee komt de laatste beperking in beeld: de container hoort in die ene functie die elke kopbalk bouwt, want de beheerkopbalk mount hetzelfde accountmenu. Een containerquery zonder container matcht nooit, en stil. Zet hem op één plek en vergeet de andere, en de accountnaam verdwijnt uit een heel deel van het product zonder dat er in enig log iets van te zien is.

Wat we zouden opschrijven

  1. Een mediaquery beantwoordt een vraag over het kijkvenster. Deelt een component zijn breedte met een zijbalk, dan is dat de verkeerde vraag, en het antwoord is precies de breedte van die zijbalk fout.
  2. Stuur op wat een rij vraagt, niet op wat hij doet. Flex krimpt eerst zijn kinderen, dus het scherm toont je het eindsymptoom.
  3. Meet de kloon bínnen de container. Erbuiten matcht de query niet en meet je de smalle gedaante, wat leest als een reparatie.
  4. Nul pixels overloop kan het kapotte geval zijn. Tekst die zijn doos verlaat maakt het document niet breder; toets de tekst tegen zijn eigen doos en tel de regelvakken.
  5. Geef de scanner iets om te vinden. Een bewijsstand die bekende defecten plant is de enige manier om "niets mis" van "niet gekeken" te onderscheiden.
  6. Kap af op een binnenste element. De knop afknippen knipt de focusring af, en de toegankelijke naam hoort heel te blijven.
  7. Kies wie er krimpt. Laat je het los, dan verdeelt flex de pijn gelijkmatig over alles.

Voor de duidelijkheid over wat dit is: de reparatie is gebouwd, gemeten over negen breedtes, negen talen, vijf routes en beide munten, en draait. Ze is niet op een productiebuild gemeten, dus hier staat niets over layoutverschuiving, en er is de hele tijd één organisatienaam gebruikt.

Uit het platformwerk aan Provibr. De pagina waarvan de overloop dit begon staat in offline naast een kop die online zegt, en wat negen talen met een verzameling knoppen van vaste maat doen staat in zestienduizend sleutels en negen talen.

Begin met één host en één agent

Maak een account aan, installeer de agent met één commando en koppel je eerste Proxmox-host. De proefperiode loopt 14 dagen en vraagt geen betaalgegevens.