ব্রাউজার কিভাবে কাজ করে

আধুনিক ওয়েব ব্রাউজারগুলির পর্দার আড়ালে

মুখবন্ধ

WebKit এবং Gecko-এর অভ্যন্তরীণ ক্রিয়াকলাপের উপর এই বিস্তৃত প্রাইমারটি ইসরায়েলি বিকাশকারী তালি গারসিয়েলের করা অনেক গবেষণার ফলাফল। কয়েক বছর ধরে, তিনি ব্রাউজার ইন্টারনাল সম্পর্কে প্রকাশিত সমস্ত ডেটা পর্যালোচনা করেছেন এবং ওয়েব ব্রাউজার সোর্স কোড পড়তে অনেক সময় ব্যয় করেছেন। সে লিখেছিল:

একজন ওয়েব ডেভেলপার হিসাবে, ব্রাউজার অপারেশনের অভ্যন্তরীণ বিষয়গুলি শেখা আপনাকে আরও ভাল সিদ্ধান্ত নিতে এবং বিকাশের সর্বোত্তম অনুশীলনের পিছনে ন্যায্যতা জানতে সাহায্য করে ৷ যদিও এটি একটি অপেক্ষাকৃত দীর্ঘ নথি, আমরা আপনাকে খনন করার জন্য কিছু সময় ব্যয় করার পরামর্শ দিচ্ছি৷ আপনি খুশি হবেন৷

পল আইরিশ, ক্রোম বিকাশকারী সম্পর্ক

ভূমিকা

ওয়েব ব্রাউজার হল সবচেয়ে বেশি ব্যবহৃত সফটওয়্যার। এই প্রাইমারে, আমি ব্যাখ্যা করি কিভাবে তারা পর্দার আড়ালে কাজ করে। আপনি ব্রাউজার স্ক্রিনে Google পৃষ্ঠা না দেখা পর্যন্ত ঠিকানা বারে google.com টাইপ করলে কী হয় তা আমরা দেখব।

ব্রাউজার সম্পর্কে আমরা কথা বলতে হবে

বর্তমানে ডেস্কটপে পাঁচটি প্রধান ব্রাউজার ব্যবহার করা হয়েছে: ক্রোম, ইন্টারনেট এক্সপ্লোরার, ফায়ারফক্স, সাফারি এবং অপেরা। মোবাইলে, প্রধান ব্রাউজারগুলি হল অ্যান্ড্রয়েড ব্রাউজার, আইফোন, অপেরা মিনি এবং অপেরা মোবাইল, ইউসি ব্রাউজার, নোকিয়া S40/S60 ব্রাউজার এবং ক্রোম, অপেরা ব্রাউজারগুলি ব্যতীত সবগুলিই ওয়েবকিটের উপর ভিত্তি করে। আমি ওপেন সোর্স ব্রাউজার ফায়ারফক্স এবং ক্রোম এবং সাফারি (যা আংশিকভাবে ওপেন সোর্স) থেকে উদাহরণ দেব। StatCounter পরিসংখ্যান অনুসারে (জুন 2013 অনুযায়ী) ক্রোম, ফায়ারফক্স এবং সাফারি বিশ্বব্যাপী ডেস্কটপ ব্রাউজার ব্যবহারের প্রায় 71% তৈরি করে। মোবাইলে, অ্যান্ড্রয়েড ব্রাউজার, আইফোন এবং ক্রোমের ব্যবহার প্রায় 54%।

ব্রাউজারের প্রধান কার্যকারিতা

একটি ব্রাউজারের প্রধান কাজ হল সার্ভার থেকে অনুরোধ করে এবং ব্রাউজার উইন্ডোতে প্রদর্শন করে আপনার বেছে নেওয়া ওয়েব রিসোর্সটি উপস্থাপন করা। রিসোর্সটি সাধারণত একটি HTML ডকুমেন্ট, তবে এটি একটি PDF, ইমেজ বা অন্য কোনো ধরনের সামগ্রীও হতে পারে। ইউনিফর্ম রিসোর্স আইডেন্টিফায়ার (ইউনিফর্ম রিসোর্স আইডেন্টিফায়ার) ব্যবহার করে রিসোর্সের অবস্থান ব্যবহারকারী দ্বারা নির্দিষ্ট করা হয়।

ব্রাউজার যেভাবে HTML ফাইলগুলিকে ব্যাখ্যা করে এবং প্রদর্শন করে তা HTML এবং CSS স্পেসিফিকেশনে নির্দিষ্ট করা আছে। এই স্পেসিফিকেশনগুলি W3C (ওয়ার্ল্ড ওয়াইড ওয়েব কনসোর্টিয়াম) সংস্থা দ্বারা রক্ষণাবেক্ষণ করা হয়, যা ওয়েবের জন্য মানক সংস্থা। বছরের পর বছর ধরে ব্রাউজারগুলি স্পেসিফিকেশনের শুধুমাত্র একটি অংশ মেনে চলে এবং তাদের নিজস্ব এক্সটেনশন তৈরি করে। এটি ওয়েব লেখকদের জন্য গুরুতর সামঞ্জস্যের সমস্যা সৃষ্টি করেছে। আজকাল বেশিরভাগ ব্রাউজারই কমবেশি স্পেসিফিকেশন মেনে চলে।

ব্রাউজার ইউজার ইন্টারফেস একে অপরের সাথে অনেক মিল আছে। সাধারণ ব্যবহারকারী ইন্টারফেস উপাদানগুলির মধ্যে রয়েছে:

  1. একটি URI সন্নিবেশ করার জন্য ঠিকানা বার
  2. পিছনে এবং এগিয়ে বোতাম
  3. বুকমার্কিং অপশন
  4. রিফ্রেশ এবং বর্তমান নথি লোড করা বন্ধ করার জন্য বোতামগুলি রিফ্রেশ করুন
  5. হোম বোতাম যা আপনাকে আপনার হোম পেজে নিয়ে যাবে

আশ্চর্যজনকভাবে, ব্রাউজারের ইউজার ইন্টারফেস কোনো আনুষ্ঠানিক স্পেসিফিকেশনে নির্দিষ্ট করা হয়নি, এটি শুধুমাত্র বছরের পর বছর ধরে তৈরি করা ভাল অনুশীলন এবং ব্রাউজার একে অপরকে অনুকরণ করে। HTML5 স্পেসিফিকেশন ব্রাউজার থাকা আবশ্যক UI উপাদানগুলিকে সংজ্ঞায়িত করে না, তবে কিছু সাধারণ উপাদান তালিকাভুক্ত করে৷ এর মধ্যে অ্যাড্রেস বার, স্ট্যাটাস বার এবং টুল বার রয়েছে। ফায়ারফক্সের ডাউনলোড ম্যানেজারের মতো নির্দিষ্ট ব্রাউজারে অবশ্যই অনন্য বৈশিষ্ট্য রয়েছে।

উচ্চ-স্তরের অবকাঠামো

ব্রাউজারের প্রধান উপাদান হল:

  1. ইউজার ইন্টারফেস : এর মধ্যে রয়েছে অ্যাড্রেস বার, ব্যাক/ফরওয়ার্ড বোতাম, বুকমার্কিং মেনু, ইত্যাদি। ব্রাউজারের প্রতিটি অংশে আপনি অনুরোধ করা পৃষ্ঠাটি যে উইন্ডোটি দেখেন তা ছাড়া প্রদর্শন করে।
  2. ব্রাউজার ইঞ্জিন : UI এবং রেন্ডারিং ইঞ্জিনের মধ্যে মার্শাল অ্যাকশন।
  3. রেন্ডারিং ইঞ্জিন : অনুরোধ করা বিষয়বস্তু প্রদর্শনের জন্য দায়ী। যেমন অনুরোধ করা বিষয়বস্তু যদি HTML হয়, তাহলে রেন্ডারিং ইঞ্জিন HTML এবং CSS পার্স করে এবং পার্স করা কন্টেন্ট স্ক্রিনে প্রদর্শন করে।
  4. নেটওয়ার্কিং : নেটওয়ার্ক কলের জন্য যেমন HTTP অনুরোধ, একটি প্ল্যাটফর্ম-স্বাধীন ইন্টারফেসের পিছনে বিভিন্ন প্ল্যাটফর্মের জন্য বিভিন্ন বাস্তবায়ন ব্যবহার করে।
  5. UI ব্যাকএন্ড : কম্বো বক্স এবং উইন্ডোর মত মৌলিক উইজেট আঁকার জন্য ব্যবহৃত হয়। এই ব্যাকএন্ড একটি জেনেরিক ইন্টারফেস প্রকাশ করে যা প্ল্যাটফর্ম নির্দিষ্ট নয়। এর নিচে অপারেটিং সিস্টেম ইউজার ইন্টারফেস পদ্ধতি ব্যবহার করা হয়েছে।
  6. জাভাস্ক্রিপ্ট দোভাষী । জাভাস্ক্রিপ্ট কোড পার্স এবং এক্সিকিউট করতে ব্যবহৃত হয়।
  7. তথ্য ভান্ডার . এটি একটি অধ্যবসায় স্তর. ব্রাউজারকে স্থানীয়ভাবে কুকির মতো সব ধরণের ডেটা সংরক্ষণ করতে হতে পারে। ব্রাউজারগুলি স্থানীয় স্টোরেজ, ইনডেক্সডডিবি, ওয়েবএসকিউএল এবং ফাইল সিস্টেমের মতো স্টোরেজ প্রক্রিয়াগুলিকেও সমর্থন করে।
ব্রাউজার উপাদান
চিত্র 1: ব্রাউজার উপাদান

এটি লক্ষ্য করা গুরুত্বপূর্ণ যে Chrome এর মতো ব্রাউজারগুলি রেন্ডারিং ইঞ্জিনের একাধিক উদাহরণ চালায়: প্রতিটি ট্যাবের জন্য একটি। প্রতিটি ট্যাব একটি পৃথক প্রক্রিয়ায় চলে।

রেন্ডারিং ইঞ্জিন

রেন্ডারিং ইঞ্জিনের দায়িত্ব ভাল... রেন্ডারিং, সেটি হল ব্রাউজার স্ক্রিনে অনুরোধ করা বিষয়বস্তু প্রদর্শন।

ডিফল্টরূপে রেন্ডারিং ইঞ্জিন HTML এবং XML নথি এবং ছবি প্রদর্শন করতে পারে। এটি প্লাগ-ইন বা এক্সটেনশনের মাধ্যমে অন্যান্য ধরনের ডেটা প্রদর্শন করতে পারে; উদাহরণস্বরূপ, পিডিএফ ভিউয়ার প্লাগ-ইন ব্যবহার করে পিডিএফ ডকুমেন্ট প্রদর্শন করা। যাইহোক, এই অধ্যায়ে আমরা প্রধান ব্যবহারের ক্ষেত্রে ফোকাস করব: এইচটিএমএল এবং চিত্রগুলি প্রদর্শন করা যা CSS ব্যবহার করে ফর্ম্যাট করা হয়েছে।

বিভিন্ন ব্রাউজার বিভিন্ন রেন্ডারিং ইঞ্জিন ব্যবহার করে: ইন্টারনেট এক্সপ্লোরার ট্রাইডেন্ট ব্যবহার করে, ফায়ারফক্স গেকো ব্যবহার করে, সাফারি ওয়েবকিট ব্যবহার করে। ক্রোম এবং অপেরা (15 সংস্করণ থেকে) ব্লিঙ্ক ব্যবহার করে, ওয়েবকিটের একটি কাঁটা।

ওয়েবকিট হল একটি ওপেন সোর্স রেন্ডারিং ইঞ্জিন যা লিনাক্স প্ল্যাটফর্মের জন্য একটি ইঞ্জিন হিসাবে শুরু হয়েছিল এবং ম্যাক এবং উইন্ডোজ সমর্থন করার জন্য অ্যাপল দ্বারা সংশোধন করা হয়েছিল।

মূল প্রবাহ

রেন্ডারিং ইঞ্জিন নেটওয়ার্কিং স্তর থেকে অনুরোধকৃত নথির বিষয়বস্তু পেতে শুরু করবে। এটি সাধারণত 8kB খণ্ডে করা হবে।

এর পরে, এটি রেন্ডারিং ইঞ্জিনের মৌলিক প্রবাহ:

রেন্ডারিং ইঞ্জিন মৌলিক প্রবাহ
চিত্র 2: রেন্ডারিং ইঞ্জিন মৌলিক প্রবাহ

রেন্ডারিং ইঞ্জিন এইচটিএমএল ডকুমেন্ট পার্সিং শুরু করবে এবং উপাদানগুলিকে "কন্টেন্ট ট্রি" নামক একটি গাছে DOM নোডে রূপান্তর করবে। ইঞ্জিন স্টাইল ডেটা পার্স করবে, উভয় বাহ্যিক CSS ফাইল এবং স্টাইল উপাদানে। এইচটিএমএল-এ ভিজ্যুয়াল নির্দেশাবলীর সাথে স্টাইলিং তথ্য অন্য একটি ট্রি তৈরি করতে ব্যবহার করা হবে: রেন্ডার ট্রি

রেন্ডার ট্রিতে রঙ এবং মাত্রার মতো চাক্ষুষ বৈশিষ্ট্য সহ আয়তক্ষেত্র রয়েছে। আয়তক্ষেত্রগুলি পর্দায় প্রদর্শিত হওয়ার জন্য সঠিক ক্রমে রয়েছে৷

রেন্ডার ট্রি নির্মাণের পর এটি একটি " লেআউট " প্রক্রিয়ার মধ্য দিয়ে যায়। এর অর্থ হল প্রতিটি নোডকে সঠিক স্থানাঙ্কগুলি দেওয়া যেখানে এটি পর্দায় উপস্থিত হওয়া উচিত। পরবর্তী ধাপ হল পেইন্টিং - রেন্ডার ট্রিটি ট্রাভার্স করা হবে এবং প্রতিটি নোড UI ব্যাকএন্ড লেয়ার ব্যবহার করে আঁকা হবে।

এটা বোঝা গুরুত্বপূর্ণ যে এটি একটি ধীরে ধীরে প্রক্রিয়া। ভালো ব্যবহারকারীর অভিজ্ঞতার জন্য, রেন্ডারিং ইঞ্জিন যত তাড়াতাড়ি সম্ভব স্ক্রীনে বিষয়বস্তু প্রদর্শন করার চেষ্টা করবে। রেন্ডার ট্রি তৈরি এবং লেআউট শুরু করার আগে সমস্ত HTML পার্স করা পর্যন্ত এটি অপেক্ষা করবে না। বিষয়বস্তুর অংশগুলি পার্স করা হবে এবং প্রদর্শিত হবে, যখন প্রক্রিয়াটি নেটওয়ার্ক থেকে আসা বাকি বিষয়বস্তুর সাথে চলতে থাকবে।

প্রধান প্রবাহ উদাহরণ

ওয়েবকিট প্রধান প্রবাহ।
চিত্র 3: ওয়েবকিট প্রধান প্রবাহ
Mozilla এর Gecko রেন্ডারিং ইঞ্জিন প্রধান প্রবাহ।
চিত্র 4: Mozilla এর Gecko রেন্ডারিং ইঞ্জিন প্রধান প্রবাহ

পরিসংখ্যান 3 এবং 4 থেকে আপনি দেখতে পাচ্ছেন যে যদিও WebKit এবং Gecko সামান্য ভিন্ন পরিভাষা ব্যবহার করে, প্রবাহটি মূলত একই।

গেকো চাক্ষুষরূপে বিন্যাসিত উপাদানের গাছকে "ফ্রেম ট্রি" বলে। প্রতিটি উপাদান একটি ফ্রেম. ওয়েবকিট "রেন্ডার ট্রি" শব্দটি ব্যবহার করে এবং এটি "রেন্ডার অবজেক্ট" নিয়ে গঠিত। ওয়েবকিট উপাদান স্থাপনের জন্য "লেআউট" শব্দটি ব্যবহার করে, যখন গেকো এটিকে "রিফ্লো" বলে। "অ্যাটাচমেন্ট" হল ওয়েবকিটের শব্দ যা DOM নোড এবং ভিজ্যুয়াল ইনফরমেশন সংযোগ করার জন্য রেন্ডার ট্রি তৈরি করার জন্য। একটি ছোট অ-অর্থবোধক পার্থক্য হল যে গেকোর HTML এবং DOM গাছের মধ্যে একটি অতিরিক্ত স্তর রয়েছে। এটিকে "কন্টেন্ট সিঙ্ক" বলা হয় এবং এটি DOM উপাদান তৈরির কারখানা। আমরা প্রবাহের প্রতিটি অংশ সম্পর্কে কথা বলব:

পার্সিং - সাধারণ

যেহেতু পার্সিং রেন্ডারিং ইঞ্জিনের মধ্যে একটি অত্যন্ত তাৎপর্যপূর্ণ প্রক্রিয়া, আমরা এটিতে আরও গভীরভাবে যাব। পার্সিং সম্পর্কে একটু ভূমিকা দিয়ে শুরু করা যাক।

একটি নথি পার্স করা মানে কোডটি ব্যবহার করতে পারে এমন একটি কাঠামোতে এটি অনুবাদ করা। পার্সিংয়ের ফলাফল সাধারণত নোডের একটি গাছ যা নথির গঠনকে প্রতিনিধিত্ব করে। একে পার্স ট্রি বা সিনট্যাক্স ট্রি বলা হয়।

উদাহরণস্বরূপ, এক্সপ্রেশন 2 + 3 - 1 পার্স করা এই ট্রিটি ফিরিয়ে দিতে পারে:

গাণিতিক এক্সপ্রেশন ট্রি নোড।
চিত্র 5: গাণিতিক অভিব্যক্তি ট্রি নোড

ব্যাকরণ

পার্সিং সিনট্যাক্স নিয়মের উপর ভিত্তি করে যা নথিটি মেনে চলে: যে ভাষা বা বিন্যাসে এটি লেখা হয়েছিল। আপনি পার্স করতে পারেন এমন প্রতিটি বিন্যাসে অবশ্যই শব্দভান্ডার এবং বাক্য গঠনের নিয়ম সমন্বিত নির্ধারক ব্যাকরণ থাকতে হবে। একে বলা হয় প্রসঙ্গ মুক্ত ব্যাকরণ । মানুষের ভাষা এই ধরনের ভাষা নয় এবং তাই প্রচলিত পার্সিং কৌশল দিয়ে পার্স করা যায় না।

পার্সার - লেক্সার সংমিশ্রণ

পার্সিংকে দুটি উপ প্রক্রিয়ায় বিভক্ত করা যেতে পারে: আভিধানিক বিশ্লেষণ এবং বাক্য গঠন বিশ্লেষণ।

আভিধানিক বিশ্লেষণ হল ইনপুটকে টোকেনে ভাঙার প্রক্রিয়া। টোকেন হল ভাষার শব্দভাণ্ডার: বৈধ বিল্ডিং ব্লকের সংগ্রহ। মানুষের ভাষায় এটি সেই ভাষার অভিধানে উপস্থিত সমস্ত শব্দ নিয়ে গঠিত।

সিনট্যাক্স বিশ্লেষণ হল ভাষার সিনট্যাক্স নিয়ম প্রয়োগ করা।

পার্সাররা সাধারণত দুটি উপাদানের মধ্যে কাজকে ভাগ করে: লেক্সার (কখনও কখনও টোকেনাইজার বলা হয়) যেটি ইনপুটকে বৈধ টোকেনে ভাঙ্গার জন্য দায়ী এবং পার্সার যেটি ভাষা সিনট্যাক্স নিয়ম অনুসারে নথির কাঠামো বিশ্লেষণ করে পার্স ট্রি তৈরির জন্য দায়ী৷

লেক্সার জানেন কিভাবে সাদা স্পেস এবং লাইন ব্রেক এর মত অপ্রাসঙ্গিক অক্ষর বাদ দিতে হয়।

উৎস নথি থেকে গাছ পার্স
ছবি 6: উৎস নথি থেকে ট্রি পার্স পর্যন্ত

পার্সিং প্রক্রিয়াটি পুনরাবৃত্তিমূলক। পার্সার সাধারণত লেক্সারকে একটি নতুন টোকেনের জন্য জিজ্ঞাসা করবে এবং সিনট্যাক্স নিয়মগুলির একটির সাথে টোকেনটি মেলানোর চেষ্টা করবে। যদি একটি নিয়ম মিলে যায়, টোকেনের সাথে সম্পর্কিত একটি নোড পার্স ট্রিতে যোগ করা হবে এবং পার্সার অন্য টোকেন চাইবে।

যদি কোনো নিয়ম মেলে না, পার্সার অভ্যন্তরীণভাবে টোকেন সংরক্ষণ করবে, এবং অভ্যন্তরীণভাবে সঞ্চিত টোকেনগুলির সাথে মেলে এমন একটি নিয়ম পাওয়া না যাওয়া পর্যন্ত টোকেনগুলির জন্য জিজ্ঞাসা করতে থাকবে৷ যদি কোন নিয়ম না পাওয়া যায় তাহলে পার্সার একটি ব্যতিক্রম উত্থাপন করবে। এর মানে ডকুমেন্টটি বৈধ ছিল না এবং এতে সিনট্যাক্স ত্রুটি ছিল।

অনুবাদ

অনেক ক্ষেত্রে পার্স গাছ চূড়ান্ত পণ্য নয়। পার্সিং প্রায়ই অনুবাদে ব্যবহৃত হয়: ইনপুট নথিকে অন্য বিন্যাসে রূপান্তর করা। একটি উদাহরণ হল সংকলন। যে কম্পাইলারটি সোর্স কোডকে মেশিন কোডে কম্পাইল করে সেটি প্রথমে পার্স ট্রিতে পার্স করে এবং তারপর ট্রিটিকে মেশিন কোড ডকুমেন্টে অনুবাদ করে।

সংকলন প্রবাহ
চিত্র 7: সংকলন প্রবাহ

পার্সিং উদাহরণ

চিত্র 5 এ আমরা একটি গাণিতিক অভিব্যক্তি থেকে একটি পার্স গাছ তৈরি করেছি। আসুন একটি সহজ গাণিতিক ভাষা সংজ্ঞায়িত করার চেষ্টা করি এবং পার্স প্রক্রিয়াটি দেখি।

বাক্য গঠন:

  1. ভাষার সিনট্যাক্স বিল্ডিং ব্লক হল এক্সপ্রেশন, টার্ম এবং অপারেশন।
  2. আমাদের ভাষা যেকোন সংখ্যক অভিব্যক্তি অন্তর্ভুক্ত করতে পারে।
  3. একটি অভিব্যক্তি একটি "টার্ম" হিসাবে সংজ্ঞায়িত করা হয় একটি "অপারেশন" দ্বারা অনুসরণ করে অন্য একটি শব্দ
  4. একটি অপারেশন একটি প্লাস টোকেন বা একটি বিয়োগ টোকেন
  5. একটি শব্দ একটি পূর্ণসংখ্যা টোকেন বা একটি অভিব্যক্তি

আসুন ইনপুট 2 + 3 - 1 বিশ্লেষণ করি।

একটি নিয়মের সাথে মেলে প্রথম সাবস্ট্রিং হল 2 : নিয়ম #5 অনুসারে এটি একটি শব্দ। দ্বিতীয় মিলটি হল 2 + 3 : এটি তৃতীয় নিয়মের সাথে মেলে: একটি শব্দের পরে একটি অপারেশন এবং অন্য একটি পদ অনুসরণ করে৷ পরবর্তী ম্যাচ শুধুমাত্র ইনপুট শেষে আঘাত করা হবে. 2 + 3 - 1 একটি অভিব্যক্তি কারণ আমরা ইতিমধ্যেই জানি যে 2 + 3 একটি পদ, তাই আমাদের কাছে একটি শব্দ আছে একটি অপারেশন দ্বারা অনুসরণ করে অন্য একটি পদ। 2 + + কোনো নিয়মের সাথে মেলে না এবং তাই এটি একটি অবৈধ ইনপুট।

শব্দভান্ডার এবং বাক্য গঠনের জন্য আনুষ্ঠানিক সংজ্ঞা

শব্দভান্ডার সাধারণত নিয়মিত অভিব্যক্তি দ্বারা প্রকাশ করা হয়।

উদাহরণস্বরূপ আমাদের ভাষা সংজ্ঞায়িত করা হবে:

INTEGER: 0|[1-9][0-9]*
PLUS: +
MINUS: -

আপনি দেখতে পাচ্ছেন, পূর্ণসংখ্যা একটি নিয়মিত অভিব্যক্তি দ্বারা সংজ্ঞায়িত করা হয়।

সিনট্যাক্স সাধারণত BNF নামে একটি বিন্যাসে সংজ্ঞায়িত করা হয়। আমাদের ভাষা এইভাবে সংজ্ঞায়িত করা হবে:

expression :=  term  operation  term
operation :=  PLUS | MINUS
term := INTEGER | expression

আমরা বলেছিলাম যে একটি ভাষা নিয়মিত পার্সার দ্বারা পার্স করা যেতে পারে যদি এর ব্যাকরণ একটি প্রসঙ্গ মুক্ত ব্যাকরণ হয়। একটি প্রসঙ্গ মুক্ত ব্যাকরণের একটি স্বজ্ঞাত সংজ্ঞা হল একটি ব্যাকরণ যা সম্পূর্ণরূপে বিএনএফ-এ প্রকাশ করা যেতে পারে। একটি আনুষ্ঠানিক সংজ্ঞার জন্য উইকিপিডিয়ার প্রসঙ্গ-মুক্ত ব্যাকরণের নিবন্ধটি দেখুন

পার্সারের প্রকারভেদ

দুই ধরনের পার্সার আছে: টপ ডাউন পার্সার এবং বটম আপ পার্সার। একটি স্বজ্ঞাত ব্যাখ্যা হল যে টপ ডাউন পার্সাররা সিনট্যাক্সের উচ্চ স্তরের কাঠামো পরীক্ষা করে এবং একটি নিয়মের মিল খুঁজে বের করার চেষ্টা করে। বটম আপ পার্সার ইনপুট দিয়ে শুরু করে এবং ধীরে ধীরে এটিকে সিনট্যাক্স নিয়মে রূপান্তরিত করে, নিম্ন স্তরের নিয়ম থেকে শুরু করে উচ্চ স্তরের নিয়মগুলি পূরণ না হওয়া পর্যন্ত।

আসুন দেখি কিভাবে দুই ধরনের পার্সার আমাদের উদাহরণটি পার্স করবে।

টপ ডাউন পার্সার উচ্চ স্তরের নিয়ম থেকে শুরু হবে: এটি 2 + 3 একটি অভিব্যক্তি হিসাবে চিহ্নিত করবে। এটি তখন 2 + 3 - 1 কে একটি অভিব্যক্তি হিসাবে চিহ্নিত করবে (অভিব্যক্তি সনাক্ত করার প্রক্রিয়াটি বিকশিত হয়, অন্যান্য নিয়মের সাথে মিলে যায়, তবে শুরুর বিন্দুটি সর্বোচ্চ স্তরের নিয়ম)।

একটি নিয়ম মেলে না হওয়া পর্যন্ত নীচের উপরের পার্সার ইনপুটটি স্ক্যান করবে। এটি তারপর নিয়মের সাথে মিলিত ইনপুট প্রতিস্থাপন করবে। ইনপুট শেষ না হওয়া পর্যন্ত এটি চলতে থাকবে। আংশিকভাবে মিলে যাওয়া অভিব্যক্তিটি পার্সারের স্ট্যাকের উপর স্থাপন করা হয়।

স্ট্যাক ইনপুট
2 + 3 - 1
মেয়াদ + 3 - 1
মেয়াদী অপারেশন 3 - 1
অভিব্যক্তি - ১
অভিব্যক্তি অপারেশন 1
অভিব্যক্তি -

এই ধরনের বটম আপ পার্সারকে শিফট-রিডুস পার্সার বলা হয়, কারণ ইনপুটটি ডানদিকে স্থানান্তরিত হয় (কল্পনা করুন একটি পয়েন্টার ইনপুট শুরুতে প্রথমে নির্দেশ করে এবং ডানদিকে চলে যায়) এবং ধীরে ধীরে সিনট্যাক্স নিয়মে হ্রাস করা হয়।

স্বয়ংক্রিয়ভাবে পার্সার তৈরি করা হচ্ছে

এমন সরঞ্জাম রয়েছে যা একটি পার্সার তৈরি করতে পারে। আপনি তাদের আপনার ভাষার ব্যাকরণ - এর শব্দভান্ডার এবং বাক্য গঠনের নিয়মগুলি খাওয়ান - এবং তারা একটি কার্যকরী পার্সার তৈরি করে৷ একটি পার্সার তৈরি করার জন্য পার্সিংয়ের গভীর বোঝার প্রয়োজন এবং এটি হাতে একটি অপ্টিমাইজ করা পার্সার তৈরি করা সহজ নয়, তাই পার্সার জেনারেটরগুলি খুব দরকারী হতে পারে।

ওয়েবকিট দুটি সুপরিচিত পার্সার জেনারেটর ব্যবহার করে: একটি লেক্সার তৈরির জন্য ফ্লেক্স এবং একটি পার্সার তৈরি করার জন্য বাইসন (আপনি লেক্স এবং ইয়াক নাম দিয়ে তাদের মধ্যে দৌড়াতে পারেন)। ফ্লেক্স ইনপুট হল একটি ফাইল যাতে টোকেনের রেগুলার এক্সপ্রেশন সংজ্ঞা থাকে। বাইসন এর ইনপুট হল BNF বিন্যাসে ভাষার সিনট্যাক্স নিয়ম।

এইচটিএমএল পার্সার

HTML পার্সারের কাজ হল HTML মার্কআপকে পার্স ট্রিতে পার্স করা।

এইচটিএমএল ব্যাকরণ

HTML এর শব্দভান্ডার এবং সিনট্যাক্স W3C সংস্থা দ্বারা তৈরি স্পেসিফিকেশনে সংজ্ঞায়িত করা হয়েছে।

আমরা পার্সিং ভূমিকাতে দেখেছি, BNF এর মত বিন্যাস ব্যবহার করে ব্যাকরণ বাক্য গঠনকে আনুষ্ঠানিকভাবে সংজ্ঞায়িত করা যেতে পারে।

দুর্ভাগ্যবশত সমস্ত প্রচলিত পার্সার বিষয় এইচটিএমএল-এ প্রযোজ্য নয় (আমি এগুলিকে শুধুমাত্র মজা করার জন্য আনিনি - সেগুলি CSS এবং JavaScript পার্সিংয়ে ব্যবহার করা হবে)। এইচটিএমএল সহজে একটি প্রসঙ্গ মুক্ত ব্যাকরণ দ্বারা সংজ্ঞায়িত করা যায় না যা পার্সারদের প্রয়োজন।

এইচটিএমএল - ডিটিডি (ডকুমেন্ট টাইপ ডেফিনিশন) সংজ্ঞায়িত করার জন্য একটি আনুষ্ঠানিক বিন্যাস রয়েছে - তবে এটি একটি প্রসঙ্গ মুক্ত ব্যাকরণ নয়।

এটি প্রথম দর্শনে অদ্ভুত বলে মনে হয়; এইচটিএমএল বরং XML এর কাছাকাছি। প্রচুর এক্সএমএল পার্সার আছে। এইচটিএমএল - এক্সএইচটিএমএল - এর একটি এক্সএমএল প্রকরণ রয়েছে - তাই বড় পার্থক্য কী?

পার্থক্য হল যে এইচটিএমএল পদ্ধতিটি আরও "ক্ষমাকারী": এটি আপনাকে নির্দিষ্ট ট্যাগগুলি বাদ দিতে দেয় (যা পরে নিহিতভাবে যোগ করা হয়), বা কখনও কখনও শুরু বা শেষ ট্যাগগুলি বাদ দিতে দেয় এবং আরও অনেক কিছু। মোটের উপর এটি একটি "নরম" সিনট্যাক্স, XML এর কঠোর এবং দাবিকৃত সিনট্যাক্সের বিপরীতে।

এই আপাতদৃষ্টিতে ছোট বিশদটি একটি পার্থক্যের বিশ্ব তৈরি করে। একদিকে এটি HTML এত জনপ্রিয় হওয়ার মূল কারণ: এটি আপনার ভুলগুলি ক্ষমা করে এবং ওয়েব লেখকের জীবনকে সহজ করে তোলে৷ অন্যদিকে, এটি একটি আনুষ্ঠানিক ব্যাকরণ লিখতে কঠিন করে তোলে। তাই সংক্ষেপে বলতে গেলে, প্রচলিত পার্সারের দ্বারা HTML সহজে পার্স করা যায় না, যেহেতু এর ব্যাকরণ প্রসঙ্গ মুক্ত নয়। XML পার্সারের দ্বারা HTML পার্স করা যাবে না।

এইচটিএমএল ডিটিডি

এইচটিএমএল সংজ্ঞা একটি DTD বিন্যাসে হয়. এই বিন্যাসটি SGML পরিবারের ভাষা সংজ্ঞায়িত করতে ব্যবহৃত হয়। বিন্যাসে সমস্ত অনুমোদিত উপাদান, তাদের বৈশিষ্ট্য এবং অনুক্রমের সংজ্ঞা রয়েছে। আমরা আগে দেখেছি, HTML DTD একটি প্রসঙ্গ মুক্ত ব্যাকরণ গঠন করে না।

DTD এর কয়েকটি বৈচিত্র রয়েছে। কঠোর মোড শুধুমাত্র নির্দিষ্টকরণের সাথে সামঞ্জস্যপূর্ণ কিন্তু অন্যান্য মোডগুলি অতীতে ব্রাউজারদের দ্বারা ব্যবহৃত মার্কআপের জন্য সমর্থন ধারণ করে। উদ্দেশ্য পুরানো বিষয়বস্তুর সাথে পিছনের সামঞ্জস্য। বর্তমান কঠোর DTD এখানে: www.w3.org/TR/html4/strict.dtd

DOM

আউটপুট ট্রি ("পার্স ট্রি") হল DOM এলিমেন্ট এবং অ্যাট্রিবিউট নোডের একটি ট্রি। ডকুমেন্ট অবজেক্ট মডেলের জন্য DOM সংক্ষিপ্ত। এটি হল এইচটিএমএল ডকুমেন্টের অবজেক্ট প্রেজেন্টেশন এবং জাভাস্ক্রিপ্টের মত বাইরের জগতে এইচটিএমএল উপাদানগুলির ইন্টারফেস।

গাছের মূল হল " ডকুমেন্ট " অবজেক্ট।

মার্কআপের সাথে DOM-এর প্রায় এক-এক সম্পর্ক রয়েছে। উদাহরণ স্বরূপ:

<html>
  <body>
    <p>
      Hello World
    </p>
    <div> <img src="example.png"/></div>
  </body>
</html>

এই মার্কআপটি নিম্নলিখিত DOM ট্রিতে অনুবাদ করা হবে:

উদাহরণ মার্কআপের DOM গাছ
চিত্র 8: উদাহরণ মার্কআপের DOM গাছ

HTML এর মত, DOM W3C সংস্থা দ্বারা নির্দিষ্ট করা হয়। www.w3.org/DOM/DOMTR দেখুন। এটি নথিগুলি হেরফের করার জন্য একটি জেনেরিক স্পেসিফিকেশন। একটি নির্দিষ্ট মডিউল HTML নির্দিষ্ট উপাদান বর্ণনা করে। HTML সংজ্ঞা এখানে পাওয়া যাবে: www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109/idl-definitions.html

যখন আমি বলি গাছটিতে DOM নোড রয়েছে, আমি বলতে চাচ্ছি যে গাছটি এমন উপাদান দিয়ে তৈরি করা হয়েছে যা DOM ইন্টারফেসগুলির একটিকে বাস্তবায়ন করে। ব্রাউজারগুলি অভ্যন্তরীণভাবে ব্রাউজার দ্বারা ব্যবহৃত অন্যান্য বৈশিষ্ট্য রয়েছে এমন কংক্রিট বাস্তবায়ন ব্যবহার করে।

পার্সিং অ্যালগরিদম

আমরা পূর্ববর্তী বিভাগে দেখেছি, নিয়মিত টপ ডাউন বা বটম আপ পার্সার ব্যবহার করে HTML পার্স করা যায় না।

কারণগুলি হল:

  1. ভাষার ক্ষমাশীল প্রকৃতি।
  2. অবৈধ HTML এর সুপরিচিত ক্ষেত্রে সমর্থন করার জন্য ব্রাউজারগুলির ঐতিহ্যগত ত্রুটি সহনশীলতা রয়েছে।
  3. পার্সিং প্রক্রিয়াটি পুনঃপ্রবেশকারী। অন্যান্য ভাষার জন্য, পার্সিংয়ের সময় উৎস পরিবর্তন হয় না, কিন্তু HTML-এ, ডাইনামিক কোড (যেমন document.write() কল সম্বলিত স্ক্রিপ্ট উপাদান) অতিরিক্ত টোকেন যোগ করতে পারে, তাই পার্সিং প্রক্রিয়া আসলে ইনপুট পরিবর্তন করে।

নিয়মিত পার্সিং কৌশল ব্যবহার করতে অক্ষম, ব্রাউজার HTML পার্স করার জন্য কাস্টম পার্সার তৈরি করে।

পার্সিং অ্যালগরিদম HTML5 স্পেসিফিকেশন দ্বারা বিশদভাবে বর্ণনা করা হয়েছে । অ্যালগরিদম দুটি পর্যায় নিয়ে গঠিত: টোকেনাইজেশন এবং গাছ নির্মাণ।

টোকেনাইজেশন হল আভিধানিক বিশ্লেষণ, ইনপুটকে টোকেনে পার্স করা। এইচটিএমএল টোকেনের মধ্যে রয়েছে স্টার্ট ট্যাগ, এন্ড ট্যাগ, অ্যাট্রিবিউটের নাম এবং অ্যাট্রিবিউটের মান।

টোকেনাইজার টোকেনটি চিনতে পারে, এটি ট্রি কনস্ট্রাক্টরকে দেয় এবং পরবর্তী টোকেনটি সনাক্ত করার জন্য পরবর্তী অক্ষরটি গ্রহণ করে এবং ইনপুট শেষ না হওয়া পর্যন্ত।

HTML পার্সিং ফ্লো (HTML5 স্পেক থেকে নেওয়া)
চিত্র 9: এইচটিএমএল পার্সিং ফ্লো (HTML5 স্পেক থেকে নেওয়া)

টোকেনাইজেশন অ্যালগরিদম

অ্যালগরিদমের আউটপুট একটি HTML টোকেন। অ্যালগরিদম একটি রাষ্ট্র মেশিন হিসাবে প্রকাশ করা হয়. প্রতিটি স্টেট ইনপুট স্ট্রীমের এক বা একাধিক অক্ষর গ্রহণ করে এবং সেই অক্ষর অনুযায়ী পরবর্তী অবস্থা আপডেট করে। সিদ্ধান্তটি বর্তমান টোকেনাইজেশন অবস্থা এবং গাছ নির্মাণের অবস্থা দ্বারা প্রভাবিত হয়। এর মানে বর্তমান অবস্থার উপর নির্ভর করে সঠিক পরবর্তী অবস্থার জন্য একই ব্যবহার করা অক্ষর বিভিন্ন ফলাফল দেবে। অ্যালগরিদম সম্পূর্ণরূপে বর্ণনা করার জন্য খুবই জটিল, তাই আসুন একটি সাধারণ উদাহরণ দেখি যা আমাদের নীতিটি বুঝতে সাহায্য করবে।

মৌলিক উদাহরণ - নিম্নলিখিত HTML টোকেনাইজ করা:

<html>
  <body>
    Hello world
  </body>
</html>

প্রাথমিক অবস্থা হল "ডেটা স্টেট"। যখন < অক্ষরটির সম্মুখীন হয়, তখন অবস্থাটি "ট্যাগ ওপেন স্টেট" এ পরিবর্তিত হয়। একটি az অক্ষর ব্যবহার করার ফলে একটি "স্টার্ট ট্যাগ টোকেন" তৈরি হয়, অবস্থাটি "ট্যাগ নেম স্টেট" এ পরিবর্তিত হয়। > অক্ষরটি গ্রাস না হওয়া পর্যন্ত আমরা এই অবস্থায় থাকি। প্রতিটি অক্ষর নতুন টোকেন নামের সাথে যুক্ত করা হয়। আমাদের ক্ষেত্রে তৈরি টোকেন একটি html টোকেন।

যখন > ট্যাগ পৌঁছে যায়, তখন বর্তমান টোকেন নির্গত হয় এবং অবস্থা আবার "ডেটা স্টেট" -এ পরিবর্তিত হয়। <body> ট্যাগটিকে একই ধাপে বিবেচনা করা হবে। এ পর্যন্ত html এবং body ট্যাগ নির্গত হয়েছে। আমরা এখন "ডেটা স্টেট" এ ফিরে এসেছি। Hello world H অক্ষর ব্যবহার করলে একটি অক্ষর টোকেন তৈরি এবং নির্গত হবে, এটি < এর </body> না হওয়া পর্যন্ত চলবে। আমরা Hello world প্রতিটি চরিত্রের জন্য একটি অক্ষর টোকেন নির্গত করব।

আমরা এখন "ট্যাগ ওপেন স্টেট" এ ফিরে এসেছি। পরবর্তী ইনপুট গ্রহণ করা / একটি end tag token তৈরি করবে এবং "ট্যাগ নাম রাজ্য" এ চলে যাবে। আবার আমরা এই অবস্থায় থাকি যতক্ষণ না আমরা > পৌঁছাই। তারপর নতুন ট্যাগ টোকেন নির্গত হবে এবং আমরা "ডেটা স্টেটে" ফিরে যাই। </html> ইনপুটটিকে আগের কেসের মতোই বিবেচনা করা হবে।

উদাহরণ ইনপুট টোকেনাইজিং
চিত্র 10: উদাহরণ ইনপুট টোকেনাইজ করা

গাছ নির্মাণ অ্যালগরিদম

যখন পার্সার তৈরি করা হয় তখন ডকুমেন্ট অবজেক্ট তৈরি হয়। গাছ নির্মাণের পর্যায়ে ডকুমেন্টের মূলে থাকা DOM গাছটিকে পরিবর্তন করা হবে এবং এতে উপাদান যোগ করা হবে। টোকেনাইজার দ্বারা নির্গত প্রতিটি নোড ট্রি কনস্ট্রাক্টর দ্বারা প্রক্রিয়া করা হবে। প্রতিটি টোকেনের জন্য স্পেসিফিকেশন নির্ধারণ করে যে কোন DOM উপাদান এটির সাথে প্রাসঙ্গিক এবং এই টোকেনের জন্য তৈরি করা হবে। উপাদানটি DOM ট্রিতে যোগ করা হয়, এবং খোলা উপাদানগুলির স্ট্যাকও। এই স্ট্যাকটি নেস্টিং অমিল এবং আনক্লোজড ট্যাগগুলি সংশোধন করতে ব্যবহৃত হয়। অ্যালগরিদম একটি রাষ্ট্র মেশিন হিসাবে বর্ণনা করা হয়. রাজ্যগুলিকে "সন্নিবেশ মোড" বলা হয়।

উদাহরণ ইনপুট জন্য গাছ নির্মাণ প্রক্রিয়া দেখুন:

<html>
  <body>
    Hello world
  </body>
</html>

গাছ নির্মাণ পর্যায়ে ইনপুট হল টোকেনাইজেশন পর্যায় থেকে টোকেনের একটি ক্রম। প্রথম মোড হল "প্রাথমিক মোড" । "html" টোকেন প্রাপ্তির ফলে "html" মোডে সরানো হবে এবং সেই মোডে টোকেন পুনঃপ্রসেস করা হবে। এর ফলে HTMLHtmlElement এলিমেন্ট তৈরি হবে, যা রুট ডকুমেন্ট অবজেক্টে যুক্ত হবে।

রাষ্ট্র পরিবর্তন করা হবে "মাথার আগে" । তারপর "শরীর" টোকেন প্রাপ্ত হয়। একটি HTMLHeadElement অন্তর্নিহিতভাবে তৈরি করা হবে যদিও আমাদের কাছে "হেড" টোকেন নেই এবং এটি গাছে যোগ করা হবে।

আমরা এখন "ইন হেড" মোডে এবং তারপরে "আফটার হেড" এ চলে যাই। বডি টোকেন পুনঃপ্রসেস করা হয়, একটি HTMLBodyElement তৈরি করা হয় এবং সন্নিবেশ করা হয় এবং মোডটি "ইন বডি" এ স্থানান্তরিত হয়।

"হ্যালো ওয়ার্ল্ড" স্ট্রিংয়ের অক্ষর টোকেনগুলি এখন প্রাপ্ত হয়েছে৷ প্রথমটি একটি "টেক্সট" নোড তৈরি এবং সন্নিবেশ ঘটাবে এবং অন্যান্য অক্ষরগুলি সেই নোডে যুক্ত করা হবে।

বডি এন্ড টোকেন প্রাপ্তির ফলে "আফটার বডি" মোডে স্থানান্তরিত হবে। আমরা এখন html শেষ ট্যাগ পাব যা আমাদেরকে "আফটার আফটার বডি" মোডে নিয়ে যাবে। ফাইল টোকেনের শেষ প্রাপ্তি পার্সিং শেষ হবে।

উদাহরণ এইচটিএমএল এর গাছ নির্মাণ.
চিত্র 11: উদাহরণ html এর গাছ নির্মাণ

পার্সিং শেষ হলে অ্যাকশন

এই পর্যায়ে ব্রাউজার নথিটিকে ইন্টারেক্টিভ হিসাবে চিহ্নিত করবে এবং "বিলম্বিত" মোডে থাকা স্ক্রিপ্টগুলিকে পার্সিং শুরু করবে: যেগুলি নথিটি পার্স করার পরে কার্যকর করা উচিত৷ নথির অবস্থা তারপর "সম্পূর্ণ" সেট করা হবে এবং একটি "লোড" ইভেন্ট ফায়ার করা হবে।

আপনি HTML5 স্পেসিফিকেশনে টোকেনাইজেশন এবং ট্রি নির্মাণের জন্য সম্পূর্ণ অ্যালগরিদম দেখতে পারেন।

ব্রাউজারের ত্রুটি সহনশীলতা

আপনি কখনই একটি HTML পৃষ্ঠায় একটি "অবৈধ সিনট্যাক্স" ত্রুটি পাবেন না৷ ব্রাউজার কোন অবৈধ বিষয়বস্তু ঠিক করে এবং চালিয়ে যান।

উদাহরণস্বরূপ এই HTML নিন:

<html>
  <mytag>
  </mytag>
  <div>
  <p>
  </div>
    Really lousy HTML
  </p>
</html>

আমি অবশ্যই প্রায় এক মিলিয়ন নিয়ম লঙ্ঘন করেছি ("mytag" একটি আদর্শ ট্যাগ নয়, "p" এবং "div" উপাদানগুলির ভুল নেস্টিং এবং আরও অনেক কিছু) কিন্তু ব্রাউজার এখনও এটি সঠিকভাবে দেখায় এবং অভিযোগ করে না৷ তাই পার্সার কোড অনেক HTML লেখক ভুল সংশোধন করা হয়.

ত্রুটি হ্যান্ডলিং ব্রাউজারে বেশ সামঞ্জস্যপূর্ণ, কিন্তু আশ্চর্যজনকভাবে এটি HTML স্পেসিফিকেশনের অংশ নয়। বুকমার্কিং এবং ব্যাক/ফরোয়ার্ড বোতামের মতো এটি এমন কিছু যা ব্রাউজারে বছরের পর বছর ধরে উন্নত হয়েছে। অনেক সাইটে বারবার অকার্যকর এইচটিএমএল কনস্ট্রাক্ট রয়েছে এবং ব্রাউজারগুলি অন্য ব্রাউজারগুলির সাথে সামঞ্জস্যপূর্ণ উপায়ে সেগুলি ঠিক করার চেষ্টা করে৷

HTML5 স্পেসিফিকেশন এই প্রয়োজনীয়তাগুলির কিছু সংজ্ঞায়িত করে। (ওয়েবকিট এইচটিএমএল পার্সার ক্লাসের শুরুতে মন্তব্যে এটিকে সুন্দরভাবে সংক্ষিপ্ত করে।)

পার্সার নথিতে টোকেনাইজড ইনপুট পার্স করে, ডকুমেন্ট ট্রি তৈরি করে। যদি নথিটি সুগঠিত হয় তবে এটিকে পার্স করা সহজ।

দুর্ভাগ্যবশত, আমাদের অনেক এইচটিএমএল ডকুমেন্ট পরিচালনা করতে হবে যা সুগঠিত নয়, তাই পার্সারকে ত্রুটির বিষয়ে সহনশীল হতে হবে।

আমাদের কমপক্ষে নিম্নলিখিত ত্রুটি শর্তগুলির যত্ন নিতে হবে:

  1. যে উপাদানটি যোগ করা হচ্ছে তা কিছু বাইরের ট্যাগের ভিতরে স্পষ্টভাবে নিষিদ্ধ। এই ক্ষেত্রে আমাদের সমস্ত ট্যাগ বন্ধ করা উচিত যা উপাদানটিকে নিষিদ্ধ করে এবং পরে এটি যোগ করে।
  2. আমরা সরাসরি উপাদান যোগ করার অনুমতি দেওয়া হয় না. এটা হতে পারে যে নথিটি লিখছেন এমন ব্যক্তি এর মধ্যে কিছু ট্যাগ ভুলে গেছেন (বা এর মধ্যে ট্যাগটি ঐচ্ছিক)। নিম্নলিখিত ট্যাগগুলির ক্ষেত্রে এটি হতে পারে: HTML HEAD BODY TBODY TR TD LI (আমি কি ভুলে গেছি?)।
  3. আমরা একটি ইনলাইন উপাদানের ভিতরে একটি ব্লক উপাদান যোগ করতে চাই। পরবর্তী উচ্চতর ব্লক উপাদান পর্যন্ত সমস্ত ইনলাইন উপাদান বন্ধ করুন।
  4. যদি এটি সাহায্য না করে, আমাদের উপাদান যোগ করার অনুমতি না দেওয়া পর্যন্ত উপাদান বন্ধ করুন - বা ট্যাগ উপেক্ষা করুন।

আসুন কিছু WebKit ত্রুটি সহনশীলতার উদাহরণ দেখি:

<br> এর পরিবর্তে </br>

কিছু সাইট <br> এর পরিবর্তে </br> ব্যবহার করে। IE এবং Firefox-এর সাথে সামঞ্জস্যপূর্ণ হওয়ার জন্য, WebKit এটিকে <br> এর মত ব্যবহার করে।

কোড:

if (t->isCloseTag(brTag) && m_document->inCompatMode()) {
     reportError(MalformedBRError);
     t->beginTag = true;
}

মনে রাখবেন যে ত্রুটি হ্যান্ডলিং অভ্যন্তরীণ: এটি ব্যবহারকারীর কাছে উপস্থাপন করা হবে না।

একটি বিপথগামী টেবিল

একটি স্ট্রে টেবিল অন্য টেবিলের ভিতরে একটি টেবিল, কিন্তু একটি টেবিল ঘরের ভিতরে নয়।

উদাহরণ স্বরূপ:

<table>
  <table>
    <tr><td>inner table</td></tr>
  </table>
  <tr><td>outer table</td></tr>
</table>

WebKit অনুক্রম দুটি ভাইবোন টেবিলে পরিবর্তন করবে:

<table>
  <tr><td>outer table</td></tr>
</table>
<table>
  <tr><td>inner table</td></tr>
</table>

কোড:

if (m_inStrayTableContent && localName == tableTag)
        popBlock(tableTag);

ওয়েবকিট বর্তমান উপাদান বিষয়বস্তুর জন্য একটি স্ট্যাক ব্যবহার করে: এটি বাইরের টেবিল স্ট্যাকের বাইরের টেবিলটি পপ করবে। টেবিল এখন ভাইবোন হবে.

নেস্টেড ফর্ম উপাদান

যদি ব্যবহারকারী অন্য ফর্মের ভিতরে একটি ফর্ম রাখে, দ্বিতীয় ফর্মটি উপেক্ষা করা হয়।

কোড:

if (!m_currentFormElement) {
        m_currentFormElement = new HTMLFormElement(formTag,    m_document);
}

একটি খুব গভীর ট্যাগ অনুক্রম

মন্তব্য নিজেই জন্য কথা বলে.

bool HTMLParser::allowNestedRedundantTag(const AtomicString& tagName)
{

unsigned i = 0;
for (HTMLStackElem* curr = m_blockStack;
         i < cMaxRedundantTagDepth && curr && curr->tagName == tagName;
     curr = curr->next, i++) { }
return i != cMaxRedundantTagDepth;
}

ভুল এইচটিএমএল বা বডি এন্ড ট্যাগ

আবার - মন্তব্য নিজের জন্য কথা বলে।

if (t->tagName == htmlTag || t->tagName == bodyTag )
        return;

তাই ওয়েব লেখকরা সতর্ক থাকুন - যদি না আপনি একটি ওয়েবকিট ত্রুটি সহনশীলতা কোড স্নিপেটে একটি উদাহরণ হিসাবে উপস্থিত হতে চান - ভালভাবে গঠিত HTML লিখুন৷

CSS পার্সিং

ভূমিকায় পার্সিং ধারণাগুলি মনে রাখবেন? ঠিক আছে, HTML এর বিপরীতে, CSS হল একটি প্রসঙ্গ মুক্ত ব্যাকরণ এবং ভূমিকায় বর্ণিত পার্সারের প্রকারগুলি ব্যবহার করে পার্স করা যেতে পারে। আসলে CSS স্পেসিফিকেশন CSS আভিধানিক এবং সিনট্যাক্স ব্যাকরণকে সংজ্ঞায়িত করে

আসুন কিছু উদাহরণ দেখি:

আভিধানিক ব্যাকরণ (শব্দভান্ডার) প্রতিটি টোকেনের জন্য নিয়মিত অভিব্যক্তি দ্বারা সংজ্ঞায়িত করা হয়:

comment   \/\*[^*]*\*+([^/*][^*]*\*+)*\/
num       [0-9]+|[0-9]*"."[0-9]+
nonascii  [\200-\377]
nmstart   [_a-z]|{nonascii}|{escape}
nmchar    [_a-z0-9-]|{nonascii}|{escape}
name      {nmchar}+
ident     {nmstart}{nmchar}*

"ident" শনাক্তকারীর জন্য সংক্ষিপ্ত, যেমন একটি শ্রেণীর নাম। "নাম" হল একটি উপাদান আইডি (যেটি "#" দ্বারা উল্লেখ করা হয়)

সিনট্যাক্স ব্যাকরণ বিএনএফ-এ বর্ণিত হয়েছে।

ruleset
  : selector [ ',' S* selector ]*
    '{' S* declaration [ ';' S* declaration ]* '}' S*
  ;
selector
  : simple_selector [ combinator selector | S+ [ combinator? selector ]? ]?
  ;
simple_selector
  : element_name [ HASH | class | attrib | pseudo ]*
  | [ HASH | class | attrib | pseudo ]+
  ;
class
  : '.' IDENT
  ;
element_name
  : IDENT | '*'
  ;
attrib
  : '[' S* IDENT S* [ [ '=' | INCLUDES | DASHMATCH ] S*
    [ IDENT | STRING ] S* ] ']'
  ;
pseudo
  : ':' [ IDENT | FUNCTION S* [IDENT S*] ')' ]
  ;

ব্যাখ্যা:

একটি নিয়ম সেট এই কাঠামো:

div.error, a.error {
  color:red;
  font-weight:bold;
}

div.error এবং a.error হল নির্বাচক। কোঁকড়া ধনুর্বন্ধনীর ভিতরের অংশে এই নিয়ম সেট দ্বারা প্রয়োগ করা নিয়ম রয়েছে। এই কাঠামোটি এই সংজ্ঞায় আনুষ্ঠানিকভাবে সংজ্ঞায়িত করা হয়েছে:

ruleset
  : selector [ ',' S* selector ]*
    '{' S* declaration [ ';' S* declaration ]* '}' S*
  ;

এর মানে হল একটি রুলসেট হল একটি নির্বাচক বা ঐচ্ছিকভাবে একটি কমা এবং স্পেস (S মানে হোয়াইট স্পেস) দ্বারা বিভক্ত একাধিক নির্বাচক। একটি রুলসেটে কোঁকড়া ধনুর্বন্ধনী থাকে এবং তাদের ভিতরে একটি ঘোষণা বা ঐচ্ছিকভাবে একটি সেমিকোলন দ্বারা পৃথক করা অনেকগুলি ঘোষণা থাকে। "ঘোষণা" এবং "নির্বাচক" নিম্নলিখিত BNF সংজ্ঞাগুলিতে সংজ্ঞায়িত করা হবে।

ওয়েবকিট সিএসএস পার্সার

ওয়েবকিট CSS ব্যাকরণ ফাইল থেকে স্বয়ংক্রিয়ভাবে পার্সার তৈরি করতে ফ্লেক্স এবং বাইসন পার্সার জেনারেটর ব্যবহার করে। যেমন আপনি পার্সার ভূমিকা থেকে স্মরণ করছেন, বাইসন একটি বটম আপ শিফট-রিডুস পার্সার তৈরি করে। ফায়ারফক্স ম্যানুয়ালি লেখা একটি টপ ডাউন পার্সার ব্যবহার করে। উভয় ক্ষেত্রেই প্রতিটি CSS ফাইল একটি স্টাইলশিট অবজেক্টে পার্স করা হয়। প্রতিটি বস্তুতে CSS নিয়ম রয়েছে। সিএসএস নিয়ম অবজেক্টে সিলেক্টর এবং ডিক্লেয়ারেশন অবজেক্ট এবং সিএসএস ব্যাকরণের সাথে সম্পর্কিত অন্যান্য অবজেক্ট থাকে।

CSS পার্সিং।
চিত্র 12: CSS পার্সিং

স্ক্রিপ্ট এবং শৈলী শীট জন্য আদেশ প্রক্রিয়াকরণ

স্ক্রিপ্ট

ওয়েবের মডেলটি সিঙ্ক্রোনাস। লেখকরা আশা করেন স্ক্রিপ্টগুলি পার্স করা হবে এবং অবিলম্বে পার্সার একটি <script> ট্যাগে পৌঁছাবে। স্ক্রিপ্টটি কার্যকর না হওয়া পর্যন্ত নথির পার্সিং বন্ধ হয়ে যায়। যদি স্ক্রিপ্টটি বাহ্যিক হয় তবে সংস্থানটি প্রথমে নেটওয়ার্ক থেকে আনতে হবে - এটিও সিঙ্ক্রোনাসভাবে করা হয়, এবং সম্পদ আনা না হওয়া পর্যন্ত পার্সিং বন্ধ থাকে। এটি বহু বছর ধরে মডেল ছিল এবং এটি HTML4 এবং 5 স্পেসিফিকেশনেও উল্লেখ করা হয়েছে। লেখকরা একটি স্ক্রিপ্টে "defer" অ্যাট্রিবিউট যোগ করতে পারেন, এই ক্ষেত্রে এটি ডকুমেন্ট পার্সিং বন্ধ করবে না এবং ডকুমেন্ট পার্স করার পরে এক্সিকিউট করবে। HTML5 স্ক্রিপ্টটিকে অ্যাসিঙ্ক্রোনাস হিসাবে চিহ্নিত করার জন্য একটি বিকল্প যোগ করে যাতে এটি একটি ভিন্ন থ্রেড দ্বারা পার্স এবং কার্যকর করা হবে।

অনুমানমূলক পার্সিং

ওয়েবকিট এবং ফায়ারফক্স উভয়ই এই অপ্টিমাইজেশনটি করে। স্ক্রিপ্টগুলি চালানোর সময়, অন্য একটি থ্রেড নথির বাকি অংশগুলিকে পার্স করে এবং নেটওয়ার্ক থেকে অন্য কোন সংস্থানগুলি লোড করতে হবে তা খুঁজে বের করে এবং সেগুলি লোড করে৷ এইভাবে, সমান্তরাল সংযোগগুলিতে সংস্থানগুলি লোড করা যেতে পারে এবং সামগ্রিক গতি উন্নত হয়। দ্রষ্টব্য: অনুমানমূলক পার্সার শুধুমাত্র বাহ্যিক স্ক্রিপ্ট, স্টাইল শীট এবং চিত্রগুলির মতো বাহ্যিক সংস্থানগুলির রেফারেন্সগুলিকে পার্স করে: এটি DOM ট্রিকে পরিবর্তন করে না - যা মূল পার্সারে ছেড়ে দেওয়া হয়।

শৈলী শীট

অন্যদিকে শৈলী শীট একটি ভিন্ন মডেল আছে. ধারণাগতভাবে মনে হচ্ছে যেহেতু স্টাইল শীটগুলি DOM ট্রি পরিবর্তন করে না, তাদের জন্য অপেক্ষা করার এবং নথি পার্সিং বন্ধ করার কোন কারণ নেই। ডকুমেন্ট পার্সিং পর্যায়ে স্ক্রিপ্টের শৈলী তথ্যের জন্য জিজ্ঞাসা করার একটি সমস্যা আছে। যদি স্টাইলটি এখনও লোড এবং পার্স করা না হয় তবে স্ক্রিপ্টটি ভুল উত্তর পাবে এবং দৃশ্যত এটি অনেক সমস্যার সৃষ্টি করেছে। এটি একটি প্রান্ত কেস বলে মনে হচ্ছে কিন্তু বেশ সাধারণ। ফায়ারফক্স সমস্ত স্ক্রিপ্ট ব্লক করে যখন একটি স্টাইল শীট থাকে যা এখনও লোড এবং পার্স করা হচ্ছে। WebKit শুধুমাত্র স্ক্রিপ্টগুলিকে ব্লক করে যখন তারা নির্দিষ্ট শৈলী বৈশিষ্ট্যগুলি অ্যাক্সেস করার চেষ্টা করে যা আনলোড করা স্টাইল শীট দ্বারা প্রভাবিত হতে পারে।

গাছ নির্মাণ রেন্ডার

যখন DOM ট্রি নির্মাণ করা হচ্ছে, ব্রাউজারটি আরেকটি ট্রি তৈরি করে, রেন্ডার ট্রি। এই গাছটি চাক্ষুষ উপাদানের যে ক্রমে তারা প্রদর্শিত হবে। এটি নথির চাক্ষুষ উপস্থাপনা। এই গাছের উদ্দেশ্য হল বিষয়বস্তুকে তাদের সঠিক ক্রমে পেইন্টিং সক্ষম করা।

ফায়ারফক্স রেন্ডার ট্রির উপাদানগুলিকে "ফ্রেম" বলে। ওয়েবকিট রেন্ডারার বা রেন্ডার অবজেক্ট শব্দটি ব্যবহার করে।

একজন উপস্থাপক জানেন কিভাবে নিজেকে এবং তার সন্তানদের সাজাতে এবং আঁকতে হয়।

ওয়েবকিটের রেন্ডারঅবজেক্ট ক্লাস, রেন্ডারারদের বেস ক্লাস, এর নিম্নলিখিত সংজ্ঞা রয়েছে:

class RenderObject{
  virtual void layout();
  virtual void paint(PaintInfo);
  virtual void rect repaintRect();
  Node* node;  //the DOM node
  RenderStyle* style;  // the computed style
  RenderLayer* containgLayer; //the containing z-index layer
}

প্রতিটি রেন্ডারার একটি আয়তক্ষেত্রাকার অঞ্চলকে প্রতিনিধিত্ব করে যা সাধারণত একটি নোডের CSS বক্সের সাথে সম্পর্কিত, যেমন CSS2 স্পেক দ্বারা বর্ণিত। এটি প্রস্থ, উচ্চতা এবং অবস্থানের মতো জ্যামিতিক তথ্য অন্তর্ভুক্ত করে।

বক্স টাইপ স্টাইল অ্যাট্রিবিউটের "ডিসপ্লে" মান দ্বারা প্রভাবিত হয় যা নোডের সাথে প্রাসঙ্গিক ( স্টাইল গণনা বিভাগটি দেখুন)। ডিসপ্লে অ্যাট্রিবিউট অনুসারে একটি DOM নোডের জন্য কী ধরনের রেন্ডারার তৈরি করা উচিত তা নির্ধারণের জন্য এখানে WebKit কোড রয়েছে:

RenderObject* RenderObject::createObject(Node* node, RenderStyle* style)
{
    Document* doc = node->document();
    RenderArena* arena = doc->renderArena();
    ...
    RenderObject* o = 0;

    switch (style->display()) {
        case NONE:
            break;
        case INLINE:
            o = new (arena) RenderInline(node);
            break;
        case BLOCK:
            o = new (arena) RenderBlock(node);
            break;
        case INLINE_BLOCK:
            o = new (arena) RenderBlock(node);
            break;
        case LIST_ITEM:
            o = new (arena) RenderListItem(node);
            break;
       ...
    }

    return o;
}

উপাদানের ধরনটিও বিবেচনা করা হয়: উদাহরণস্বরূপ, ফর্ম নিয়ন্ত্রণ এবং টেবিলের বিশেষ ফ্রেম রয়েছে।

ওয়েবকিটে যদি একটি উপাদান একটি বিশেষ রেন্ডারার তৈরি করতে চায়, তবে এটি createRenderer() পদ্ধতিকে ওভাররাইড করবে। রেন্ডারাররা এমন স্টাইল অবজেক্টের দিকে নির্দেশ করে যেখানে অ জ্যামিতিক তথ্য নেই।

DOM গাছের সাথে রেন্ডার ট্রি সম্পর্ক

রেন্ডারারগুলি DOM উপাদানগুলির সাথে মিলে যায়, কিন্তু সম্পর্ক একের সাথে এক নয়৷ নন-ভিজ্যুয়াল DOM উপাদানগুলি রেন্ডার ট্রিতে ঢোকানো হবে না। একটি উদাহরণ হল "মাথা" উপাদান। এছাড়াও যে উপাদানগুলির প্রদর্শনের মান "কোনটি" তে নির্ধারিত ছিল সেগুলি গাছে উপস্থিত হবে না (যেখানে "লুকানো" দৃশ্যমানতা সহ উপাদানগুলি গাছে উপস্থিত হবে)।

DOM উপাদান আছে যা বেশ কিছু ভিজ্যুয়াল বস্তুর সাথে মিলে যায়। এগুলি সাধারণত জটিল কাঠামোর উপাদান যা একটি আয়তক্ষেত্র দ্বারা বর্ণনা করা যায় না। উদাহরণস্বরূপ, "নির্বাচন" উপাদানটিতে তিনটি রেন্ডারার রয়েছে: একটি প্রদর্শন এলাকার জন্য, একটি ড্রপ ডাউন তালিকা বাক্সের জন্য এবং একটি বোতামের জন্য৷ এছাড়াও যখন পাঠ্য একাধিক লাইনে বিভক্ত হয় কারণ প্রস্থ একটি লাইনের জন্য যথেষ্ট নয়, তখন নতুন লাইনগুলি অতিরিক্ত রেন্ডারার হিসাবে যোগ করা হবে।

একাধিক রেন্ডারারের আরেকটি উদাহরণ হল ভাঙা HTML। CSS স্পেক অনুযায়ী একটি ইনলাইন এলিমেন্টে শুধুমাত্র ব্লক এলিমেন্ট বা শুধুমাত্র ইনলাইন এলিমেন্ট থাকতে হবে। মিশ্র সামগ্রীর ক্ষেত্রে, ইনলাইন উপাদানগুলিকে মোড়ানোর জন্য বেনামী ব্লক রেন্ডারার তৈরি করা হবে।

কিছু রেন্ডার অবজেক্ট একটি DOM নোডের সাথে মিলে যায় কিন্তু গাছের একই জায়গায় নয়। ফ্লোট এবং একেবারে অবস্থান করা উপাদানগুলি প্রবাহের বাইরে, গাছের একটি ভিন্ন অংশে স্থাপন করা হয় এবং বাস্তব ফ্রেমে ম্যাপ করা হয়। একটি স্থানধারক ফ্রেম যেখানে তারা থাকা উচিত ছিল.

রেন্ডার ট্রি এবং সংশ্লিষ্ট DOM ট্রি।
চিত্র 13: রেন্ডার ট্রি এবং সংশ্লিষ্ট DOM ট্রি। "ভিউপোর্ট" হল প্রাথমিক ধারণকারী ব্লক। ওয়েবকিটে এটি "রেন্ডারভিউ" অবজেক্ট হবে

গাছ নির্মাণের প্রবাহ

ফায়ারফক্সে, উপস্থাপনাটি DOM আপডেটের জন্য শ্রোতা হিসাবে নিবন্ধিত হয়। উপস্থাপনা ফ্রেম নির্মাণকে FrameConstructor অর্পণ করে এবং কনস্ট্রাক্টর শৈলী সমাধান করে ( শৈলী গণনা দেখুন) এবং একটি ফ্রেম তৈরি করে।

ওয়েবকিটে শৈলী সমাধান এবং একটি রেন্ডারার তৈরি করার প্রক্রিয়াটিকে "সংযুক্তি" বলা হয়। প্রতিটি DOM নোডের একটি "সংযুক্ত" পদ্ধতি রয়েছে। সংযুক্তি সিঙ্ক্রোনাস, DOM ট্রিতে নোড সন্নিবেশ নতুন নোডকে "সংযুক্ত" পদ্ধতি বলে।

এইচটিএমএল এবং বডি ট্যাগ প্রক্রিয়াকরণের ফলে রেন্ডার ট্রি রুট তৈরি হয়। রুট রেন্ডার অবজেক্টের সাথে মিল রয়েছে যা CSS স্পেক কন্টেনিং ব্লককে বলে: টপ মোস্ট ব্লক যাতে অন্য সব ব্লক থাকে। এর মাত্রা হল ভিউপোর্ট: ব্রাউজার উইন্ডো প্রদর্শন এলাকা মাত্রা। ফায়ারফক্স এটিকে ViewPortFrame বলে এবং ওয়েবকিট এটিকে RenderView বলে। এটি রেন্ডার অবজেক্ট যা নথি নির্দেশ করে। বাকি গাছ একটি DOM নোড সন্নিবেশ হিসাবে নির্মিত হয়.

প্রসেসিং মডেলে CSS2 স্পেক দেখুন।

শৈলী গণনা

রেন্ডার ট্রি তৈরি করার জন্য প্রতিটি রেন্ডার অবজেক্টের ভিজ্যুয়াল বৈশিষ্ট্য গণনা করা প্রয়োজন। এটি প্রতিটি উপাদানের শৈলী বৈশিষ্ট্য গণনা করে করা হয়।

শৈলীতে বিভিন্ন উত্সের স্টাইল শীট, ইনলাইন শৈলী উপাদান এবং HTML এর ভিজ্যুয়াল বৈশিষ্ট্য অন্তর্ভুক্ত থাকে (যেমন "bgcolor" প্রপার্টি)। পরবর্তীতে সিএসএস শৈলীর বৈশিষ্ট্যের সাথে মিল রেখে অনুবাদ করা হয়।

স্টাইল শীটগুলির উৎপত্তি হল ব্রাউজারের ডিফল্ট স্টাইল শীট, পৃষ্ঠার লেখক দ্বারা প্রদত্ত স্টাইল শীট এবং ব্যবহারকারীর স্টাইল শীটগুলি - এগুলি ব্রাউজার ব্যবহারকারী দ্বারা প্রদত্ত স্টাইল শীট (ব্রাউজারগুলি আপনাকে আপনার পছন্দের শৈলীগুলি সংজ্ঞায়িত করতে দেয়৷ উদাহরণস্বরূপ, ফায়ারফক্সে, এটি "Firefox প্রোফাইল" ফোল্ডারে একটি স্টাইল শীট স্থাপন করে করা হয়)।

শৈলী গণনা কিছু অসুবিধা নিয়ে আসে:

  1. শৈলী ডেটা একটি খুব বড় গঠন, যা অনেক শৈলী বৈশিষ্ট্য ধারণ করে, এটি মেমরি সমস্যা সৃষ্টি করতে পারে।
  2. অপ্টিমাইজ করা না হলে প্রতিটি উপাদানের জন্য ম্যাচিং নিয়মগুলি খুঁজে বের করা কর্মক্ষমতা সমস্যা সৃষ্টি করতে পারে। মিল খুঁজে পেতে প্রতিটি উপাদানের জন্য সম্পূর্ণ নিয়ম তালিকা অতিক্রম করা একটি ভারী কাজ। নির্বাচকদের জটিল কাঠামো থাকতে পারে যা ম্যাচিং প্রক্রিয়াটিকে একটি আপাতদৃষ্টিতে প্রতিশ্রুতিবদ্ধ পথে শুরু করতে পারে যা নিরর্থক বলে প্রমাণিত হয় এবং অন্য পথের চেষ্টা করতে হবে।

    উদাহরণস্বরূপ - এই যৌগ নির্বাচক:

    div div div div{
    ...
    }
    

    মানে নিয়মগুলি একজন <div> এর ক্ষেত্রে প্রযোজ্য যিনি 3 div-এর বংশধর৷ ধরুন আপনি একটি প্রদত্ত <div> উপাদানের জন্য নিয়মটি প্রযোজ্য কিনা তা পরীক্ষা করতে চান। আপনি পরীক্ষা করার জন্য গাছের উপরে একটি নির্দিষ্ট পথ বেছে নিন। শুধুমাত্র দুটি ডিভ রয়েছে এবং নিয়ম প্রযোজ্য নয় তা খুঁজে বের করার জন্য আপনাকে নোড ট্রিটি অতিক্রম করতে হতে পারে। তারপরে আপনাকে গাছের অন্যান্য পথ চেষ্টা করতে হবে।

  3. নিয়মগুলি প্রয়োগ করার জন্য বেশ জটিল ক্যাসকেড নিয়ম জড়িত যা নিয়মগুলির শ্রেণিবিন্যাসকে সংজ্ঞায়িত করে।

আসুন দেখি কিভাবে ব্রাউজারগুলি এই সমস্যার মুখোমুখি হয়:

স্টাইল ডেটা শেয়ার করা

WebKit নোড রেফারেন্স স্টাইল অবজেক্ট (RenderStyle)। এই অবজেক্টগুলি কিছু শর্তে নোড দ্বারা ভাগ করা যেতে পারে। নোডগুলি ভাইবোন বা কাজিন এবং:

  1. উপাদানগুলি অবশ্যই একই মাউসের অবস্থায় থাকতে হবে (যেমন, একটি হতে পারে না : hover যখন অন্যটি নয়)
  2. কোনো উপাদানেরই কোনো আইডি থাকা উচিত নয়
  3. ট্যাগের নামগুলো মিলে যাওয়া উচিত
  4. ক্লাসের গুণাবলী মিলিত হওয়া উচিত
  5. ম্যাপ করা বৈশিষ্ট্যের সেট অবশ্যই অভিন্ন হতে হবে
  6. লিঙ্কের অবস্থা অবশ্যই মিলবে
  7. ফোকাস স্টেট অবশ্যই মেলে
  8. কোনও উপাদানই অ্যাট্রিবিউট নির্বাচকদের দ্বারা প্রভাবিত হওয়া উচিত নয়, যেখানে প্রভাবিতকে সংজ্ঞায়িত করা হয় এমন কোনও নির্বাচকের সাথে মিল থাকা যা নির্বাচকের মধ্যে যে কোনও অবস্থানে কোনও বৈশিষ্ট্য নির্বাচককে ব্যবহার করে
  9. উপাদানগুলিতে কোনও ইনলাইন শৈলী বৈশিষ্ট্য থাকতে হবে না
  10. ব্যবহারে কোনো ভাইবোন নির্বাচক অবশ্যই থাকবে না। কোনো ভাইবোন নির্বাচকের সম্মুখীন হলে WebCore শুধুমাত্র একটি বিশ্বব্যাপী সুইচ ছুড়ে দেয় এবং যখন তারা উপস্থিত থাকে তখন সমগ্র নথির জন্য স্টাইল ভাগাভাগি অক্ষম করে। এর মধ্যে রয়েছে + নির্বাচক এবং নির্বাচক যেমন :first-child এবং :last-child।

ফায়ারফক্সের নিয়ম গাছ

সহজ শৈলী গণনার জন্য ফায়ারফক্সের দুটি অতিরিক্ত গাছ রয়েছে: নিয়ম গাছ এবং শৈলী প্রসঙ্গ ট্রি। WebKit-এও স্টাইল অবজেক্ট আছে কিন্তু সেগুলি স্টাইল কনটেক্সট ট্রির মতো ট্রিতে সংরক্ষণ করা হয় না, শুধুমাত্র DOM নোড তার প্রাসঙ্গিক শৈলীর দিকে নির্দেশ করে।

ফায়ারফক্স শৈলী প্রসঙ্গ গাছ।
চিত্র 14: ফায়ারফক্স শৈলীর প্রসঙ্গ ট্রি।

শৈলী প্রসঙ্গে শেষ মান রয়েছে। মানগুলি সঠিক ক্রমে সমস্ত মিলে যাওয়া নিয়মগুলি প্রয়োগ করে এবং ম্যানিপুলেশনগুলি সম্পাদন করে যা তাদের যৌক্তিক থেকে কংক্রিট মানগুলিতে রূপান্তরিত করে গণনা করা হয়। উদাহরণস্বরূপ, যদি যৌক্তিক মানটি স্ক্রিনের শতাংশ হয় তবে এটি গণনা করা হবে এবং পরম এককে রূপান্তরিত হবে। নিয়ম গাছ ধারণা সত্যিই চতুর. এটি নোডগুলির মধ্যে এই মানগুলিকে আবার গণনা করা এড়াতে সক্ষম করে। এটি স্থানও বাঁচায়।

সমস্ত মিলে যাওয়া নিয়ম একটি গাছে সংরক্ষণ করা হয়। একটি পথের নীচের নোডগুলির অগ্রাধিকার বেশি। গাছটিতে নিয়মের মিলের জন্য সমস্ত পথ রয়েছে যা পাওয়া গেছে। নিয়ম অলসভাবে সংরক্ষণ করা হয়. প্রতিটি নোডের জন্য শুরুতে গাছটি গণনা করা হয় না, তবে যখনই একটি নোড শৈলী গণনা করা প্রয়োজন তখন গণনা করা পাথগুলি গাছে যোগ করা হয়।

ধারণাটি হল গাছের পথগুলিকে একটি অভিধানে শব্দ হিসাবে দেখা। ধরা যাক আমরা ইতিমধ্যে এই নিয়ম গাছটি গণনা করেছি:

গণনাকৃত নিয়ম গাছ
চিত্র 15: গণনাকৃত নিয়ম গাছ।

ধরুন আমাদের কন্টেন্ট ট্রিতে অন্য একটি উপাদানের জন্য নিয়মগুলি মেলাতে হবে এবং মিলিত নিয়মগুলি খুঁজে বের করতে হবে (সঠিক ক্রমে) BEI। আমরা ইতিমধ্যে গাছের মধ্যে এই পথ আছে কারণ আমরা ইতিমধ্যে পাথ ABEIL গণনা. আমাদের এখন কম কাজ করতে হবে।

আসুন দেখি কিভাবে গাছ আমাদের কাজ বাঁচায়।

structs মধ্যে বিভাজন

শৈলী প্রসঙ্গগুলি স্ট্রাকটে বিভক্ত। এই স্ট্রাকটগুলিতে সীমানা বা রঙের মতো একটি নির্দিষ্ট বিভাগের শৈলীর তথ্য রয়েছে। একটি স্ট্রাকটের সমস্ত বৈশিষ্ট্য হয় উত্তরাধিকারসূত্রে প্রাপ্ত বা উত্তরাধিকারসূত্রে প্রাপ্ত নয়। উত্তরাধিকারসূত্রে প্রাপ্ত বৈশিষ্ট্যগুলি এমন বৈশিষ্ট্য যা উপাদান দ্বারা সংজ্ঞায়িত না হলে, তার পিতামাতার কাছ থেকে উত্তরাধিকারসূত্রে প্রাপ্ত হয়। অ-উত্তরাধিকারী বৈশিষ্ট্য (যাকে "রিসেট" বৈশিষ্ট্য বলা হয়) সংজ্ঞায়িত না হলে ডিফল্ট মান ব্যবহার করে।

গাছটি গাছে সম্পূর্ণ স্ট্রাকট (গণনা করা শেষ মান ধারণ করে) ক্যাশে করে আমাদের সাহায্য করে। ধারণাটি হল যে যদি নীচের নোডটি একটি স্ট্রাকটের জন্য একটি সংজ্ঞা সরবরাহ না করে তবে একটি উপরের নোডে একটি ক্যাশে করা স্ট্রাকট ব্যবহার করা যেতে পারে।

নিয়ম গাছ ব্যবহার করে শৈলী প্রসঙ্গ গণনা করা

একটি নির্দিষ্ট উপাদানের জন্য শৈলী প্রসঙ্গ গণনা করার সময়, আমরা প্রথমে নিয়ম ট্রিতে একটি পথ গণনা করি বা বিদ্যমান একটি ব্যবহার করি। তারপরে আমরা আমাদের নতুন শৈলী প্রসঙ্গে স্ট্রাকটগুলি পূরণ করার জন্য নিয়মগুলি প্রয়োগ করতে শুরু করি। আমরা পাথের নীচের নোড থেকে শুরু করি - যেটির সর্বোচ্চ অগ্রাধিকার রয়েছে (সাধারণত সবচেয়ে নির্দিষ্ট নির্বাচক) এবং আমাদের স্ট্রাকট পূর্ণ না হওয়া পর্যন্ত গাছটি অতিক্রম করি। যদি সেই নিয়ম নোডে স্ট্রাকটের জন্য কোন স্পেসিফিকেশন না থাকে, তাহলে আমরা ব্যাপকভাবে অপ্টিমাইজ করতে পারি - যতক্ষণ না আমরা একটি নোড খুঁজে না পাই যেটি সম্পূর্ণরূপে নির্দিষ্ট করে এবং এটি নির্দেশ করে - আমরা বৃহৎভাবে অপ্টিমাইজ করতে পারি - এটি সর্বোত্তম অপ্টিমাইজেশান - সমগ্র স্ট্রাকট ভাগ করা হয়। এটি শেষ মান এবং মেমরির গণনা সংরক্ষণ করে।

যদি আমরা আংশিক সংজ্ঞা খুঁজে পাই, আমরা স্ট্রাকটটি পূরণ না হওয়া পর্যন্ত গাছে উঠি।

যদি আমরা আমাদের struct-এর জন্য কোনো সংজ্ঞা খুঁজে না পাই তাহলে, যদি struct একটি "উত্তরাধিকারী" টাইপ হয়, তাহলে আমরা প্রসঙ্গ ট্রি- তে আমাদের পিতামাতার struct নির্দেশ করি। এই ক্ষেত্রে আমরা স্ট্রাকট শেয়ার করতেও সফল হয়েছি। যদি এটি একটি রিসেট স্ট্রাকট হয় তবে ডিফল্ট মান ব্যবহার করা হবে।

যদি সবচেয়ে নির্দিষ্ট নোডটি মান যোগ করে তবে এটিকে প্রকৃত মানগুলিতে রূপান্তর করার জন্য আমাদের কিছু অতিরিক্ত গণনা করতে হবে। তারপরে আমরা ফলাফলটিকে ট্রি নোডে ক্যাশে করি যাতে এটি শিশুদের দ্বারা ব্যবহার করা যায়।

যদি একটি উপাদানের একটি ভাই বা ভাই থাকে যা একই ট্রি নোডের দিকে নির্দেশ করে তবে সম্পূর্ণ শৈলীর প্রসঙ্গ তাদের মধ্যে ভাগ করা যেতে পারে।

আসুন একটি উদাহরণ দেখি: ধরুন আমাদের এই HTML আছে

<html>
  <body>
    <div class="err" id="div1">
      <p>
        this is a <span class="big"> big error </span>
        this is also a
        <span class="big"> very  big  error</span> error
      </p>
    </div>
    <div class="err" id="div2">another error</div>
  </body>
</html>

এবং নিম্নলিখিত নিয়ম:

div {margin: 5px; color:black}
.err {color:red}
.big {margin-top:3px}
div span {margin-bottom:4px}
#div1 {color:blue}
#div2 {color:green}

জিনিসগুলিকে সহজ করার জন্য আসুন আমরা বলি যে আমাদের কেবল দুটি স্ট্রাকট পূরণ করতে হবে: রঙের কাঠামো এবং মার্জিন কাঠামো। রঙের কাঠামোতে শুধুমাত্র একটি সদস্য রয়েছে: রঙ মার্জিন কাঠামোতে চারটি দিক রয়েছে।

ফলস্বরূপ রুল ট্রি দেখতে এইরকম হবে (নোডগুলি নোডের নাম দিয়ে চিহ্নিত করা হয়েছে: তারা যে নিয়মটি নির্দেশ করে তার সংখ্যা):

নিয়ম গাছ
চিত্র 16: নিয়ম গাছ

প্রসঙ্গ গাছটি দেখতে এইরকম হবে (নোডের নাম: নিয়ম নোড তারা নির্দেশ করে):

প্রসঙ্গ গাছ।
চিত্র 17: প্রসঙ্গ গাছ

ধরুন আমরা HTML পার্স করি এবং দ্বিতীয় <div> ট্যাগে চলে আসি। আমাদের এই নোডের জন্য একটি স্টাইল প্রসঙ্গ তৈরি করতে হবে এবং এর স্টাইল স্ট্রাকটগুলি পূরণ করতে হবে।

আমরা নিয়মগুলি মেলাব এবং আবিষ্কার করব যে <div> এর জন্য মিলিত নিয়মগুলি হল 1, 2 এবং 6৷ এর অর্থ হল গাছে ইতিমধ্যেই একটি বিদ্যমান পথ রয়েছে যা আমাদের উপাদানটি ব্যবহার করতে পারে এবং আমাদের কেবল এটিতে আরেকটি নোড যুক্ত করতে হবে নিয়ম 6 (রুল ট্রিতে নোড F)।

আমরা একটি স্টাইল প্রসঙ্গ তৈরি করব এবং এটিকে প্রসঙ্গ ট্রিতে রাখব। নতুন শৈলী প্রসঙ্গ নিয়ম ট্রিতে নোড F নির্দেশ করবে।

আমাদের এখন শৈলীর কাঠামো পূরণ করতে হবে। আমরা মার্জিন কাঠামো পূরণ করে শুরু করব। যেহেতু শেষ নিয়ম নোড (F) মার্জিন স্ট্রাকটে যোগ করে না, আমরা যতক্ষণ না আমরা পূর্ববর্তী নোড সন্নিবেশে গণনা করা একটি ক্যাশড স্ট্রাকট খুঁজে না পাই এবং এটি ব্যবহার করতে পারি ততক্ষণ পর্যন্ত আমরা গাছের উপরে যেতে পারি। আমরা এটি নোড B-এ খুঁজে পাব, যা সর্বোচ্চ নোড যা নির্দিষ্ট মার্জিন নিয়ম।

আমরা একটি সংজ্ঞা আছে রঙ struct জন্য, তাই আমরা একটি ক্যাশে struct ব্যবহার করতে পারি না. যেহেতু রঙের একটি বৈশিষ্ট্য রয়েছে আমাদের অন্যান্য বৈশিষ্ট্যগুলি পূরণ করতে গাছে উঠতে হবে না। আমরা শেষ মান গণনা করব (স্ট্রিংকে আরজিবি ইত্যাদিতে রূপান্তর করব) এবং এই নোডে গণনা করা স্ট্রাকট ক্যাশে করব।

দ্বিতীয় <span> উপাদানের কাজ আরও সহজ। আমরা নিয়মের সাথে মিল রাখব এবং এই সিদ্ধান্তে উপনীত হব যে এটি পূর্ববর্তী স্প্যানের মতো G-কে নির্দেশ করে। যেহেতু আমাদের ভাইবোন আছে যেগুলি একই নোডের দিকে নির্দেশ করে, তাই আমরা পুরো শৈলীর প্রসঙ্গটি ভাগ করতে পারি এবং কেবলমাত্র পূর্ববর্তী স্প্যানটির প্রসঙ্গে নির্দেশ করতে পারি।

প্যারেন্ট থেকে উত্তরাধিকারসূত্রে প্রাপ্ত নিয়ম ধারণ করে এমন স্ট্রাকটগুলির জন্য, প্রসঙ্গ ট্রিতে ক্যাশিং করা হয় (রঙের বৈশিষ্ট্যটি আসলে উত্তরাধিকারসূত্রে পাওয়া যায়, কিন্তু ফায়ারফক্স এটিকে রিসেট হিসাবে বিবেচনা করে এবং নিয়ম ট্রিতে ক্যাশে করে)।

উদাহরণস্বরূপ, যদি আমরা একটি অনুচ্ছেদে ফন্টের জন্য নিয়ম যোগ করি:

p {font-family: Verdana; font size: 10px; font-weight: bold}

তারপর অনুচ্ছেদ উপাদান, যা প্রসঙ্গ ট্রিতে ডিভ-এর একটি শিশু, তার পিতামাতার মতো একই ফন্টের কাঠামো ভাগ করতে পারে। অনুচ্ছেদের জন্য কোনো ফন্টের নিয়ম নির্দিষ্ট করা না থাকলে এটি হয়।

WebKit-এ, যার কোনো নিয়ম গাছ নেই, মিলে যাওয়া ঘোষণাগুলি চারবার অতিক্রম করা হয়। প্রথমে অ-গুরুত্বপূর্ণ উচ্চ অগ্রাধিকার বৈশিষ্ট্যগুলি প্রয়োগ করা হয় (প্রথমে যে বৈশিষ্ট্যগুলি প্রয়োগ করা উচিত কারণ অন্যরা তাদের উপর নির্ভর করে, যেমন প্রদর্শন), তারপর উচ্চ অগ্রাধিকার গুরুত্বপূর্ণ, তারপর স্বাভাবিক অগ্রাধিকার অ-গুরুত্বপূর্ণ, তারপর স্বাভাবিক অগ্রাধিকার গুরুত্বপূর্ণ নিয়ম। এর মানে হল যে বৈশিষ্ট্যগুলি একাধিক বার প্রদর্শিত হবে সঠিক ক্যাসকেড ক্রম অনুসারে সমাধান করা হবে৷ শেষ জয়।

তাই সংক্ষেপে বলতে গেলে: স্টাইল অবজেক্ট শেয়ার করা (সম্পূর্ণভাবে বা তাদের ভিতরের কিছু স্ট্রাকট) সমস্যা 1 এবং 3 সমাধান করে। ফায়ারফক্স রুল ট্রি সঠিক ক্রমে বৈশিষ্ট্য প্রয়োগ করতেও সাহায্য করে।

সহজ ম্যাচের জন্য নিয়ম কানুন

শৈলী নিয়মের জন্য বেশ কয়েকটি উত্স রয়েছে:

  1. CSS নিয়ম, হয় বাহ্যিক স্টাইল শীট বা শৈলী উপাদানে। css p {color: blue}
  2. ইনলাইন শৈলী বৈশিষ্ট্য যেমন html <p style="color: blue" />
  3. এইচটিএমএল ভিজ্যুয়াল অ্যাট্রিবিউট (যা প্রাসঙ্গিক শৈলীর নিয়মে ম্যাপ করা হয়) html <p bgcolor="blue" /> শেষ দুটি সহজেই উপাদানের সাথে মিলে যায় কারণ তিনি শৈলী বৈশিষ্ট্যের মালিক এবং HTML বৈশিষ্ট্যগুলি কী হিসাবে উপাদান ব্যবহার করে ম্যাপ করা যেতে পারে৷

আগের সংখ্যা # 2-এ যেমন উল্লেখ করা হয়েছে, সিএসএস নিয়মের মিল আরও জটিল হতে পারে। অসুবিধা সমাধানের জন্য, সহজ অ্যাক্সেসের জন্য নিয়মগুলি হেরফের করা হয়।

স্টাইল শীট পার্স করার পরে, নির্বাচকের মতে নিয়মগুলি বেশ কয়েকটি হ্যাশ মানচিত্রের একটিতে যোগ করা হয়। আইডি অনুসারে, শ্রেণির নাম অনুসারে, ট্যাগের নাম অনুসারে এবং এই বিভাগগুলির সাথে খাপ খায় না এমন কিছুর জন্য একটি সাধারণ মানচিত্র রয়েছে৷ যদি নির্বাচক একটি আইডি হয় তবে নিয়মটি আইডি মানচিত্রে যোগ করা হবে, যদি এটি একটি শ্রেণি হয় তবে এটি ক্লাস ম্যাপে যোগ করা হবে ইত্যাদি।

এই ম্যানিপুলেশন নিয়ম মেলে অনেক সহজ করে তোলে। প্রতিটি ঘোষণা দেখার দরকার নেই: আমরা মানচিত্র থেকে একটি উপাদানের জন্য প্রাসঙ্গিক নিয়মগুলি বের করতে পারি। এই অপ্টিমাইজেশানটি 95+% নিয়মগুলিকে সরিয়ে দেয়, যাতে ম্যাচিং প্রক্রিয়া (4.1) চলাকালীন সেগুলি বিবেচনা করারও প্রয়োজন হয় না।

আসুন উদাহরণস্বরূপ নিম্নলিখিত শৈলী নিয়মগুলি দেখি:

p.error {color: red}
#messageDiv {height: 50px}
div {margin: 5px}

প্রথম নিয়মটি ক্লাস ম্যাপে সন্নিবেশ করা হবে। দ্বিতীয়টি আইডি মানচিত্রে এবং তৃতীয়টি ট্যাগ মানচিত্রে।

নিম্নলিখিত HTML খণ্ডের জন্য;

<p class="error">an error occurred</p>
<div id=" messageDiv">this is a message</div>

আমরা প্রথমে p এলিমেন্টের নিয়ম খোঁজার চেষ্টা করব। ক্লাস ম্যাপে একটি "এরর" কী থাকবে যার অধীনে "p.error"-এর নিয়ম পাওয়া যাবে। ডিভ এলিমেন্টের আইডি ম্যাপে প্রাসঙ্গিক নিয়ম থাকবে (কী হল আইডি) এবং ট্যাগ ম্যাপে। তাই চাবি দ্বারা নিষ্কাশন করা নিয়মের মধ্যে কোনটি সত্যিই মেলে তা খুঁজে বের করা একমাত্র কাজ বাকি।

উদাহরণস্বরূপ যদি div এর নিয়ম ছিল:

table div {margin: 5px}

এটি এখনও ট্যাগ ম্যাপ থেকে বের করা হবে, কারণ কীটি সবচেয়ে ডানদিকের নির্বাচক, কিন্তু এটি আমাদের ডিভ উপাদানের সাথে মেলে না, যার একটি টেবিল পূর্বপুরুষ নেই।

ওয়েবকিট এবং ফায়ারফক্স উভয়ই এই ম্যানিপুলেশন করে।

শৈলী শীট ক্যাসকেড অর্ডার

স্টাইল অবজেক্টের প্রতিটি ভিজ্যুয়াল অ্যাট্রিবিউটের সাথে সম্পর্কিত বৈশিষ্ট্য রয়েছে (সমস্ত CSS অ্যাট্রিবিউট কিন্তু আরও জেনেরিক)। যদি প্রপার্টিটি মিলিত নিয়মগুলির কোনো দ্বারা সংজ্ঞায়িত না হয়, তাহলে কিছু বৈশিষ্ট্য প্যারেন্ট এলিমেন্ট স্টাইল অবজেক্ট দ্বারা উত্তরাধিকার সূত্রে প্রাপ্ত হতে পারে। অন্যান্য বৈশিষ্ট্য ডিফল্ট মান আছে.

সমস্যাটি শুরু হয় যখন একাধিক সংজ্ঞা থাকে - এখানে সমস্যাটি সমাধান করার জন্য ক্যাসকেড অর্ডার আসে।

একটি শৈলী সম্পত্তির জন্য একটি ঘোষণা বিভিন্ন স্টাইল শীটে এবং একটি স্টাইল শীটের ভিতরে বেশ কয়েকবার প্রদর্শিত হতে পারে। এর মানে নিয়ম প্রয়োগের ক্রম অত্যন্ত গুরুত্বপূর্ণ। একে "ক্যাসকেড" অর্ডার বলা হয়। CSS2 স্পেক অনুযায়ী, ক্যাসকেড অর্ডার হল (নিম্ন থেকে উচ্চ পর্যন্ত):

  1. ব্রাউজার ঘোষণা
  2. ব্যবহারকারীর স্বাভাবিক ঘোষণা
  3. লেখক স্বাভাবিক ঘোষণা
  4. লেখক গুরুত্বপূর্ণ ঘোষণা
  5. ব্যবহারকারীর গুরুত্বপূর্ণ ঘোষণা

ব্রাউজার ঘোষণাগুলি সর্বনিম্ন গুরুত্বপূর্ণ এবং ব্যবহারকারী শুধুমাত্র লেখককে ওভাররাইড করে যদি ঘোষণাটি গুরুত্বপূর্ণ হিসাবে চিহ্নিত করা হয়। একই ক্রম সহ ঘোষণাগুলি নির্দিষ্টতা দ্বারা বাছাই করা হবে এবং তারপরে সেগুলি নির্দিষ্ট করা হয়েছে৷ এইচটিএমএল ভিজ্যুয়াল অ্যাট্রিবিউটগুলি সিএসএস ঘোষণার সাথে মিলে যাওয়ায় অনুবাদ করা হয়। তারা কম অগ্রাধিকার সঙ্গে লেখক নিয়ম হিসাবে বিবেচিত হয়.

বিশেষত্ব

নির্বাচক নির্দিষ্টতা CSS2 স্পেসিফিকেশন দ্বারা নিম্নরূপ সংজ্ঞায়িত করা হয়েছে:

  1. গণনা 1 যদি এটি থেকে ঘোষণাটি একটি 'স্টাইল' অ্যাট্রিবিউট না হয় একটি নির্বাচক সহ একটি নিয়মের পরিবর্তে, 0 অন্যথায় (= a)
  2. নির্বাচক (= b) এ আইডি বৈশিষ্ট্যের সংখ্যা গণনা করুন
  3. নির্বাচক (= c) এ অন্যান্য বৈশিষ্ট্য এবং ছদ্ম-শ্রেণীর সংখ্যা গণনা করুন
  4. নির্বাচকের উপাদানের নাম এবং ছদ্ম-উপাদানের সংখ্যা গণনা করুন (= d)

চারটি সংখ্যা abcd (বড় ভিত্তি সহ একটি সংখ্যা পদ্ধতিতে) একত্রিত করা নির্দিষ্টতা দেয়।

আপনার যে সংখ্যার ভিত্তিটি ব্যবহার করতে হবে সেটিকে আপনার একটি বিভাগে থাকা সর্বোচ্চ গণনা দ্বারা সংজ্ঞায়িত করা হয়।

উদাহরণস্বরূপ, যদি a=14 আপনি হেক্সাডেসিমাল বেস ব্যবহার করতে পারেন। অসম্ভাব্য ক্ষেত্রে যেখানে a=17 আপনার একটি 17 সংখ্যার সংখ্যার ভিত্তি প্রয়োজন হবে। পরবর্তী পরিস্থিতি এইরকম একজন নির্বাচকের সাথে ঘটতে পারে: html body div div p… (আপনার নির্বাচকের মধ্যে 17 ট্যাগ... খুব একটা সম্ভব নয়)।

কিছু উদাহরণ:

 *             {}  /* a=0 b=0 c=0 d=0 -> specificity = 0,0,0,0 */
 li            {}  /* a=0 b=0 c=0 d=1 -> specificity = 0,0,0,1 */
 li:first-line {}  /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */
 ul li         {}  /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */
 ul ol+li      {}  /* a=0 b=0 c=0 d=3 -> specificity = 0,0,0,3 */
 h1 + *[rel=up]{}  /* a=0 b=0 c=1 d=1 -> specificity = 0,0,1,1 */
 ul ol li.red  {}  /* a=0 b=0 c=1 d=3 -> specificity = 0,0,1,3 */
 li.red.level  {}  /* a=0 b=0 c=2 d=1 -> specificity = 0,0,2,1 */
 #x34y         {}  /* a=0 b=1 c=0 d=0 -> specificity = 0,1,0,0 */
 style=""          /* a=1 b=0 c=0 d=0 -> specificity = 1,0,0,0 */

নিয়ম বাছাই

নিয়মগুলো মিলে যাওয়ার পর ক্যাসকেডের নিয়ম অনুযায়ী সাজানো হয়। WebKit ছোট তালিকার জন্য বুদ্বুদ বাছাই ব্যবহার করে এবং বড় তালিকার জন্য মার্জ সর্ট ব্যবহার করে। WebKit নিয়মগুলির জন্য > অপারেটরকে ওভাররাইড করে সাজানোর প্রয়োগ করে:

static bool operator >(CSSRuleData& r1, CSSRuleData& r2)
{
    int spec1 = r1.selector()->specificity();
    int spec2 = r2.selector()->specificity();
    return (spec1 == spec2) : r1.position() > r2.position() : spec1 > spec2;
}

ধীরে ধীরে প্রক্রিয়া

WebKit একটি পতাকা ব্যবহার করে যা চিহ্নিত করে যে সমস্ত শীর্ষ স্তরের স্টাইল শীট (@imports সহ) লোড করা হয়েছে কিনা। সংযুক্ত করার সময় শৈলী সম্পূর্ণরূপে লোড না হলে, স্থানধারক ব্যবহার করা হয় এবং এটি নথিতে চিহ্নিত করা হয়, এবং স্টাইল শীটগুলি লোড হওয়ার পরে সেগুলি পুনরায় গণনা করা হবে৷

লেআউট

যখন রেন্ডারার তৈরি করা হয় এবং গাছে যোগ করা হয়, তখন এর অবস্থান এবং আকার থাকে না। এই মানগুলি গণনা করাকে লেআউট বা রিফ্লো বলা হয়।

এইচটিএমএল একটি প্রবাহ ভিত্তিক লেআউট মডেল ব্যবহার করে, যার অর্থ হল বেশিরভাগ সময় একটি একক পাসে জ্যামিতি গণনা করা সম্ভব। উপাদানগুলি পরে "প্রবাহে" সাধারণত উপাদানগুলির জ্যামিতিকে প্রভাবিত করে না যা "প্রবাহে" আগে থাকে, তাই বিন্যাস নথির মাধ্যমে বাম-থেকে-ডান, উপরে-থেকে-নিচে যেতে পারে। ব্যতিক্রম আছে: উদাহরণস্বরূপ, HTML টেবিলের একাধিক পাসের প্রয়োজন হতে পারে।

স্থানাঙ্ক সিস্টেম রুট ফ্রেমের সাথে আপেক্ষিক। উপরের এবং বাম স্থানাঙ্ক ব্যবহার করা হয়।

লেআউট একটি পুনরাবৃত্ত প্রক্রিয়া। এটি রুট রেন্ডারার থেকে শুরু হয়, যা HTML নথির <html> উপাদানের সাথে মিলে যায়। লেআউট কিছু বা সমস্ত ফ্রেম অনুক্রমের মাধ্যমে পুনরাবৃত্তিমূলকভাবে চলতে থাকে, প্রতিটি রেন্ডারারের জন্য জ্যামিতিক তথ্য গণনা করে যার জন্য এটি প্রয়োজন।

রুট রেন্ডারারের অবস্থান হল 0,0 এবং এর মাত্রা হল ভিউপোর্ট - ব্রাউজার উইন্ডোর দৃশ্যমান অংশ।

সমস্ত রেন্ডারারের একটি "লেআউট" বা "রিফ্লো" পদ্ধতি থাকে, প্রতিটি রেন্ডারার তার বাচ্চাদের লেআউট পদ্ধতির আহ্বান করে যার লেআউট প্রয়োজন।

নোংরা বিট সিস্টেম

প্রতিটি ছোট পরিবর্তনের জন্য একটি সম্পূর্ণ বিন্যাস না করার জন্য, ব্রাউজারগুলি একটি "নোংরা বিট" সিস্টেম ব্যবহার করে। পরিবর্তিত বা যোগ করা একটি রেন্ডারার নিজেকে এবং তার বাচ্চাদের "নোংরা" হিসাবে চিহ্নিত করে: লেআউট প্রয়োজন৷

দুটি পতাকা রয়েছে: "নোংরা", এবং "শিশুরা নোংরা" যার অর্থ হল যদিও রেন্ডারার নিজেই ঠিক হতে পারে, এটিতে অন্তত একটি শিশু রয়েছে যার একটি লেআউট প্রয়োজন৷

গ্লোবাল এবং ইনক্রিমেন্টাল লেআউট

সম্পূর্ণ রেন্ডার ট্রিতে লেআউটটি ট্রিগার করা যেতে পারে - এটি "গ্লোবাল" লেআউট। এটি এর ফলে ঘটতে পারে:

  1. একটি বিশ্বব্যাপী শৈলী পরিবর্তন যা সমস্ত রেন্ডারারকে প্রভাবিত করে, যেমন ফন্টের আকার পরিবর্তন৷
  2. একটি পর্দার আকার পরিবর্তন করা হচ্ছে ফলে

লেআউট ক্রমবর্ধমান হতে পারে, শুধুমাত্র নোংরা রেন্ডারারগুলিকে সাজানো হবে (এটি কিছু ক্ষতির কারণ হতে পারে যার জন্য অতিরিক্ত লেআউটের প্রয়োজন হবে)।

রেন্ডারার নোংরা হলে ক্রমবর্ধমান লেআউট ট্রিগার হয় (অসিঙ্ক্রোনাসভাবে)। উদাহরণস্বরূপ, নেটওয়ার্ক থেকে অতিরিক্ত সামগ্রী আসার পরে এবং DOM ট্রিতে যোগ করার পরে যখন রেন্ডার ট্রিতে নতুন রেন্ডারার যুক্ত করা হয়।

ক্রমবর্ধমান বিন্যাস।
চিত্র 18: ক্রমবর্ধমান বিন্যাস - শুধুমাত্র নোংরা রেন্ডারার এবং তাদের সন্তানদের রাখা হয়েছে

অ্যাসিঙ্ক্রোনাস এবং সিঙ্ক্রোনাস লেআউট

ক্রমবর্ধমান বিন্যাস অ্যাসিঙ্ক্রোনাসভাবে করা হয়। ফায়ারফক্স ক্রমবর্ধমান লেআউটের জন্য "রিফ্লো কমান্ড" সারিবদ্ধ করে এবং একটি শিডিউলার এই কমান্ডগুলির ব্যাচ এক্সিকিউশনকে ট্রিগার করে। WebKit-এ একটি টাইমারও রয়েছে যা একটি ক্রমবর্ধমান বিন্যাস কার্যকর করে - গাছটি ট্র্যাভার্স করা হয় এবং "নোংরা" রেন্ডারারগুলি লেআউট হয়৷

স্ক্রিপ্টগুলি স্টাইল তথ্যের জন্য জিজ্ঞাসা করে, যেমন "অফসেট হাইট" সিঙ্ক্রোনাসভাবে ক্রমবর্ধমান লেআউট ট্রিগার করতে পারে।

গ্লোবাল লেআউট সাধারণত সিঙ্ক্রোনাসভাবে ট্রিগার করা হবে।

কখনও কখনও লেআউট একটি প্রাথমিক লেআউটের পরে একটি কলব্যাক হিসাবে ট্রিগার করা হয় কারণ কিছু বৈশিষ্ট্য, যেমন স্ক্রলিং অবস্থান পরিবর্তিত হয়েছে৷

অপ্টিমাইজেশন

যখন একটি লেআউট একটি "রিসাইজ" বা রেন্ডারারের অবস্থানের পরিবর্তন (এবং আকার নয়) দ্বারা ট্রিগার করা হয়, তখন রেন্ডারের আকারগুলি ক্যাশে থেকে নেওয়া হয় এবং পুনরায় গণনা করা হয় না...

কিছু ক্ষেত্রে শুধুমাত্র একটি সাব ট্রি পরিবর্তন করা হয় এবং লেআউট রুট থেকে শুরু হয় না। এটি এমন ক্ষেত্রে ঘটতে পারে যেখানে পরিবর্তনটি স্থানীয় এবং এর আশেপাশে প্রভাব ফেলে না - যেমন টেক্সট ফিল্ডে টেক্সট ঢোকানো হয় (অন্যথায় প্রতিটি কীস্ট্রোক রুট থেকে শুরু করে একটি লেআউট ট্রিগার করবে)।

লেআউট প্রক্রিয়া

লেআউটে সাধারণত নিম্নলিখিত প্যাটার্ন থাকে:

  1. অভিভাবক রেন্ডারার তার নিজস্ব প্রস্থ নির্ধারণ করে।
  2. পিতামাতা শিশুদের উপর যান এবং:
    1. চাইল্ড রেন্ডারার রাখুন (এটির x এবং y সেট করে)।
    2. প্রয়োজনে চাইল্ড লেআউটকে কল করে - তারা নোংরা বা আমরা একটি বিশ্বব্যাপী লেআউটে আছি, বা অন্য কোনও কারণে - যা শিশুর উচ্চতা গণনা করে।
  3. অভিভাবক শিশুদের সঞ্চিত উচ্চতা এবং মার্জিন এবং প্যাডিংয়ের উচ্চতাগুলি তার নিজস্ব উচ্চতা সেট করতে ব্যবহার করেন - এটি অভিভাবক রেন্ডারারের অভিভাবক দ্বারা ব্যবহার করা হবে৷
  4. তার নোংরা বিট মিথ্যা সেট করে.

ফায়ারফক্স লেআউটের প্যারামিটার হিসাবে একটি "স্টেট" অবজেক্ট (nsHTMLReflowState) ব্যবহার করে (যাকে "রিফ্লো" বলা হয়)। অন্যদের মধ্যে রাষ্ট্র পিতামাতার প্রস্থ অন্তর্ভুক্ত.

ফায়ারফক্স লেআউটের আউটপুট হল একটি "মেট্রিক্স" অবজেক্ট(nsHTMLReflowMetrics)। এতে রেন্ডারারের গণনাকৃত উচ্চতা থাকবে।

প্রস্থ গণনা

কনটেইনার ব্লকের প্রস্থ, রেন্ডারারের স্টাইল "প্রস্থ" বৈশিষ্ট্য, মার্জিন এবং সীমানা ব্যবহার করে রেন্ডারারের প্রস্থ গণনা করা হয়।

উদাহরণস্বরূপ নিম্নলিখিত div এর প্রস্থ:

<div style="width: 30%"/>

নিম্নলিখিত হিসাবে WebKit দ্বারা গণনা করা হবে (শ্রেণী রেন্ডারবক্স পদ্ধতি calcWidth):

  • কন্টেইনারের প্রস্থ হল উপলভ্য কন্টেইনারগুলির সর্বাধিক প্রস্থ এবং 0। এই ক্ষেত্রে উপলব্ধ প্রস্থ হল সামগ্রীপ্রস্থ যা হিসাবে গণনা করা হয়:
clientWidth() - paddingLeft() - paddingRight()

ক্লায়েন্টউইথ এবং ক্লায়েন্ট উচ্চতা সীমানা এবং স্ক্রলবার ব্যতীত একটি বস্তুর অভ্যন্তরের প্রতিনিধিত্ব করে।

  • উপাদানের প্রস্থ হল "প্রস্থ" শৈলী বৈশিষ্ট্য। ধারক প্রস্থের শতাংশ গণনা করে এটি একটি পরম মান হিসাবে গণনা করা হবে।

  • অনুভূমিক সীমানা এবং প্যাডিংগুলি এখন যোগ করা হয়েছে।

এখন পর্যন্ত এটি "পছন্দের প্রস্থ" এর গণনা ছিল। এখন সর্বনিম্ন এবং সর্বোচ্চ প্রস্থ গণনা করা হবে।

পছন্দের প্রস্থ সর্বোচ্চ প্রস্থের চেয়ে বেশি হলে, সর্বোচ্চ প্রস্থ ব্যবহার করা হয়। যদি এটি ন্যূনতম প্রস্থের চেয়ে কম হয় (সবচেয়ে ছোট অবিচ্ছেদ্য একক) তাহলে সর্বনিম্ন প্রস্থ ব্যবহার করা হয়।

একটি বিন্যাস প্রয়োজন হলে মানগুলি ক্যাশে করা হয়, কিন্তু প্রস্থ পরিবর্তন হয় না।

লাইন ব্রেকিং

যখন একটি লেআউটের মাঝখানে একটি রেন্ডারার সিদ্ধান্ত নেয় যে এটি ভাঙতে হবে, তখন রেন্ডারার থামে এবং লেআউটের অভিভাবকের কাছে প্রচার করে যে এটি ভাঙতে হবে। অভিভাবক অতিরিক্ত রেন্ডারার তৈরি করেন এবং তাদের উপর কল লেআউট তৈরি করেন।

পেইন্টিং

পেইন্টিং পর্যায়ে, রেন্ডার ট্রি ট্র্যাভার্স করা হয় এবং রেন্ডারারের "পেইন্ট()" পদ্ধতিটিকে স্ক্রিনে সামগ্রী প্রদর্শনের জন্য বলা হয়। পেইন্টিং UI অবকাঠামো উপাদান ব্যবহার করে।

গ্লোবাল এবং ক্রমবর্ধমান

লেআউটের মতো, পেইন্টিংও বিশ্বব্যাপী হতে পারে - পুরো গাছটি আঁকা হয় - বা ক্রমবর্ধমান। ইনক্রিমেন্টাল পেইন্টিংয়ে, কিছু রেন্ডারার এমনভাবে পরিবর্তিত হয় যা পুরো গাছকে প্রভাবিত করে না। পরিবর্তিত রেন্ডারার স্ক্রিনে এর আয়তক্ষেত্রকে অবৈধ করে। এটি ওএসকে একটি "নোংরা অঞ্চল" হিসাবে দেখতে এবং একটি "পেইন্ট" ইভেন্ট তৈরি করে। ওএস এটি চালাকি করে এবং বেশ কয়েকটি অঞ্চলকে একত্রিত করে। ক্রোমে এটি আরও জটিল কারণ রেন্ডারার মূল প্রক্রিয়ার পরে একটি ভিন্ন প্রক্রিয়ায় রয়েছে। Chrome কিছু পরিমাণে OS আচরণ অনুকরণ করে। উপস্থাপনা এই ঘটনাগুলি শোনে এবং রেন্ডার রুটে বার্তা অর্পণ করে। প্রাসঙ্গিক রেন্ডারারের কাছে না পৌঁছানো পর্যন্ত গাছটি অতিক্রম করা হয়। এটি নিজেই (এবং সাধারণত এর বাচ্চাদের) পুনরায় রঙ করবে।

পেইন্টিং অর্ডার

CSS2 পেইন্টিং প্রক্রিয়ার ক্রম সংজ্ঞায়িত করে । এটি আসলে সেই ক্রম যাতে উপাদানগুলি স্ট্যাকিং প্রসঙ্গে স্ট্যাক করা হয়। এই ক্রমটি পেইন্টিংকে প্রভাবিত করে যেহেতু স্ট্যাকগুলি পিছনে থেকে সামনে আঁকা হয়। একটি ব্লক রেন্ডারারের স্ট্যাকিং অর্ডার হল:

  1. পেছনের রং
  2. ব্যাকগ্রাউন্ড ইমেজ
  3. সীমান্ত
  4. শিশু
  5. রূপরেখা

ফায়ারফক্স প্রদর্শন তালিকা

ফায়ারফক্স রেন্ডার ট্রির উপরে যায় এবং আঁকা আয়তক্ষেত্রাকার জন্য একটি প্রদর্শন তালিকা তৈরি করে। এতে আয়তক্ষেত্রাকার জন্য প্রাসঙ্গিক রেন্ডারার রয়েছে, সঠিক পেইন্টিং ক্রমে (রেন্ডারারের পটভূমি, তারপর সীমানা ইত্যাদি)।

এইভাবে গাছটিকে কয়েকবার না করে শুধুমাত্র একবার পুনরায় রং করার জন্য অতিক্রম করতে হবে - সমস্ত ব্যাকগ্রাউন্ড, তারপর সমস্ত ছবি, তারপর সমস্ত সীমানা ইত্যাদি আঁকা।

ফায়ারফক্স অন্যান্য অস্বচ্ছ উপাদানগুলির সম্পূর্ণ নীচে উপাদানগুলির মতো লুকানো উপাদানগুলি যোগ না করে প্রক্রিয়াটিকে অপ্টিমাইজ করে৷

ওয়েবকিট আয়তক্ষেত্র সঞ্চয়স্থান

পুনরায় রং করার আগে, ওয়েবকিট পুরানো আয়তক্ষেত্রটিকে বিটম্যাপ হিসাবে সংরক্ষণ করে। তারপরে এটি নতুন এবং পুরানো আয়তক্ষেত্রগুলির মধ্যে শুধুমাত্র ডেল্টা রঙ করে।

গতিশীল পরিবর্তন

ব্রাউজারগুলি পরিবর্তনের প্রতিক্রিয়া হিসাবে ন্যূনতম সম্ভাব্য ক্রিয়াগুলি করার চেষ্টা করে। তাই একটি উপাদানের রঙ পরিবর্তন শুধুমাত্র উপাদান পুনরায় রং ঘটাবে. উপাদানের অবস্থানে পরিবর্তনের ফলে উপাদানটির বিন্যাস এবং পুনরায় রং করা হবে, এর সন্তান এবং সম্ভবত ভাইবোন। একটি DOM নোড যোগ করার ফলে নোডের লেআউট এবং পুনরায় রং করা হবে। বড় পরিবর্তন, যেমন "html" উপাদানের ফন্টের আকার বাড়ানো, ক্যাশে, রিলেআউট এবং পুরো ট্রির পুনরায় রং করার কারণ হবে।

রেন্ডারিং ইঞ্জিনের থ্রেড

রেন্ডারিং ইঞ্জিন একক থ্রেডেড। নেটওয়ার্ক অপারেশন ব্যতীত প্রায় সবকিছুই একক থ্রেডে ঘটে। ফায়ারফক্স এবং সাফারিতে এটি ব্রাউজারের প্রধান থ্রেড। ক্রোমে এটি ট্যাব প্রক্রিয়া প্রধান থ্রেড.

নেটওয়ার্ক অপারেশনগুলি বেশ কয়েকটি সমান্তরাল থ্রেড দ্বারা সঞ্চালিত হতে পারে। সমান্তরাল সংযোগের সংখ্যা সীমিত (সাধারণত 2 - 6 সংযোগ)।

ইভেন্ট লুপ

ব্রাউজার প্রধান থ্রেড একটি ইভেন্ট লুপ. এটি একটি অসীম লুপ যা প্রক্রিয়াটিকে জীবিত রাখে। এটি ইভেন্টগুলির জন্য অপেক্ষা করে (যেমন লেআউট এবং পেইন্ট ইভেন্ট) এবং সেগুলি প্রক্রিয়া করে৷ এটি প্রধান ইভেন্ট লুপের জন্য ফায়ারফক্স কোড:

while (!mExiting)
    NS_ProcessNextEvent(thread);

CSS2 ভিজ্যুয়াল মডেল

ক্যানভাস

CSS2 স্পেসিফিকেশন অনুসারে, ক্যানভাস শব্দটি "সেই স্থান যেখানে ফর্ম্যাটিং কাঠামো রেন্ডার করা হয়" বর্ণনা করে: যেখানে ব্রাউজার সামগ্রীটি পেইন্ট করে।

স্থানের প্রতিটি মাত্রার জন্য ক্যানভাস অসীম কিন্তু ব্রাউজার ভিউপোর্টের মাত্রার উপর ভিত্তি করে একটি প্রাথমিক প্রস্থ বেছে নেয়।

www.w3.org/TR/CSS2/zindex.html অনুসারে, ক্যানভাসটি স্বচ্ছ হয় যদি অন্যটির মধ্যে থাকে এবং এটি না থাকলে একটি ব্রাউজারকে সংজ্ঞায়িত রঙ দেওয়া হয়।

সিএসএস বক্স মডেল

সিএসএস বক্স মডেল আয়তক্ষেত্রাকার বাক্সগুলি বর্ণনা করে যা নথি গাছের উপাদানগুলির জন্য তৈরি করা হয় এবং ভিজ্যুয়াল ফর্ম্যাটিং মডেল অনুসারে বিছিয়ে দেওয়া হয়।

প্রতিটি বাক্সে একটি বিষয়বস্তু এলাকা (যেমন পাঠ্য, একটি চিত্র, ইত্যাদি) এবং ঐচ্ছিক পার্শ্ববর্তী প্যাডিং, সীমানা এবং মার্জিন এলাকা রয়েছে।

CSS2 বক্স মডেল
চিত্র 19: CSS2 বক্স মডেল

প্রতিটি নোড 0…n এরকম বক্স তৈরি করে।

সমস্ত উপাদানের একটি "প্রদর্শন" বৈশিষ্ট্য রয়েছে যা বাক্সের ধরণ নির্ধারণ করে যা তৈরি করা হবে।

উদাহরণ:

block: generates a block box.
inline: generates one or more inline boxes.
none: no box is generated.

ডিফল্ট ইনলাইন কিন্তু ব্রাউজার স্টাইল শীট অন্য ডিফল্ট সেট করতে পারে। উদাহরণস্বরূপ: "div" উপাদানের জন্য ডিফল্ট প্রদর্শন হল ব্লক।

আপনি এখানে একটি ডিফল্ট স্টাইল শীট উদাহরণ পেতে পারেন: www.w3.org/TR/CSS2/sample.html

পজিশনিং স্কিম

তিনটি স্কিম আছে:

  1. সাধারণ: নথিতে বস্তুটি তার স্থান অনুযায়ী অবস্থান করা হয়। এর মানে রেন্ডার ট্রিতে এর স্থানটি DOM গাছের জায়গার মতো এবং এটির বাক্সের ধরন এবং মাত্রা অনুসারে বিন্যস্ত
  2. ফ্লোট: বস্তুটি প্রথমে স্বাভাবিক প্রবাহের মতো স্থাপন করা হয়, তারপর যতটা সম্ভব বাম বা ডানদিকে সরানো হয়
  3. পরম: বস্তুটিকে রেন্ডার ট্রিতে DOM গাছের চেয়ে আলাদা জায়গায় রাখা হয়

পজিশনিং স্কিম "অবস্থান" বৈশিষ্ট্য এবং "ফ্লোট" বৈশিষ্ট্য দ্বারা সেট করা হয়।

  • স্থির এবং আপেক্ষিক একটি স্বাভাবিক প্রবাহ ঘটায়
  • পরম এবং স্থির কারণ পরম অবস্থান

স্ট্যাটিক পজিশনিং এ কোন পজিশন সংজ্ঞায়িত করা হয় না এবং ডিফল্ট পজিশনিং ব্যবহার করা হয়। অন্যান্য স্কিমগুলিতে, লেখক অবস্থানটি নির্দিষ্ট করে: উপরে, নীচে, বাম, ডান।

বাক্সটি যেভাবে স্থাপন করা হয় তা দ্বারা নির্ধারিত হয়:

  • বক্স টাইপ
  • বাক্সের মাত্রা
  • পজিশনিং স্কিম
  • বাহ্যিক তথ্য যেমন ছবির আকার এবং পর্দার আকার

বাক্সের ধরন

ব্লক বক্স: একটি ব্লক গঠন করে - ব্রাউজার উইন্ডোতে এর নিজস্ব আয়তক্ষেত্র রয়েছে।

ব্লক বক্স।
চিত্র 20: ব্লক বক্স

ইনলাইন বক্স: এর নিজস্ব ব্লক নেই, তবে একটি ধারণকারী ব্লকের ভিতরে রয়েছে।

ইনলাইন বাক্স.
চিত্র 21: ইনলাইন বাক্স

ব্লকগুলি একের পর এক উল্লম্বভাবে ফর্ম্যাট করা হয়। ইনলাইনগুলি অনুভূমিকভাবে বিন্যাসিত হয়৷

ব্লক এবং ইনলাইন বিন্যাস.
চিত্র 22: ব্লক এবং ইনলাইন বিন্যাস

ইনলাইন বাক্সগুলি লাইন বা "লাইন বক্স" এর ভিতরে রাখা হয়। রেখাগুলি অন্তত লম্বা বাক্সের মতো লম্বা কিন্তু লম্বা হতে পারে, যখন বাক্সগুলিকে "বেসলাইন" সারিবদ্ধ করা হয় - যার অর্থ হল একটি উপাদানের নীচের অংশটি অন্য একটি বাক্সের একটি বিন্দুতে সারিবদ্ধ থাকে তারপর নীচের দিকে৷ যদি ধারক প্রস্থ যথেষ্ট না হয়, ইনলাইনগুলি বেশ কয়েকটি লাইনে স্থাপন করা হবে। এটি সাধারণত একটি অনুচ্ছেদে ঘটে।

লাইন।
চিত্র 23: লাইন

পজিশনিং

আপেক্ষিক

আপেক্ষিক অবস্থান - স্বাভাবিকের মতো অবস্থান এবং তারপর প্রয়োজনীয় ব-দ্বীপ দ্বারা সরানো।

আপেক্ষিক অবস্থান।
চিত্র 24: আপেক্ষিক অবস্থান

ভাসছে

একটি ফ্লোট বক্স একটি লাইনের বাম বা ডানে স্থানান্তরিত হয়। আকর্ষণীয় বৈশিষ্ট্য হল অন্যান্য বাক্সগুলি এটির চারপাশে প্রবাহিত হয়। এইচটিএমএল:

<p>
  <img style="float: right" src="images/image.gif" width="100" height="100">
  Lorem ipsum dolor sit amet, consectetuer...
</p>

এর মত দেখাবে:

ভাসা.
চিত্র 25: ভাসা

পরম এবং স্থির

বিন্যাস স্বাভাবিক প্রবাহ নির্বিশেষে ঠিক সংজ্ঞায়িত করা হয়. উপাদানটি স্বাভাবিক প্রবাহে অংশগ্রহণ করে না। মাত্রা ধারক আপেক্ষিক হয়. স্থির, ধারক হল ভিউপোর্ট।

স্থির অবস্থান।
চিত্র 26: স্থির অবস্থান

স্তরপূর্ণ উপস্থাপনা

এটি z-index CSS প্রপার্টি দ্বারা নির্দিষ্ট করা হয়েছে। এটি বাক্সের তৃতীয় মাত্রা উপস্থাপন করে: "z অক্ষ" বরাবর এর অবস্থান।

বাক্সগুলি স্ট্যাকগুলিতে বিভক্ত (যাকে স্ট্যাকিং প্রসঙ্গ বলা হয়)। প্রতিটি স্ট্যাকের মধ্যে পিছনের উপাদানগুলি প্রথমে আঁকা হবে এবং সামনের উপাদানগুলি উপরে, ব্যবহারকারীর কাছাকাছি। ওভারল্যাপের ক্ষেত্রে অগ্রণী উপাদানটি পূর্বের উপাদানটিকে লুকিয়ে রাখবে।

স্ট্যাকগুলি z-সূচক সম্পত্তি অনুসারে অর্ডার করা হয়েছে। "z-index" বৈশিষ্ট্য সহ বাক্সগুলি একটি স্থানীয় স্ট্যাক তৈরি করে। ভিউপোর্টের বাইরের স্ট্যাক আছে।

উদাহরণ:

<style type="text/css">
  div {
    position: absolute;
    left: 2in;
    top: 2in;
  }
</style>

<p>
  <div
    style="z-index: 3;background-color:red; width: 1in; height: 1in; ">
  </div>
  <div
    style="z-index: 1;background-color:green;width: 2in; height: 2in;">
  </div>
</p>

ফলাফল এই হবে:

স্থির অবস্থান।
চিত্র 27: স্থির অবস্থান

যদিও লাল ডিভ মার্কআপে সবুজ রঙের আগে থাকে, এবং নিয়মিত প্রবাহে আগে আঁকা হত, z-সূচক বৈশিষ্ট্য বেশি, তাই এটি রুট বক্সের দ্বারা রাখা স্ট্যাকের মধ্যে আরও এগিয়ে থাকে।

সম্পদ

  1. ব্রাউজার আর্কিটেকচার

    1. গ্রসকার্থ, অ্যালান। ওয়েব ব্রাউজারগুলির জন্য একটি রেফারেন্স আর্কিটেকচার (পিডিএফ)
    2. গুপ্তা, বিনীত। কিভাবে ব্রাউজার কাজ করে - পার্ট 1 - আর্কিটেকচার
  2. পার্সিং

    1. আহো, শেঠি, উলম্যান, কম্পাইলার: প্রিন্সিপলস, টেকনিকস এবং টুলস (ওরফে "ড্রাগন বই"), অ্যাডিসন-ওয়েসলি, 1986
    2. রিক জেলিফ। দ্য বোল্ড অ্যান্ড দ্য বিউটিফুল: HTML 5-এর জন্য দুটি নতুন খসড়া।
  3. ফায়ারফক্স

    1. এল. ডেভিড ব্যারন, দ্রুত এইচটিএমএল এবং সিএসএস: ওয়েব ডেভেলপারদের জন্য লেআউট ইঞ্জিন অভ্যন্তরীণ।
    2. এল. ডেভিড ব্যারন, দ্রুত এইচটিএমএল এবং সিএসএস: ওয়েব ডেভেলপারদের জন্য লেআউট ইঞ্জিন ইন্টারনাল (গুগল টেক টক ভিডিও)
    3. এল. ডেভিড ব্যারন, মজিলার লেআউট ইঞ্জিন
    4. এল. ডেভিড ব্যারন, মজিলা স্টাইল সিস্টেম ডকুমেন্টেশন
    5. ক্রিস ওয়াটারসন, এইচটিএমএল রিফ্লোতে নোট
    6. ক্রিস ওয়াটারসন, গেকো ওভারভিউ
    7. আলেকজান্ডার লারসন, একটি HTML HTTP অনুরোধের জীবন
  4. ওয়েবকিট

    1. ডেভিড হায়াত, সিএসএস বাস্তবায়ন (পার্ট 1)
    2. ডেভিড হায়াত, ওয়েবকোরের একটি ওভারভিউ
    3. ডেভিড হায়াত, ওয়েবকোর রেন্ডারিং
    4. ডেভিড হায়াত, FOUC সমস্যা
  5. W3C স্পেসিফিকেশন

    1. HTML 4.01 স্পেসিফিকেশন
    2. W3C HTML5 স্পেসিফিকেশন
    3. ক্যাসকেডিং স্টাইল শীট লেভেল 2 রিভিশন 1 (CSS 2.1) স্পেসিফিকেশন
  6. ব্রাউজার নির্দেশাবলী নির্মাণ

    1. ফায়ারফক্স। https://developer.mozilla.org/Build_Documentation
    2. ওয়েবকিট। http://webkit.org/building/build.html

অনুবাদ

এই পৃষ্ঠাটি জাপানি ভাষায় দুইবার অনুবাদ করা হয়েছে:

আপনি কোরিয়ান এবং তুর্কি ভাষার বাহ্যিকভাবে হোস্ট করা অনুবাদগুলি দেখতে পারেন।

ধন্যবাদ সবাইকে!