renderNG ayrıntılı incelemesi: LayoutNG blok parçalanması

LayoutNG'de blok parçalanması tamamlandı. Bu makalenin nasıl çalıştığını ve neden önemli olduğunu öğrenmek için bu makaleyi inceleyin.

Morten Stenshorne
Morten Stenshorne

Ben Morten Stenshorne. Google'ın Blink oluşturma ekibinde düzen mühendisiyim. 2000'lerin başından beri tarayıcı motoru geliştirme alanındayım ve Presto motorunda (Opera 12 ve öncesi) acid2 testin başarılı olmasına yardımcı olmak ve Presto'daki tablo düzenini düzeltmek için diğer tarayıcılarda tersine mühendislik yapmak gibi çok eğlendim. Ayrıca bu yılların çoğunu blok parçalamaya, özellikle Presto, WebKit ve Blink'te çoklu olarak harcadım. Geçtiğimiz birkaç yıl boyunca Google'da ağırlıklı olarak LayoutNG'ye blok parça parçalama desteği ekleme çalışmalarına rehberlik etmeye odaklandım. Blok parçalama uygulamasıyla ilgili bu ayrıntılı inceleme için bize katılın. Bu, blok parçalamayı son uygulamam olabilir. :)

Blok parçalama nedir?

Blok parçalama, CSS blok düzeyindeki bir kutunun (bölüm veya paragraf gibi) parçalayıcı adı verilen tek bir parça kapsayıcının içine bütün olarak sığmadığında birden fazla parçaya bölünmesi anlamına gelir. Parçalayıcı bir öğe değildir ancak çok sütunlu düzendeki bir sütunu veya sayfalı medyadaki bir sayfayı temsil eder. Parçalanmanın gerçekleşmesi için içeriğin bir parçalanma bağlamı içinde olması gerekir. Parçalı içerik, en yaygın olarak çok sütunlu kapsayıcı (içerik sütunlara bölünür) veya yazdırma işlemi sırasında (içerik sayfalara bölünür) oluşturulur. Çok sayıda satır içeren uzun bir paragrafın birden çok parçaya bölünmesi gerekebilir. Böylece ilk satırlar ilk parçaya, kalan satırlar sonraki parçalara yerleştirilir.

İki sütuna ayrılmış bir metin paragrafı.
Bu örnekte bir paragraf çok sütunlu düzen kullanılarak iki sütuna ayrılmıştır. Her sütun, parçalara ayrılmış akışın bir parçasını temsil eden parçalara ayrılır.

Blok parçalama, iyi bilinen başka bir parçalama türüne benzer: çizgi parçalanması ("satır kırma" olarak da bilinir). Birden fazla kelimeden (herhangi bir metin düğümü, herhangi bir <a> öğesi vb.) oluşan ve satır sonlarına izin veren herhangi bir satır içi öğe birden çok parçaya bölünebilir. Her parça, farklı bir satır kutusuna yerleştirilir. Çizgi kutusu, sütunlar ve sayfalar için parçalayıcı aracına eşdeğer olan satır içi parçalamadır.

LayoutNG blok parçalanması nedir?

LayoutNGBlockFragmentation, LayoutNG için parçalama motorunun yeniden yazılmış bir ifadesidir. Yıllar süren çalışmalardan sonra ilk parçalar nihayet bu yılın başlarında Chrome 102'de kullanıma sunulmuştur. Bu, "eski" motorumuzda aslında düzeltilemeyen, uzun süredir devam eden sorunları düzeltti. Veri yapıları açısından bakıldığında, NG öncesi birden çok veri yapısını doğrudan parça ağacında temsil edilen NG parçaları ile değiştirir.

Örneğin, yazarların bir üstbilgiden hemen sonra ara vermelerini sağlayan "break-before" ve "break-after" CSS özellikleri için "avoid" değerini artık destekliyoruz. Bir sayfaya yerleştirilen son öğenin bir başlık olması, bölümün içeriğinin ise sonraki sayfada başlaması genellikle iyi bir şey değildir. Bunun yerine, üstbilgiden önce ara vermek daha iyidir. Örnek için aşağıdaki resme bakın.

İlk örnekte sayfanın alt tarafında bir başlık, ikinci örnekte ise ilişkili içerikle birlikte sonraki sayfanın üst kısmında gösterilmektedir.

Chrome 102, parçalı taşmayı da destekler. Böylece monolitik (kırılamaz olması düşünülen) içerik birden çok sütuna bölünmez. Gölge ve dönüştürme gibi boyama efektleri doğru şekilde uygulanır.

LayoutNG'de blok parçalama tamamlandı

Bu yazı hazırlanırken, LayoutNG'de tam blok parçalama desteğini tamamlamış bulunuyoruz. Chrome 102 ile gönderilen çekirdek parçalanma (çizgi düzeni, kayan öğeler ve akış dışı konumlandırma dahil olmak üzere blok kapsayıcılar). Esnek ve ızgara parçalama Chrome 103'te, tablo parçalama ise Chrome 106'da kullanıma sunulur. Son olarak, yazdırma Chrome 108 sürümünde gönderilmiştir. Blok parçalama, düzeni gerçekleştirmek için eski motora bağlı olan son özellikti. Bu, Chrome 108 sürümünden itibaren eski motorun düzeni gerçekleştirmek için kullanılamayacağı anlamına gelmektedir.

LayoutNG veri yapıları, gerçekten içeriğin yerleşimine ek olarak, boyamayı ve isabet testini destekler. Ancak, offsetLeft ve offsetTop gibi düzen bilgilerini okuyan JavaScript API'leri için, bazı eski veri yapılarını kullanmaya devam ediyoruz.

Her şeyi NG kullanarak düzenlemek, CSS kapsayıcı sorguları, çapa konumlandırması, MathML ve özel düzen (Houdini) gibi yalnızca LayoutNG uygulamaları olan (eski motor eşdeğeri olmayan) yeni özelliklerin uygulanmasını ve sunulmasını mümkün kılar. Kapsayıcı sorguları için ise, yazdırmanın henüz desteklenmediğini geliştiricilere belirten bir uyarıyla birlikte bir süre önceden gönderdik.

Normal blok kapsayıcı düzeni, satır içi düzen, kaymalar ve akış dışı konumlandırmadan oluşan ancak esnek, ızgara veya tablo desteği sunmayan ve blok parça parçalamayı hiçbir şekilde desteklemeyen LayoutNG'in ilk bölümünü 2019'da gönderdik. Eski düzen motorunu esnek, ızgara, tablolar ve blok parçalamaya ilişkin her şey için kullanabiliriz. Bu, parçalanmış içerik içindeki blok, satır içi, kayan ve akış dışı öğeler için bile geçerliydi. Gördüğünüz gibi, böyle karmaşık bir düzen motorunu yerinde yükseltmek oldukça hassas bir işlemdir.

Buna ek olarak, ister inanın ister inanmayın, 2019'un ortalarına doğru LayoutNG blok parça parçalama düzeninin temel işlevlerinin büyük bir kısmı (bayrağın arkasında) zaten uygulanmıştı. Peki, gönderilmesi neden bu kadar uzun sürdü? Bunun kısa yanıtı şudur: Parçalılığın, sistemin çeşitli eski bölümleriyle doğru bir şekilde bir arada bulunması gerekir ve bu da tüm bağımlılıklar yeni sürüme geçirilene kadar kaldırılamaz veya yükseltilemez. Uzun yanıt için aşağıdaki ayrıntılara bakın.

Eski motor etkileşimi

Eski veri yapıları hâlâ düzen bilgilerini okuyan JavaScript API'lerinden sorumludur. Bu nedenle, verileri eski motora onun anlayacağı şekilde geri yazmamız gerekir. Buna LayoutMultiColumnFlowThread gibi eski çok sütunlu veri yapılarının doğru şekilde güncellenmesi de dahildir.

Eski motor yedek algılama ve işleme

İçinde LayoutNG blok parçası tarafından henüz işlenmeyen içerik varken eski düzen motorunu kullanmaya devam etmek zorunda kalıyorduk. Esnek, ızgara, tablolar ve yazdırılan her şeyi içeren temel LayoutNG bloğu parçalanma zamanı (2022 ilkbaharı) sırasında. Düzen ağacında nesne oluşturmadan önce eski yedek ihtiyacını algılamamız gerektiğinden bu durum özellikle zordu. Örneğin, çok sütunlu kapsayıcı üst öğesi olup olmadığını ve hangi DOM düğümlerinin biçimlendirme bağlamına dönüşeceğini öğrenmeden önce tespit etmemiz gerekiyordu. Bu bir tavuk-yumurta sorunu ve mükemmel bir çözümü olmayan, ancak tek yanlış davranışı yanlış pozitifler olduğu sürece (aslında ihtiyaç olmadığında eskiye dönmek) sorun değil, çünkü bu düzen davranışındaki hatalar Chromium'un zaten sahip olduğu hatalar değil, yeni olanlar değil.

Ağaç boyama öncesi yürüyüşü

Ön boyama, düzenlendikten sonra ancak boyadan önce yaptığımız bir iştir. Asıl zorluk, düzen nesne ağacını yürütmemiz gerekmesi, ama şu anda NG parçalarımız var. Peki bununla nasıl başa çıkacağız? Hem düzen nesnesini hem de NG parça ağaçlarını aynı anda yürütürüz. Bu oldukça karmaşık bir işlemdir, çünkü iki ağaç arasındaki harita oluşturmak önemsiz değildir. Düzen nesnesi ağaç yapısı, DOM ağacının yapısına çok benzese de parça ağacı, düzenin bir girişi değil, düzen çıkışıdır. Satır içi parçalama (satır parçaları) ve blok parçalama (sütun veya sayfa parçaları) dahil herhangi bir parçalamanın etkisini yansıtmak dışında, parça ağacının içeren blok ile bu parçayı içeren blok olarak içeren DOM alt öğeleri arasında doğrudan bir üst-alt ilişkisi de vardır. Örneğin, parça ağacında, tam olarak konumlandırılmış bir öğe tarafından oluşturulan bir parça, üst öğe zincirinde akış dışı konumlandırılmış alt öğe ile bunu içeren blok arasında başka düğümler olsa bile, bunu içeren blok parçasının doğrudan alt öğesidir.

Parçalanma içinde akış dışı konumlandırılmış bir öğe olduğunda daha da karmaşık hale gelir, çünkü bu durumda akış dışı parçalar, parçalayıcı öğesinin doğrudan alt öğeleri olur (CSS'nin kapsayıcı blok olarak düşündüğü bir alt öğe olmaz). Ne yazık ki, eski motorla çok fazla sorun yaşamadan bir arada bulunabilmek için çözülmesi gereken bir sorun vardı. LayoutNG, tüm modern düzen modlarını esnek bir şekilde destekleyecek şekilde tasarlandığından, gelecekte bu kodun büyük bir kısmını basitleştirebileceğiz.

Eski parçalama motoruyla ilgili sorunlar

Web'in daha önceki bir çağında tasarlanan eski motor, (baskıyı desteklemek için) o zamanlar da teknik olarak parçalanma olsa bile gerçek parçalama kavramına sahip değildir. Parçalama desteği sadece üste vidalanan (yazdırma) veya güçlendirilen (çok sütunlu) bir özellikti.

Parçalanabilir içeriği yerleştirirken, eski motor her şeyi, genişliği bir sütun veya sayfanın satır içi boyutu kadar ve yüksekliği, içeriğini barındırmak için gereken yükseklikte olan uzun bir şerit halinde düzenler. Bu uzun şerit sayfaya dönüştürülmez. Bunu, nihai görüntüleme için yeniden düzenlenen sanal bir sayfa olarak düşünebilirsiniz. Bu işlem, kavramsal olarak bir gazete makalesinin tamamını bir sütuna yazdırıp ikinci adım olarak makas kullanarak birden çok parçaya bölmeye benzer. (Eskiden bazı gazeteler aslında buna benzer teknikler kullanıyordu!)

Eski motor, şeritteki sanal bir sayfa veya sütun sınırını izler. Bu şekilde, sınırın dışına taşan içeriği bir sonraki sayfaya veya sütuna sürükler. Örneğin, motorun geçerli sayfa olarak düşündüğüne bir çizginin yalnızca üst yarısı sığarsa, motorun sonraki sayfanın üst kısmının olduğunu varsaydığı konuma aşağı itmek için bir "sayfalara ayırma desteği" ekler. Daha sonra, gerçek parçalama işinin çoğu ("makasla kesme ve yerleştirme") düzenden sonra, önceden boyama ve boyama sırasında içerik sütunlarının kırpılmasından sonra yapılır. Bu, parçalamadan sonra dönüşüm uygulamak ve göreli konumlandırmayı uygulamak (özelliklerin gerektirdiği) gibi birkaç şeyi esasen imkansız hale getirdi. Ayrıca, eski motorda tablo parçalanması için bir miktar destek olsa da esnek veya ızgara parçalama desteği yoktur.

Makas, yerleşim ve yapıştırıcı kullanmadan önce üç sütunlu bir düzenin eski motorda dahili olarak nasıl temsil edildiğini burada görebilirsiniz (belirtilen bir yüksekliğimiz vardır, dolayısıyla yalnızca dört satır sığar, ancak alt kısımda biraz fazla alan vardır):

Dahili temsil, sayfalara ayırma içeren tek sütun olarak içeriğin kırıldığı noktalara, ekrandaki gösterim ise üç sütun halinde gösterilir.

Eski düzen motoru düzen sırasında aslında içeriği parçalara ayırmadığından, göreli konumlandırma ve dönüştürmelerin yanlış uygulanması ve kutu gölgelerinin sütun kenarlarından kırpılması gibi pek çok tuhaf yapı mevcuttur.

Aşağıda, text-shadow komutunu içeren basit bir örnek verilmiştir:

Eski motor bu sorunu iyi işlemez:

Kırpılmış metin gölgeleri ikinci sütuna yerleştirilir.

İlk sütundaki satırdan alınan metin gölgesinin nasıl kırpıldığını ve bunun yerine ikinci sütunun en üstüne nasıl yerleştirildiğini görüyor musunuz? Bunun nedeni, eski düzen motorunun parçalamayı anlamamasıdır.

Şu şekilde görünmelidir (NG ile bu şekilde görünür):

Gölgelerin doğru şekilde gösterildiği iki metin sütunu.

Şimdi de dönüştürme ve kutu gölgelendirmesiyle işi biraz daha karmaşık hale getirelim. Eski motorda, kırpma ve sütun kanamasının yanlış olduğuna dikkat edin. Bunun nedeni, dönüşümlerin spesifikasyona göre düzene göre, parçalama sonrası efekt olarak uygulanmasıdır. LayoutNG parçalanmasıyla her ikisi de düzgün çalışır. Bu, Firefox ile birlikte çalışabilirliği artırır. Firefox, bu alandaki çoğu testin aynısını oradan geçerken bir süredir iyi parçalama desteğine sahipti.

Kutular yanlış bir şekilde iki sütuna bölünmüştür.

Eski motorda, uzun monolitik içerikle ilgili sorunlar da vardır. İçerik, birden fazla parçaya bölünmeye uygun değilse monolitik niteliktedir. Taşma kaydırmalı öğeler, kullanıcıların dikdörtgen olmayan bir bölgede kaydırma yapması anlamlı olmadığından monolitik öğelerdir. Diğer monolitik içerik örnekleri çizgi kutuları ve resimlerdir. Aşağıda bir örnek verilmiştir:

Monolitik içerik parçası, bir sütuna sığmayacak kadar uzunsa eski motor, bunu acımasızca dilimler (kaydırılabilir kapsayıcıyı kaydırmaya çalışırken çok "ilginç" bir davranışa yol açar):

LayoutNG blok parçasında olduğu gibi ilk sütunda taşmasına izin vermek yerine:

ALT_TEXT_HERE

Eski motor, zorunlu araları destekler. Örneğin, <div style="break-before:page;">, DIV öğesinden önce bir sayfa sonu ekler. Ancak en uygun zorunlu araları bulma konusunda sınırlı desteğe sahiptir. break-inside:avoid ile yetimler ve dullar desteklenir ancak örneğin break-before:avoid üzerinden istenirse bloklar arasında bölmelerin olmaması için herhangi bir destek yoktur. Aşağıdaki örneğe bakın:

Metin iki sütuna ayrılmış.

Burada, #multicol öğesinde her sütunda 5 satırlık yer vardır (çünkü 100 piksel yüksekliğinde ve çizgi yüksekliği 20 pikseldir), dolayısıyla #firstchild öğesinin tamamı ilk sütuna sığabilir. Bununla birlikte, kardeş öğesi #secondchild olan "break-before:avoid" (içerik bu öğeler arasında ara verilmemesini ister). widows değeri 2 olduğundan, tüm aradan kaçınma isteklerini kabul etmek için ikinci sütuna 2 #firstchild satırı aktarmamız gerekir. Chromium, bu özellik kombinasyonunu tam olarak destekleyen ilk tarayıcı motorudur.

NG parçalanmasının işleyiş şekli

NG düzen motoru, dokümanı genellikle önce CSS kutu ağacı derinliğinden geçirerek yerleştirir. Bir düğümün tüm alt öğeleri yerleştirildiğinde, NGPhysicalFragment oluşturulup üst düzen algoritmasına dönerek söz konusu düğümün düzeni tamamlanabilir. Bu algoritma, parçayı alt parçalar listesine ekler ve tüm alt parçalar tamamlandığında, tüm alt parçalarıyla birlikte kendisi için bir parça oluşturur. Bu yöntemle, dokümanın tamamı için bir parça ağacı oluşturur. Bu, işlemi fazla basite indirger. Örneğin, akış dışı konumlandırılmış öğeler yerleştirilmeden önce, DOM ağacında bulundukları konumdan kapsayıcı bloklarına yükselmek zorunda kalır. Kolaylık olsun diye bu ileri düzey ayrıntıyı yok sayıyorum.

LayoutNG, CSS kutusunun kendisiyle birlikte düzen algoritması için bir sınırlama alanı sağlar. Bu, algoritmaya düzen için kullanılabilir alan, yeni bir biçimlendirme bağlamının oluşturulup oluşturulmadığı ve önceki içeriğe ait ara kenar boşluğu daraltılması gibi bilgiler sağlar. Sınırlama alanı, parçalayıcının yerleştirilmiş blok boyutunu ve bunun içine geçerli blok ofsetini de bilir. Bu sütun, nerede sona ereceğini gösterir.

Blok parçalanması söz konusu olduğunda, alt öğelerin düzeni bir arada durmalıdır. Ayrılma nedenleri arasında, sayfada veya sütunda yer olmaması ya da zorunlu ara yer alır. Ardından, ziyaret ettiğimiz düğümler için parçalar üretiriz ve parçalanma bağlamı köküne (çoklu sütun veya yazdırma durumunda belge kökü) kadar geri döneriz. Ardından, parçalanma bağlamı kökünde, yeni bir parçalayıcı için hazırlanır ve tekrar ağaca inerek aradan önce kaldığımız yerden devam ederiz.

Aradan sonra düzeni devam ettirme yollarını sağlayan önemli veri yapısına NGBlockBreakToken adı verilir. Bir sonraki parçalayıcıda düzeni doğru bir şekilde devam ettirmek için gereken tüm bilgileri içerir. NGBlockBreakToken, bir düğümle ilişkilendirilir ve bir NGBlockBreakToken ağacı oluşturur. Böylece devam ettirilmesi gereken her düğüm temsil edilir. İçeride kalan düğümler için oluşturulan NGPhysicalBoxFragment öğesine bir NGBlockBreakToken eklenir. Ara jetonları, üst öğelere dağıtılarak bir ara jetonları ağacı oluşturur. Düğümün içinde değil, düğümden önce kırmamız gerekirse üst düğümün yine de düğüm için "break-önce" ara jetonu oluşturması gerekir. Böylece, sonraki parçalayıcıda düğüm ağacında aynı konuma vardığımızda bunu yerleştirmeye başlayabiliriz.

Parçalayıcı alanımız tükendiğinde (zorunlu ayrılmamış ara) veya zorunlu ara istendiğinde aralar eklenir.

En uygun zorunlu olmayan aralar için spesifikasyonda bazı kurallar vardır. Ayrıca, tam olarak alanımızın tükendiği bir yere ara eklemek her zaman doğru bir yöntem değildir. Örneğin, ara konumu seçimini etkileyen break-before gibi çeşitli CSS özellikleri vardır. Bu nedenle, düzen sırasında zorunlu aralar spesifikasyon bölümünü doğru bir şekilde uygulamak için olası iyi ayrılma noktalarını takip etmemiz gerekir. Bu kayıt, bozulma önleme isteklerini ihlal edecek bir noktada (örneğin, break-before:avoid veya orphans:7) alanımız kalmazsa geri gidip bulunan mümkün olan en son kesme noktasını kullanabileceğimiz anlamına gelir. Olası her ayrılma noktasına "bunu yalnızca son çare olarak yap" ile "kırılmak için mükemmel yer" arasında ve arada bazı değerler içeren bir puan verilir. Bir mola konumu "mükemmel" olarak puanlanırsa bu, o noktaya kırdığımızda hiçbir ihlal kuralının ihlal edilmeyeceği anlamına gelir (ve bu skoru tam olarak alanımız tükentiği noktada alırsak daha iyi bir şey aramamıza gerek yoktur). Puan "son çözüm" ise ayrılma noktası, geçerli bile değildir, ancak daha iyi bir şey bulamazsak ayrılma noktası, parça parça taşmalarını önlemek için yine de bozulabilir.

Geçerli ayrılma noktaları genellikle yalnızca kardeşler (satır kutuları veya bloklar) arasında ortaya çıkar. Örneğin, bir üst ve ilk alt öğesi arasında geçerli değildir (C sınıfı ayrılma noktaları istisnadır ancak bunları burada ele almamız gerekmez). Örneğin, break-before:avoid ile blok kardeşten önce geçerli bir ayrılma noktası vardır, ancak "perfect" ile "son-resort" arasında bir yerdedir.

Düzen sırasında, NGEarlyBreak adlı bir yapıda bulunan en iyi ayrılma noktasını izleriz. Erken ayrılma, bir blok düğümünden önce, içinde veya bir çizgiden (blok kapsayıcı satırı ya da esnek çizgi) önce gelen olası bir ayrılma noktasıdır. En iyi ayrılma noktasının daha önce alanımız tükendiğinde üzerinden geçip geçdiğimiz bir şeyin içinde derin bir yerde olması ihtimaline karşı, NGEarlyBreak nesnelerinden oluşan bir zincir veya yol oluşturabiliriz. Aşağıda bir örnek verilmiştir:

Bu örnekte, #second tarihinden hemen önce alanımız bitti ancak bu örnekte "break-before:avoid" ifadesi yer alıyor. Bu durumda, "aradan kaçınmayı ihlal ediyor" şeklinde bir ara konum puanı verilir. Bu noktada, "perfect"ten önce "perfect"ten önce "perfect" (mükemmel)" içeren bir NGEarlyBreak zincirimiz var ve "inside #outer > içinde #middle içinde > #inner içinde > bulunmaktadır. Dolayısıyla bu zincire girmeyi tercih ederiz. Dolayısıyla, düzeni #outer öğesinin başından başlayarak yeniden çalıştırmamız (ve bu kez bulduğumuz NGEarlyBreak'i geçmemiz) gerekir. Böylece, #Inner öğesinde "satır 3"ten önce bölebiliriz. ("Satır 3"ün önüne geçiyoruz. Böylece, kalan 4 satır bir sonraki parçalayıcıda yer alacak ve widows:4 kodunu koruyabilecek.)

Algoritma, hepsi sağlanamayacaksa kuralları doğru sırada bırakarak her zaman mümkün olan en iyi ayrılma noktasında (spec tanımlandığı gibi) kırılacak şekilde tasarlanmıştır. Parçalara ayırma akışı başına en fazla bir kez yeniden düzenleme yapmamız gerektiğini unutmayın. İkinci düzen geçişi sırasında, en iyi ara konumu düzen algoritmalarına geçmiştir. Bu, ilk düzen geçişinde keşfedilen ve o turda düzen çıkışının bir parçası olarak sağlanan ara konumudur. İkinci düzen geçişinde, yer tükenene kadar boş alan yapmıyoruz. Aslına bakılırsa, kuralların gereksiz yere ihlal edilmesini önlemek üzere erken ara eklememiz için son derece uygun (ve olması da çok güzel olan) bir yer sağlandığı için boş alanın dolması beklenmiyor (bu aslında bir hatadır). Bu yüzden, bu noktayı açıklığa kavuşturuyoruz ve kırıyoruz.

Bununla birlikte, parça parça taşmalarının önüne geçmeye yardımcı olduğu takdirde, bazen aradan kaçınma isteklerinden bazılarını ihlal etmemiz gerekebilir. Örnek:

Burada, #second öncesinde alanımız doldu, ancak "break-before:avoid" var. Bunun karşılığı, son örnekte olduğu gibi, "aradan kaçınmanın ihlali". Ayrıca, "ihlalde bulunan yetimler ve dullar" ("satır 2 "den önce #first içinde> içinde) bulunan bir NGEarlyBreak'i de sunuyoruz. Bu bölüm, yine de mükemmel değildir ancak "aradan kaçınmayı ihlal etmekten" daha iyidir. Bu yüzden, "2. satır"dan önce, yetimler / dullar isteğini ihlal edeceğiz. Bu spesifikasyon, 4.4. Uygulanmamış Aralar:

Özet

LayoutNG blok parçalama projesinin ana işlevsel hedefi, hata düzeltmeleri dışında, eski motorun desteklediği her şeyin LayoutNG mimarisini destekleyen bir uygulama şekli sağlamak ve bunu mümkün olduğunca az yapmaktı. Buradaki ana istisna, daha iyi ara önleme desteğidir (örneğin, break-before:avoid). Çünkü bu destek, parçalama motorunun temel bir parçasıdır. Bu nedenle, daha sonra eklemek başka bir yeniden yazma anlamına geleceğinden bu desteğin en baştan dahil edilmesi gerekir.

LayoutNG blok parçalama işlemi tamamlandı. Yazdırma sırasında karma sayfa boyutlarını destekleme, yazdırma sırasında @page kenar boşluğu kutuları ve box-decoration-break:clone gibi yeni işlevler eklemek için çalışmaya başlayabiliriz. Ayrıca LayoutNG'de genel olarak olduğu gibi, yeni sistemin hata oranının ve bakım yükünün zamanla önemli ölçüde daha düşük olmasını bekliyoruz.

Okuduğunuz için teşekkür ederiz!

Teşekkür