ਕੁਝ ਸਾਲ ਪਹਿਲਾਂ, ਮੈਂ ਇੱਕ ਡੈਸ਼ਬੋਰਡ ਬਣਾਉਣ ਲਈ ਬੈਠਾ ਸੀ। ਕੁਝ ਖਾਸ ਨਹੀਂ—ਬਸ ਇੱਕ ਫਿਕਸਡ ਸਾਈਡਬਾਰ (sidebar), ਇੱਕ ਮੁੱਖ ਕੰਟੈਂਟ ਏਰੀਆ, ਅਤੇ ਇੱਕ ਫੁੱਟਰ (footer)। Flexbox ਇੱਕ ਸਪੱਸ਼ਟ ਚੋਣ ਲੱਗ ਰਹੀ ਸੀ, ਅਤੇ ਸ਼ੁਰੂ ਵਿੱਚ, ਇਹ ਸਹੀ ਕੰਮ ਕਰ ਰਿਹਾ ਸੀ। ਫਿਰ ਮੈਂ ਮੁੱਖ ਸੈਕਸ਼ਨ ਵਿੱਚ ਕਾਰਡਾਂ ਦੀ ਇੱਕ ਲਾਈਨ ਪਾਈ। ਪੂਰਾ ਲੇਆਉਟ (layout) ਵਿਗੜ ਗਿਆ। ਮੈਂ ਅਗਲੇ ਤਿੰਨ ਘੰਟੇ flex-grow ਰੇਸ਼ੀਓ ਅਤੇ ਨੈਸਟਡ ਪ੍ਰਤੀਸ਼ਤ ਚੌੜਾਈਆਂ (nested percentage widths) ਨਾਲ ਲੜਦਿਆਂ ਬਿਤਾਏ, ਅਤੇ ਦੇਖਿਆ ਕਿ ਕਿੰਨਾ ਵੀ ਪੈਡਿੰਗ ਘਟਾਉਣ ਦੇ ਬਾਵਜੂਦ ਕੰਟੇਨਰ ਸਹੀ ਤਰ੍ਹਾਂ ਲਾਈਨ ਵਿੱਚ ਨਹੀਂ ਆ ਰਹੇ ਸਨ। ਪੇਜ ਅਜਿਹਾ ਲੱਗ ਰਿਹਾ ਸੀ ਜਿਵੇਂ ਕੋਈ ਟਾਵਰ ਡਿੱਗਣ ਹੀ ਵਾਲਾ ਹੋਵੇ।
ਇਸ ਕਠੋਰ ਅਨੁਭਵ ਨੇ ਮੈਨੂੰ ਆਧੁਨਿਕ CSS ਲੇਆਉਟ ਬਾਰੇ ਸਭ ਤੋਂ ਮਹੱਤਵਪੂਰਨ ਗੱਲ ਸਿਖਾਈ: Flexbox ਅਤੇ Grid ਇੱਕ ਦੂਜੇ ਦੇ ਵਿਰੋਧੀ ਨਹੀਂ ਹਨ। ਉਹ ਵੱਖ-ਵੱਖ ਕੰਮਾਂ ਲਈ ਸੰਦ ਹਨ, ਅਤੇ ਜ਼ਿਆਦਾਤਰ ਫੇਲ ਹੋਏ ਲੇਆਉਟ ਗਲਤ ਸੰਦ ਦੀ ਚੋਣ ਕਰਨ ਕਾਰਨ ਹੁੰਦੇ ਹਨ।
ਅੰਤਰ ਡਾਇਮੈਂਸ਼ਨਲ (Dimensional) ਹੈ
Flexbox ਨੂੰ ਇੱਕ ਗਲਿਆਰੇ ਵਾਂਗ ਸਮਝੋ। ਚੀਜ਼ਾਂ ਇੱਕ ਦਿਸ਼ਾ ਵਿੱਚ ਵਹਿੰਦੀਆਂ ਹਨ, ਜਾਂ ਤਾਂ ਇੱਕ ਰੋਅ (row) ਵਜੋਂ ਜਾਂ ਇੱਕ ਕਾਲਮ (column) ਵਜੋਂ। ਇਹ ਇੱਕ-ਆਯਾਮੀ (one-dimensional) ਵੰਡ ਲਈ ਬਣਾਇਆ ਗਿਆ ਹੈ। ਬ੍ਰਾਊਜ਼ਰ ਕੰਟੈਂਟ ਨੂੰ ਦੇਖਦਾ ਹੈ, ਅਤੇ ਫਿਰ ਫੈਸਲਾ ਕਰਦਾ ਹੈ ਕਿ ਉਸਨੂੰ ਉਸ ਸਿੰਗਲ ਐਕਸਿਸ (axis) ਦੇ ਨਾਲ ਕਿਵੇਂ ਖਿੱਚਣਾ, ਸੁੰਘੜਨਾ ਜਾਂ ਅਲਾਈਨ ਕਰਨਾ ਹੈ। ਇਹ Flexbox ਨੂੰ ਉਹਨਾਂ ਸਥਿਤੀਆਂ ਲਈ ਸੰਪੂਰਨ ਬਣਾਉਂਦਾ ਹੈ ਜਿੱਥੇ ਕੰਟੈਂਟ ਲੇਆਉਟ ਨੂੰ ਨਿਰਧਾਰਤ ਕਰਦਾ ਹੈ। ਇੱਕ ਨੈਵੀਗੇਸ਼ਨ ਬਾਰ, ਫਾਰਮ ਫੀਲਡਾਂ ਦਾ ਇੱਕ ਸਟੈਕ, ਜਾਂ ਟੈਗਸ ਦਾ ਇੱਕ ਸਮੂਹ ਜਿਨ੍ਹਾਂ ਨੂੰ ਬਰਾਬਰ ਸਪੇਸਿੰਗ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ, ਸਾਰੇ ਇੱਕ flex ਕੰਟੇਨਰ ਵਿੱਚ ਕੁਦਰਤੀ ਤੌਰ 'ਤੇ ਸੈੱਟ ਹੋ ਜਾਂਦੇ ਹਨ ਕਿਉਂਕਿ ਉਹ ਇੱਕੋ ਤਰ੍ਹਾਂ ਦੇ ਲੌਜਿਕ ਨੂੰ ਸਾਂਝਾ ਕਰਦੇ ਹਨ।
ਦੂਜੇ ਪਾਸੇ, Grid ਇੱਕ ਫਲੋਰ ਪਲਾਨ ਹੈ। ਇਹ ਸਖ਼ਤੀ ਨਾਲ ਦੋ-ਆਯਾਮੀ (two-dimensional) ਹੈ, ਜੋ ਰੋਅ ਅਤੇ ਕਾਲਮ ਨੂੰ ਇੱਕੋ ਸਮੇਂ ਸੰਭਾਲਦਾ ਹੈ। ਤੁਸੀਂ ਪਹਿਲਾਂ ਢਾਂਚਾ (structure) ਪਰਿਭਾਸ਼ਿਤ ਕਰਦੇ ਹੋ, ਫਿਰ ਤੁਸੀਂ ਇਸਦੇ ਅੰਦਰ ਚੀਜ਼ਾਂ ਰੱਖਦੇ ਹੋ। ਇਹ Grid ਨੂੰ ਪੂਰੇ ਪੇਜ ਦੀ ਬਣਤਰ (architecture) ਲਈ ਆਦਰਸ਼ ਬਣਾਉਂਦਾ ਹੈ—ਉੱਥੇ ਜਿੱਥੇ ਤੁਹਾਨੂੰ ਵਰਟੀਕਲ ਅਤੇ ਹੋਰੀਜ਼ੋਂਟਲ ਪੋਜੀਸ਼ਨਿੰਗ ਨੂੰ ਇਕੱਠੇ ਕੰਟਰੋਲ ਕਰਨ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ। ਜਦੋਂ ਤੁਸੀਂ ਨੈਸਟਡ Flexbox ਕੰਟੇਨਰਾਂ ਰਾਹੀਂ ਇੱਕ ਗੁੰਝਲਦਾਰ ਦੋ-ਆਯਾਮੀ ਡਿਜ਼ਾਈਨ ਨੂੰ ਲਾਗੂ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਡੇ ਕੋਲ ਡੂੰਘਾ ਮਾਰਕਅੱਪ, ਨਾਜ਼ੁਕ ਵੈਪਰਜ਼ (wrappers), ਅਤੇ ਅਜਿਹਾ ਗਣਿਤ ਬਚਦਾ ਹੈ ਜੋ ਇੱਕ ਵਾਧੂ ਐਲੀਮੈਂਟ ਜੋੜਦੇ ਹੀ ਟੁੱਟ ਜਾਂਦਾ ਹੈ।
Flexbox ਅਜੇ ਵੀ ਆਪਣੀ ਮਹੱਤਤਾ ਬਣਾਈ ਰੱਖਦਾ ਹੈ
ਹਰ flex ਕੰਟੇਨਰ ਨੂੰ Grid ਨਾਲ ਬਦਲਣ ਦੀ ਕਾਹਲੀ ਨਾ ਕਰੋ। ਵਿਅਕਤੀਗਤ ਕੰਪੋਨੈਂਟਸ ਦੇ ਅੰਦਰ, Flexbox ਅਕਸਰ ਵਧੇਰੇ ਸਾਫ਼ ਅਤੇ ਸਹੀ ਹੁੰਦਾ ਹੈ। ਜੇਕਰ ਤੁਹਾਡੇ ਕੋਲ ਦੋ ਬਟਨਾਂ ਵਾਲਾ ਇੱਕ ਕਾਰਡ ਫੁੱਟਰ ਹੈ ਅਤੇ ਤੁਸੀਂ ਇੱਕ ਨੂੰ ਖੱਬੇ ਅਤੇ ਇੱਕ ਨੂੰ ਸੱਜੇ ਅਲਾਈਨ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ, ਤਾਂ justify-content: space-between ਉਹੀ ਕਰਦਾ ਹੈ ਜੋ ਤੁਸੀਂ ਚਾਹੁੰਦੇ ਹੋ। ਜੇਕਰ ਤੁਹਾਨੂੰ ਅਣਜਾਣ ਉਚਾਈ ਵਾਲੇ ਬਟਨ ਦੇ ਅੰਦਰ ਇੱਕ ਆਈਕਨ ਨੂੰ ਵਰਟੀਕਲ ਰੂਪ ਵਿੱਚ ਕੇਂਦਰਿਤ ਕਰਨ ਦੀ ਲੋੜ ਹੈ, ਤਾਂ align-items: center ਸਭ ਤੋਂ ਸੌਖਾ ਰਸਤਾ ਹੈ। ਵੇਰੀਏਬਲ ਕੰਟੈਂਟ—ਜਿਵੇਂ ਕਿ ਵੱਖ-ਵੱਖ ਨਾਮ ਦੀ ਲੰਬਾਈ ਵਾਲੇ ਯੂਜ਼ਰ ਬੈਜਾਂ ਦੀ ਇੱਕ ਰੋਅ—Flexbox ਦੇ ਅੰਦਰ ਆਰਾਮ ਨਾਲ ਫਿੱਟ ਹੋ ਜਾਂਦੀ ਹੈ ਕਿਉਂਕਿ ਇਹ content-first ਹੈ। ਕੰਟੇਨਰ ਉਸਦੇ ਅੰਦਰਲੇ ਕੰਟੈਂਟ ਅਨੁਸਾਰ ਆਪਣੇ ਆਪ ਨੂੰ ਢਾਲ ਲੈਂਦਾ ਹੈ।
Grid container-first ਹੈ। ਤੁਸੀਂ ਬ੍ਰਾਊਜ਼ਰ ਨੂੰ ਦੱਸਦੇ ਹੋ ਕਿ ਕਿੰਨੇ ਟ੍ਰੈਕਸ (tracks) ਹਨ ਅਤੇ ਉਹ ਕਿੰਨੇ ਵੱਡੇ ਹੋਣੇ ਚਾਹੀਦੇ ਹਨ, ਫਿਰ ਤੁਸੀਂ ਉਹਨਾਂ ਸੈੱਲਾਂ ਵਿੱਚ ਚੀਜ਼ਾਂ ਪਾਉਂਦੇ ਹੋ। ਜੇਕਰ ਤੁਹਾਡਾ ਲੇਆਉਟ ਸਿਰਫ਼ ਸਪੇਸ ਸਾਂਝਾ ਕਰਨ ਵਾਲੀਆਂ ਭੈਣ-ਭਰਾ ਚੀਜ਼ਾਂ (siblings) ਦੀ ਇੱਕ ਸਿੰਗਲ ਲਾਈਨ ਹੈ, ਤਾਂ Grid ਬੇਲੋੜੀ ਗੁੰਝਲ ਪੈਦਾ ਕਰਦਾ ਹੈ।
ਪੇਜ ਲੇਆਉਟ Grid ਦਾ ਹੈ
ਇੱਥੇ Grid ਕੰਮ ਸੰਭਾਲ ਲੈਂਦਾ ਹੈ। ਮੇਰਾ ਡੈਸ਼ਬੋਰਡ ਡਰਾਵਾਣਾ ਸੁਪਨਾ ਯਾਦ ਹੈ? ਇੱਥੇ ਦਿੱਤਾ ਗਿਆ ਹੈ ਕਿ ਢਾਂਚਾ ਸ਼ੁਰੂ ਤੋਂ ਹੀ ਕਿਹੋ ਜਿਹਾ ਹੋਣਾ ਚਾਹੀਦਾ ਸੀ:
.page {
display: grid;
min-height: 100vh;
grid-template-rows: auto 1fr auto;
grid-template-columns: 200px 1fr;
}
.header { grid-row: 1; grid-column: 1 / -1; }
.sidebar { grid-row: 2; grid-column: 1; }
.main { grid-row: 2; grid-column: 2; }
.footer { grid-row: 3; grid-column: 1 / -1; }
ਦੇਖੋ ਕੀ ਹੋ ਰਿਹਾ ਹੈ। .page ਕੰਟੇਨਰ ਤਿੰਨ ਰੋਅ ਅਤੇ ਦੋ ਕਾਲਮ ਸਥਾਪਿਤ ਕਰਦਾ ਹੈ। ਪਹਿਲੀ ਰੋਅ auto ਦੀ ਮਦਦ ਨਾਲ ਆਪਣੇ ਆਪ ਨੂੰ ਹੈਡਰ ਦੇ ਕੰਟੈਂਟ ਦੇ ਅਨੁਸਾਰ ਸੈੱਟ ਕਰ ਲੈਂਦੀ ਹੈ। ਵਿਚਕਾਰਲੀ ਰੋਅ 1fr ਨਾਲ ਬਾਕੀ ਬਚਿਆ ਸਾਰਾ ਖਾਲੀ ਸਪੇਸ ਲੈ ਲੈਂਦੀ ਹੈ। ਫੁੱਟਰ ਆਖਰੀ ਰੋਅ ਵਿੱਚ ਆ ਜਾਂਦਾ ਹੈ, ਜੋ ਆਪਣੇ ਕੰਟੈਂਟ ਦੇ ਅਨੁਸਾਰ ਸਾਈਜ਼ ਹੁੰਦਾ ਹੈ। ਇਸ ਦੌਰਾਨ, ਸਾਈਡਬਾਰ 200 ਪਿਕਸਲ ਚੌੜਾ ਫਿਕਸ ਰਹਿੰਦਾ ਹੈ, ਅਤੇ ਮੁੱਖ ਏਰੀਆ ਬਾਕੀ ਸਾਰਾ ਹਿੱਸਾ ਭਰ ਲੈਂਦਾ ਹੈ।
ਪਲੇਸਮੈਂਟ ਲੌਜਿਕ ਅਸਲ ਰਾਹਤ ਹੈ। ਹੈਡਰ ਕਾਲਮ ਲਾਈਨ 1 ਤੋਂ ਲਾਈਨ -1 ਤੱਕ ਫੈਲਿਆ ਹੋਇਆ ਹੈ, ਜਿਸਦਾ ਮਤਲਬ ਹੈ ਕਿ ਇਹ ਦੋਵਾਂ ਕਾਲਮਾਂ ਵਿੱਚ ਫੈਲਿਆ ਹੋਇਆ ਹੈ, ਭਾਵੇਂ ਤੁਸੀਂ ਬਾਅਦ ਵਿੱਚ ਕਿੰਨੇ ਵੀ ਕਾਲਮ ਜੋੜੋ। ਸਾਈਡਬਾਰ ਅਤੇ ਮੁੱਖ ਕੰਟੈਂਟ ਰੋਅ 2 ਸਾਂਝੀ ਕਰਦੇ ਹਨ ਪਰ ਵੱਖਰੇ ਕਾਲਮਾਂ ਵਿੱਚ ਹੁੰਦੇ ਹਨ। ਫੁੱਟਰ ਰੋਅ 3 ਵਿੱਚ ਪੂਰੀ ਚੌੜਾਈ ਵਿੱਚ ਵਾਪਸ ਆ ਜਾਂਦਾ ਹੈ। ਤੁਹਾਨੂੰ ਬੱਚਿਆਂ (children) 'ਤੇ ਪ੍ਰਤੀਸ਼ਤ ਗਣਿਤ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ। ਤੁਹਾਨੂੰ ਉਚਾਈ ਲਈ ਲੜਦੇ ਹੋਏ ਨੈਸਟਡ ਵੈਪਰਜ਼ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ। ਸਿਰਫ਼ ਇੱਕ ਜਗ੍ਹਾ 'ਤੇ ਸਾਈਡਬਾਰ ਦੀ ਚੌੜਾਈ ਬਦਲੋ, ਅਤੇ ਮੁੱਖ ਏਰੀਆ ਆਪਣੇ ਆਪ ਐਡਜਸਟ ਹੋ ਜਾਵੇਗਾ। ਪੂਰਾ ਲੇਆਉਟ ਇੱਕ ਸਿੰਗਲ ਸਿਸਟਮ ਵਜੋਂ ਸਾਹ ਲੈਂਦਾ ਹੈ।
grid-template-areas ਨਾਲ ਪੜ੍ਹਨਯੋਗਤਾ
ਹੋਰ ਵੀ ਸਪੱਸ਼ਟਤਾ ਲਈ, ਤੁਸੀਂ ਆਪਣੇ ਸੈਕਸ਼ਨਾਂ ਨੂੰ ਨਾਮ ਦੇ ਸਕਦੇ ਹੋ। ਲਾਈਨ ਨੰਬਰਾਂ ਨੂੰ ਪ੍ਰਬੰਧਿਤ ਕਰਨ ਦੀ ਬਜਾਏ, ਤੁਸੀਂ ਇੱਕ ਵਿਜ਼ੂਅਲ ਮੈਪ ਲਿਖਦੇ ਹੋ:
.page {
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
.header { grid-area: header; }
.main { grid-area: main; }
ਹੁਣ ਤੁਹਾਡੀ ਸਟਾਈਲਸ਼ੀਟ ਇੱਕ ਵਾਈਰਫਰੇਮ (wireframe) ਵਾਂਗ ਪੜ੍ਹੀ ਜਾ ਸਕਦੀ ਹੈ। ਜੇਕਰ ਤੁਸੀਂ ਕਦੇ ਕਿਸੇ ਵੱਖਰੇ ਬ੍ਰੇਕਪੁਆਇੰਟ (breakpoint) ਲਈ ਸਾਈਡਬਾਰ ਨੂੰ ਸੱਜੇ ਪਾਸੇ ਦਿਖਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ, ਤਾਂ ਤੁਸੀਂ ਟੈਂਪਲੇਟ ਸਟ੍ਰਿੰਗ ਵਿੱਚ ਦੋ ਸ਼ਬਦ ਬਦਲ ਦਿੰਦੇ ਹੋ। ਇਸ ਤਰ੍ਹਾਂ ਦੀ ਸਟ੍ਰਕਚਰਲ ਪੜ੍ਹਨਯੋਗਤਾ ਨੈਸਟਡ ਫਲੈਕਸ ਕੰਟੇਨਰਾਂ ਦੇ ਢਾਂਚੇ ਦੇ ਅੰਦਰ ਪ੍ਰਾਪਤ ਕਰਨਾ ਅਸੰਭਵ ਹੈ।
ਦੋ ਸਖ਼ਤ ਸਬਕ
Grid ਕੋਈ ਜਾਦੂ ਨਹੀਂ ਹੈ। ਦੋ ਅਜਿਹੀਆਂ ਗਲਤੀਆਂ ਹਨ ਜੋ ਤੁਹਾਡੇ ਲੇਆਉਟ ਨੂੰ ਜਲਦੀ ਖ਼ਰਾਬ ਕਰ ਸਕਦੀਆਂ ਹਨ।
ਪਹਿਲੀ ਗਲਤੀ ਯੂਨਿਟ ਦੀ ਲਾਪਰਵਾਹੀ ਨਾਲ ਵਰਤੋਂ ਕਰਨਾ ਹੈ। ਜੇਕਰ ਤੁਸੀਂ grid-template-columns: 1fr 1fr 1fr ਪਰਿਭਾਸ਼ਿਤ ਕਰਦੇ ਹੋ ਪਰ ਤੁਹਾਡੇ ਡਿਜ਼ਾਈਨ ਨੂੰ ਸਿਰਫ਼ ਕੰਟੈਂਟ ਦੇ ਦੋ ਕਾਲਮਾਂ ਦੀ ਲੋੜ ਹੈ, ਤਾਂ ਉਹ ਤੀਜਾ ਟ੍ਰੈਕ ਅਜੇ ਵੀ ਮੌਜੂਦ ਰਹੇਗਾ। ਇਹ ਜਾਂ ਤਾਂ ਖਾਲੀ ਰਹੇਗਾ ਅਤੇ ਇੱਕ ਅਜਿਹਾ ਅੰਤਰਾਲ (gap) ਬਣਾਏਗਾ ਜਿਸਦੀ ਤੁਸੀਂ ਉਮੀਦ ਨਹੀਂ ਕੀਤੀ ਸੀ, ਜਾਂ ਇਹ ਤੁਹਾਡੇ ਅਸਲ ਕੰਟੈਂਟ ਨੂੰ ਅਜਿਹੇ ਤਰੀਕੇ ਨਾਲ ਦਬਾਉਣ ਲਈ ਮਜਬੂਰ ਕਰੇਗਾ ਜੋ ਤੁਹਾਡੇ ਡਿਜ਼ਾਈਨ ਨੂੰ ਵਿਗਾੜ ਦੇਵੇਗਾ। ਸੋਚ-ਸਮਝ ਕੇ ਕੰਮ ਕਰੋ। ਜਦੋਂ ਤੁਹਾਡਾ ਮਤਲਬ ਦੋ ਕਾਲਮਾਂ ਤੋਂ ਹੋਵੇ, ਤਾਂ repeat(2, 1fr) ਲਿਖੋ।
