Css z-index

Алан-э-Дейл       10.03.2024 г.

Введение в контекст наложения

Второе условие еще более непонятно: действие  ограничено контекстом наложения, который включает в себя корневой html-узел и всех его потомков.

Базовый контекст наложения создается узлом . По умолчанию к нему принадлежат и все остальные элементы в документе. Однако любой из них также может стать корневым узлом локального контекста.

Создать новый контекст можно несколькими способами:

  • установить абсолютное или относительное позиционирование, а также любой  кроме ;
  • установить фиксированное позиционирование ( или );
  • установить прозрачность меньше 1;
  • использовать свойства или .

Полный список способов создания контекстов можно найти на MDN.

Рассмотрим три HTML-дерева. Нижняя часть — это корневой узел, а потомки уложены сверху. Предположим, что все три корня находятся прямо внутри .

Это будет выглядеть примерно так:

See the Pen
by Benjamin Johnson (@benjaminj6)
on CodePen.

Не ожидали?

Прежде всего, почему находится внизу? Ведь его равен миллиону, он должен самым верхним, не так ли?

Почему наверху, хотя его всего 2? Разве больший индекс не должен перекрывать меньший?

Начнем с . Его родитель — — имеет , поэтому мы предполагаем, что он поднимется на самый верх. Но не влияет на элементы с . Это означает, что является частью корневого контекста наложения, в котором, кроме него, есть еще и . Он имеет более высокий , чем они, поэтому находится выше.

Красный и синий корневые блоки создают собственные локальные контексты наложения. Почему находится ниже, чем , несмотря на больший ? Дело в том, что это свойство управляет положением слоя только в локальном контексте. , безусловно, будет выше всех дочерних элементов . Но контекст выше, чем контекст , поэтому все красные потомки всегда будут выше синих.

Чтобы поднять выше придется изменить структуру HTML и извлечь его из локального контекста наложения в корневой (или в другой локальный, который будет выше красного). Но помните, что такие изменения в больших проектах могут привести к непредвиденным последствиям.

Многие библиотеки компонентов используют интерфейс с большим количеством слоев (всплывающие подсказки, модальные окна), добавляя их к тегу , а не внутрь самого компонента. Это позволяет обойти подводные камни стека наложения и гарантирует, что нужные элементы всегда будут на самом верху.

Позиционирование с применением z-index

Если теперь мы хотим изменить порядок расположения элементов, мы можем использовать CSS-свойство z-index. Элемент с более высоким z-индексом будет отображаться перед элементом с более низким z-индексом. Следует отметить, что z-индекс работает только с позиционируемыми элементами.

.blue, .pink, .orange {
  position: absolute;
}

.blue {
z-index: 2;
}

.orange {
z-index: 3;
}

.green {
z-index: 100; // has no effect since the green box is non- positioned
}

Перед синим квадратом отображается оранжевый квадрат, потому что он имеет более высокий z-index.

Top Tip: Think About Your z-index Elements In Advance When Planning Your Website

When creating a website, you might find yourself with a number of different elements that will need to be layered and overlap on the same page, sometimes at the same time.

Start Planning

It’s worth planning in advance the order in which your z-index elements should take precedence. For example, should your popup box be able to overlap your navigation element? Or should it be the other way around.

I say this because a lot of developers will automatically set the z-index of an element to a high number (something like 999) and this okay because it’s definitely going to overlap the page with such a high value, but doesn’t take into account scenarios where you have two or more overlapping elements action and open at the same time.

Let me hammer home that point in meme form:

This might not ever be a scenario you need to worry about, but if you think it might be then it’s a good idea to come up with a more sensible z-index valuation system.

For example, you can always image the base layer of your website to have a z-index value of 0. Set the next value you’d like to overlap to have a z-index value of 1. If then you decide you need another element to overlap and it’s more important to the user to display it over the top of the previous overlapping element, then set it to 2 and so on.

This way, you can always guaranteed the right overlay will be displayed to the user.

Conclusion

Stacking contexts in CSS are a complex topic. This article did not attempt to discuss every detail on that topic, but instead has attempted to provide a solid discussion of how a web page’s stacking contexts are affected by , which, when fully understood, becomes a powerful CSS property.

Beginning developers should now have a good understanding of this property and avoid some of the common problems that arise when trying to implement it. Additionally, advanced developers should have a stronger understanding of how proper use of can provide solutions to countless layout issues and open doors to a number of creative possibilities in CSS design.

Creating a stacking context #

You don’t need to apply and to create a new stacking context. You can create a new stacking context by adding a value for properties which create a new composite layer such as , and . You can see a full list of properties here.

To explain what a composite layer is, imagine a web page is a canvas. A browser takes your HTML and CSS and uses these to work out how big to make the canvas. It then paints the page on this canvas. If an element was to change—say, it changes position—the browser then has to go back and re-work out what to paint.

To help with performance, the browser creates new composite layers which are layered on top of the canvas. These are a bit like post-it notes: moving one around and changing it doesn’t have a huge impact on the overall canvas. A new composite layer is created for elements with , and because these are very likely to change, so the browser makes sure that change is performant as possible by using the GPU to apply style adjustments.

Stacking Order

I know some (or maybe all) of the above discussion on stacking contexts and stacking levels is confusing. Hopefully you’re still with me, because the stacking order helps tie things together.

To understand the stacking order let’s build up the rules slowly by not considering z-index at all at first. In fact let’s look at only two levels in the stacking order to start and then see where new levels fit in the order

  1. Background and borders of the root element of the stacking context
  2. Descendant block boxes in the normal flow, in order of appearance (in the html)

Remember the root of all root stacking contexts is the html element. Looking at the above you’ll see that the background and borders of the html element represent the lowest level of the stack. A (a div inside your html for example) would be at a higher level within the stack.

Makes sense. If you add a background to your html and then fill a div with content inside your html, you’d expect the div content to be in front of the the html background.

Let’s start adding more levels to the stacking order

  1. Background and borders of the root element of the stacking context
  2. Descendant block boxes in the normal flow, in order of appearance (in the html)
  3. Descendant positioned elements, in order of appearance (in html)

Positioned elements without z-index applied or z-index: 0 are on a higher stacking level than non-positioned elements. Even if you don’t specify a z-index (default becomes auto) your positioned element will appear on a higher layer than block level elements in the normal document flow.

  1. Background and borders of the root element of the stacking context
  2. Descendant block boxes in the normal flow, in order of appearance (in the html)
  3. Floating blocks
  4. Descendant positioned elements, in order of appearance (in html)

Floated elements have a higher stacking level than block level elements in the normal document flow, but a lower stacking level than positioned elements without z-index applied.

  1. Background and borders of the root element of the stacking context
  2. Descendant block boxes in the normal flow, in order of appearance (in the html)
  3. Floating blocks
  4. Descendant inline boxes in the normal flow, in order of appearance (in the html)
  5. Descendant positioned elements, in order of appearance (in html)

Notice that inline boxes have a higher stacking level than both block boxes and floated boxes, which you might not expect.

Now lets put the z-index back in and get the full stacking order rules as define by the w3C.

  1. the background and borders of the element forming the stacking context.
  2. the stacking contexts of descendants with negative stack levels. (negative z-index)
  3. a stacking level containing in-flow non-inline-level non-positioned descendants. (block level boxes in the normal document flow)
  4. a stacking level for non-positioned floats and their contents. (floated boxes)
  5. a stacking level for in-flow inline-level non-positioned descendants. (inline boxes)
  6. a stacking level for positioned descendants with ‘z-index: auto’, and any descendant stacking contexts with ‘z-index: 0’.
  7. the stacking contexts of descendants with positive stack levels. (positive z-index)

A few things stand out in the final stacking order. As you might expect an element with a positive z-index appears at the top of the stack and while not specifically mentioned the higher the z-index the higher the level in the stack order.

What is less expected is that boxes with negative z-indexes are still higher in the stacking order than the background and borders of the element forming the stacking context. Remember that element forming the stacking context is likely the element you just added z-index to.

Also it’s interesting where boxes with a z-index of 0 or auto lie in the stacking order. There are several stacking levels below your z-index: 0 element, which you might not expect.

The main thing to understand about the stacking order is that more than the z-index value goes into determining what layer in the stack an element is on.

Stacking Context: How the Parent Element’s Z-index Applies to Children as Well

Let’s say we put a yellow box between the red and the blue one:

Which renders the following:

Now as you see in the code, even if the yellow box has a higher value compared to the blue one, it is positioned behind the blue box.

This is because the yellow box is the child of the red box, and the of the parent element always applies to its children as well. Since the parent element has a lower z-index, its children inherit the same value as well.

This is due to something called stacking context. Put simply, a stacking context is like a new instance of the stacking order list from before:

  1. A root HTML element
  2. Non-positioned elements () in the order they appear
  3. Positioned elements ( is set to another value) in the order they appear

The main thing to remember is that a positioned element with a value besides the default will create a new stacking context.

So looking at our HTML above, because the red box has a of 1, it creates a new stacking context for its child, the yellow box. In that stacking context, the red box serves as the root HTML element, and the yellow box is a positioned element inside of it.

Then because the blue box is part of the same stacking context as the red box (where the element serves as the root element), it will always appear above the yellow box.

If you see this kind of issue, you can solve it by either taking the child element out of its parent, or you removing the position property of the parent so the won’t affect its children:

Which gives us:

Note that there are a number of other properties that affect the stacking context of an element. You can read more about them here.

Because it’s a bit unintuitive, this is one of the most common reasons that doesn’t work.

Determining an Element’s Position in the Stacking Order

Actually determining the global stacking order for all elements on a page (including borders, backgrounds, text nodes, etc.) is extremely complicated and far beyond the scope of this article (again, I refer you to the spec).

But for most intents and purposes, a basic understanding of the order can go a long way and help keep CSS development predictable. So let’s start by breaking the order down into individual stacking contexts.

Stacking Order Within the Same Stacking Context

Here are the basic rules to determine stacking order within a single stacking context (from back to front):

  1. The stacking context’s root element
  2. Positioned elements (and their children) with negative z-index values (higher values are stacked in front of lower values; elements with the same value are stacked according to appearance in the HTML)
  3. Non-positioned elements (ordered by appearance in the HTML)
  4. Positioned elements (and their children) with a z-index value of (ordered by appearance in the HTML)
  5. Positioned elements (and their children) with positive z-index values (higher values are stacked in front of lower values; elements with the same value are stacked according to appearance in the HTML)

Note: positioned elements with negative z-indexes are ordered first within a stacking context, which means they appear behind all other elements. Because of this, it becomes possible for an element to appear behind its own parent, which is normally not possible. This will only work if the element’s parent is in the same stacking context and is not the root element of that stacking context. A great example of this is Nicolas Gallagher’s CSS drop-shadows without images.

Global Stacking Order

With a firm understanding of how/when new stacking contexts are formed as well as a grasp of the stacking order within a stacking context, figuring out where a particular element will appear in the global stacking order isn’t so bad.

The key to avoid getting tripped up is being able to spot when new stacking contexts are formed. If you’re setting a z-index of a billion on an element and it’s not moving forward in the stacking order, take a look up its ancestor tree and see if any of its parents form stacking contexts. If they do, your z-index of a billion isn’t going to do you any good.

CSS Properties

accent-coloralign-contentalign-itemsalign-selfallanimationanimation-delayanimation-directionanimation-durationanimation-fill-modeanimation-iteration-countanimation-nameanimation-play-stateanimation-timing-functionbackdrop-filterbackface-visibilitybackgroundbackground-attachmentbackground-blend-modebackground-clipbackground-colorbackground-imagebackground-originbackground-positionbackground-repeatbackground-sizeborderborder-bottomborder-bottom-colorborder-bottom-left-radiusborder-bottom-right-radiusborder-bottom-styleborder-bottom-widthborder-collapseborder-colorborder-imageborder-image-outsetborder-image-repeatborder-image-sliceborder-image-sourceborder-image-widthborder-leftborder-left-colorborder-left-styleborder-left-widthborder-radiusborder-rightborder-right-colorborder-right-styleborder-right-widthborder-spacingborder-styleborder-topborder-top-colorborder-top-left-radiusborder-top-right-radiusborder-top-styleborder-top-widthborder-widthbottombox-decoration-breakbox-shadowbox-sizingbreak-afterbreak-beforebreak-insidecaption-sidecaret-color@charsetclearclipclip-pathcolorcolumn-countcolumn-fillcolumn-gapcolumn-rulecolumn-rule-colorcolumn-rule-stylecolumn-rule-widthcolumn-spancolumn-widthcolumnscontentcounter-incrementcounter-resetcursordirectiondisplayempty-cellsfilterflexflex-basisflex-directionflex-flowflex-growflex-shrinkflex-wrapfloatfont@font-facefont-familyfont-feature-settingsfont-kerningfont-sizefont-size-adjustfont-stretchfont-stylefont-variantfont-variant-capsfont-weightgapgridgrid-areagrid-auto-columnsgrid-auto-flowgrid-auto-rowsgrid-columngrid-column-endgrid-column-gapgrid-column-startgrid-gapgrid-rowgrid-row-endgrid-row-gapgrid-row-startgrid-templategrid-template-areasgrid-template-columnsgrid-template-rowshanging-punctuationheighthyphensimage-rendering@importisolationjustify-content@keyframesleftletter-spacingline-heightlist-stylelist-style-imagelist-style-positionlist-style-typemarginmargin-bottommargin-leftmargin-rightmargin-topmask-imagemask-modemask-originmask-positionmask-repeatmask-sizemax-heightmax-width@mediamin-heightmin-widthmix-blend-modeobject-fitobject-positionopacityorderorphansoutlineoutline-coloroutline-offsetoutline-styleoutline-widthoverflowoverflow-wrapoverflow-xoverflow-ypaddingpadding-bottompadding-leftpadding-rightpadding-toppage-break-afterpage-break-beforepage-break-insideperspectiveperspective-originpointer-eventspositionquotesresizerightrow-gapscroll-behaviortab-sizetable-layouttext-aligntext-align-lasttext-decorationtext-decoration-colortext-decoration-linetext-decoration-styletext-decoration-thicknesstext-indenttext-justifytext-overflowtext-shadowtext-transformtoptransformtransform-origintransform-styletransitiontransition-delaytransition-durationtransition-propertytransition-timing-functionunicode-bidiuser-selectvertical-alignvisibilitywhite-spacewidowswidthword-breakword-spacingword-wrapwriting-modez-index

Положение элементов по умолчанию

Для начала давайте разберемся с тем, как браузер по умолчанию позиционирует элементы, когда не указаны значения z-index:

  1. Корневой элемент (элемент <html>)
  2. Непозиционируемые элементы в том порядке, в котором они определены
  3. Позиционированные элементы в том порядке, в котором они определены

Непозиционируемый элемент — это элемент со значением position: static по умолчанию. Позиционируемый элемент представляет собой элемент с любым другим значением свойства position. Примерами других значений являются: absolute (абсолютное), relative (относительное), sticky(приклеенное) или fixed (фиксированное).

HTML:

<div class=”pink”>
  <div class=”orange”></div>
</div>
<div class=”blue”></div>
<div class=”green”></div>

CSS:

/* Это только CSS, который подходит для примера. Для отображения полного CSS воспользуйтесь ссылками под изображениями. */

.blue, .pink, .orange {
position: absolute;
}

Мы определили зеленый квадрат в конце документа. Тем не менее, он появляется не впереди, а позади всех остальных элементов, потому что у него не задано позиционирование.

Позиционирование и взаимное расположение

По умолчанию для любого html-элемента значение свойства . Таким образом, все элементы по умолчанию не позиционированы и показываются последовательно в нормальном потоке.

Элемент становится позиционированным, если значением его свойства будет любое из — , , , или . После этого элемент может смещаться или покидать поток вывода.

Таким образом, каждый html-элемент на странице можно расположить поверх других элементов (или позади них). Это называется порядком наложения. Например, всплывающее окно находится поверх остального содержимого страницы.

Посмотрите, как это выглядит:

See this code Positioning and Stacking Order on x.xhtml.ru.

Don’t Assign Large Numbers to Z-Index

Another common reason why might not be working is because sometimes people assign very high numbers to the property:

In a couple of projects I’ve worked on in the past, I often saw people assign these very large numbers like 9999 to the of an element.

Sure it works, but it’s like using a hammer when you really need a screwdriver.

Picture it this way – you come into a large project and are working on some HTML, but no matter what you try you can’t get the elements to appear in the correct order. So after a bunch of digging and searching online, you find out that someone at some point had set a global property to 9999, which keeps overwriting your .

Now that you know how to use properly, and understand stacking context, you shouldn’t have to use large values like this 🙂

I hope this post has helped you to have a better understanding of how to use the property, along with stacking order and stacking context as well. If you want to learn more about web development, don’t forget to subscribe my channel.

Thank you for reading!

Zindex 101:

Zindex can be called directly as a runnable command with:

~/projects/myIndexer$ ./node_modules/zindex/bin/zindex.js

or as a normal library by

var zindex =require('zindex');

Zindex by default will look for scripts inside a and a in your project’s directory.

dirsbase'./src'

Will tell to to look for both and watchers under your projects directory

dirsindexers'./foo/index'watchers'./bar/watch'

Will cause to search for inside the directory and for watchers inside

Zindex’ primary role is to be able to sync data
between one data source to N backends.

With bootstrapping we indicate the act of building a backend from scratch.
This commands works only on backends that expose a «bootstrap» function.
If the backend does not have one, it just does nothing.

With Sourcing we indicate the base indexing action:
fetching data from a Source, ie: a mysql table

Zindex will look by default look for indexers in you local folder.

In order to do so, you simply need to create a
directory in your folder with the
entity you want to sync, ie. :

Zindex will read a file that is inside that directory
to source the data that needs to be synced; an example
would look like:

# libindexerproductssource.jsvar shops =include('storages/mysql');var path  =require('path');module.exports=function(options){var products =mysql.query('severId','SELECT * FROM db.products');return{    data products,    options{myProperty'value'}};};

With Transforming we indicate the actual process of manipulating
your data objects.

At this point, once the data has been extracted from
the source, you might want to apply some transformations,
like renaming a boolean field to or and so on:
to do so zindex will look for a script inside
.

An example would look like:

# indexerproductstransformer.jsfunctiontransform(product,options){  product'in_stock'=!!(product.quantity>);return product;}module.exports=function(products,options){returnproducts.map(function(product){returntransform(product, options);});};

Having an Highland Stream means you can do stuff
like this:

returnproducts.filter(function(product){returnproduct.price>100;}).take(10);

As you see an observable is a simple collection
which you can chunk, filter, etc.

In the example above we are simply filtering
our collection to pick the first ten products
which have a price higher than 100.

Persisting is the last and final step of our indexing process:
here we save the data were they need to be saved!

The data is then fed to what we call «backends»:
Zindex looks for them scripts under
and will send the
data to each one of them so they can be be stored in each
backend; think of your backends as different storage systems:
for example you might want to sync products in a mysql table
and in redis, which means you will create two backends, one called
and the other one called .

If we create a file called under
and write something like:

# indexerproductsbackendsredis.jsvar redis =require('redis')('...','...','...');module.exports=function(data){data.each(funciton(product){redis.execute('HSET','namshi:products', product);});};

We will effectively have setup a sync of the products
from a MySQL table to a redis hash.

How does the CSS z-index Property Work?

The CSS z-index property works by assigning the property with a numeric value to any element.

The property can take large numeric values, as well as minus values should you want to position elements further back in the stack.

An element without a z-index specifically assigned to it, automatically inherits in the z-index of its parent and if the parent element doesn’t have a value set, then the default z-index is 0.

Here’s a visual demonstration of how it works:

As you can see from the example above, we’re trying to position both layer 1 and layer 2 to the top left of the base layer. To do this we’re using the absolute positioning CSS property along with the z-index property.

As you can see, the orange layer (layer 2) is the layer on top. This is because we’ve set the z-index for the layer to 2. The blue layer (layer 1) is set to a z-index of 1, so layer 2 will be displayed on top.

But what if we set layer 2 to have a z-index of 1? You might think that layer 1 would take precedence and layer 2 would be hidden behind it, but that’s not what happens.

Because layer 2 uses absolute positioning and its HTML element is underneath layer 1, it takes precedence. This can be tested by moving layer 1’s element underneath layer 2.

Now, if we alter the layer 2 z-index to have a value of 2 rather than 1, layer 2 takes precedence again because we’ve explicitly stated it should be place higher than layer 1 in the CSS.

Very interesting stuff (at least, it is for geek like me).

Showcase of Various Usage

Applying the property to elements on a page can provide a quick solution to various layout challenges, and allows designers to be a little more creative with overlapping objects in their designs. Some of the practical and creative uses for the property are discussed and shown below.

Overlapping Tabbed Navigation

The CTCOnlineCME website uses overlapping transparent PNG images with applied to the “focused” tab, demonstrating practical use for this CSS property:

The property can be used as part of a CSS-based tooltip, as shown in the example below from trentrichardson.com:

Light Box

There are dozens of quality light box scripts available for free use, such as the JQuery plugin FancyBox. Most, if not all of these scripts utilize the property:

Light box scripts use a semi-opaque PNG image to darken the background, while bringing a new element, usually a window-like to the foreground. The PNG overlay and the both utilize to ensure those two elements are above all others on the page.

Drop-Down Menus

Drop down menus such as Brainjar’s classic Revenge of the Menu Bar use to ensure the menu buttons and their drop-downs are at the top of the stack.

Photo Gallery Effects

A unique combination of JQuery animation and can create a unique effect for use in a slideshow or photo gallery, as shown in the example below from the usejquery.com website:

Polaroid Photo Gallery by Chris Spooner utilizes some CSS3 enhancements combined with to create a cool re-stacking effect on hover.

In this Fancy Thumbnail Hover Effect Soh Tanaka changes values in a JQuery-based script:

CSS Experiments by Stu Nicholls

Stu Nicholls describes a number of CSS experiments on his website CSSplay. Here are a few that make creative use of the property:

Layered Layout Enhancements

The 24 ways website implements to enhance the site’s template, weaving year and date columns that stretch the length and width of the site’s content, for a very interesting effect.

The Janko At Warp Speed site uses in a “fancy share box”:

Perfect Full Page Background Image

This technique was described by Chris Coyier and used on the ringvemedia.com website. It implements on content sections to ensure they appear above the “background” image, which is not a background image, but only mimics one:

The Natural Stacking Order

In an HTML page, the natural stacking order (i.e. the order of elements on the Z axis) is determined by a number of factors. Below is a list showing the order that items fit into a stacking context, starting with the bottom of the stack. This list assumes none of the items has applied:

  • Background and borders of the element that establish stacking context
  • Elements with negative stacking contexts, in order of appearance
  • Non-positioned, non-floated, block-level elements, in order of appearance
  • Non-positioned, floated elements, in order of appearance
  • Inline elements, in order of appearance
  • Positioned elements, in order of appearance

The property, when applied correctly, can change this natural stacking order.

Of course, the stacking order of elements is not evident unless elements are positioned to overlap one another. Thus, to see the natural stacking order, negative margins can be used as shown below:

Grey Box

Blue Box

Gold Box

The boxes above are given different background and border colors, and the last two are indented and given negative top margins so you can see the natural stacking order. The grey box appears first in the markup, the blue box second, and the gold box third. The applied negative margins clearly demonstrate this fact. These elements do not have values set; their stacking order is the natural, or default, order. The overlaps that occur are due to the negative margins.

Вычисляем позицию в стеке

Кроме свойства z-index на position relative CSS элемента в стеке также влияет несколько факторов. Элементы располагаются в стеке в следующем порядке:

Позиция Описание CSS-код
1 (bottom) Элемент формирует контекст наложения. z-index: <integer>
2 Дочерние элементы с отрицательным уровнем стека. z-index: <negative integer>

position: relative | absolute | fixed

3 Дочерние элементы со стилизацией In-flow, non-inline или без установленного позиционирования. display: /* not inline */

position: static

4 Плавающие дочерние элементы без установленного позиционирования. float: left | right

position: static

5 Дочерние элементы со стилизацией In-flow inline или без выставленного позиционирования. display: /* inline */

position: static

6 Дочерние элементы с 0 уровнем стека. z-index: auto | 0

position: relative | absolute | fixed

7 (top) Дочерние элементы с положительным уровнем стека. z-index: <positive integer>

position: relative | absolute | fixed

What’s a CSS z-index?

I think the W3Schools definition of the z-index property sums it up the best:

This basically means you can use this CSS property to stack items on top of each other.

Another good way I like to look at it is: it’s basically the concept of layers for websites.

If you’ve ever used any kind of decent image editing/creation software like Photoshop, GIMP or maybe even Canva, then will no doubt have come across the concept of layers: the ability place images, shapes, text and anything else you might use on top of each other to create a stunning effect or display.

That’s what the CSS z-index property can do for your website design.

Гость форума
От: admin

Эта тема закрыта для публикации ответов.