La solution acceptée fonctionne très bien, mais l'OMI n'a pas d'explication sur la raison pour laquelle elle fonctionne. L'exemple ci-dessous se résume aux principes de base et sépare le CSS important du CSS de style non pertinent. En bonus, j'ai également inclus une explication détaillée du fonctionnement du positionnement CSS.
TLDR; si vous ne voulez que le code, faites défiler vers le bas jusqu'au résultat .
Le problème
Il y a deux éléments séparés, frères et sœurs et le but est de positionner le deuxième élément (avec un id
de infoi
), afin qu'il apparaisse dans l'élément précédent (celui avec un class
de navi
). La structure HTML ne peut pas être modifiée.
Solution proposée
Pour obtenir le résultat souhaité, nous allons déplacer ou positionner le deuxième élément, que nous appellerons de #infoi
sorte qu'il apparaisse dans le premier élément, que nous appellerons .navi
. Plus précisément, nous voulons #infoi
être positionnés dans le coin supérieur droit de .navi
.
Position CSS Connaissances requises
CSS a plusieurs propriétés pour positionner les éléments. Par défaut, tous les éléments le sont position: static
. Cela signifie que l'élément sera positionné selon son ordre dans la structure HTML, à quelques exceptions près.
Les autres position
valeurs sont relative
, absolute
, sticky
et fixed
. En définissant un élément position
sur l'une de ces autres valeurs, il est désormais possible d'utiliser une combinaison des quatre propriétés suivantes pour positionner l'élément:
En d'autres termes, en définissant position: absolute
, nous pouvons ajouter top: 100px
pour positionner l'élément à 100 pixels du haut de la page. Inversement, si nous définissons bottom: 100px
l'élément, il serait positionné à 100 pixels du bas de la page.
C'est là que de nombreux nouveaux arrivants CSS se perdent -position: absolute
a un cadre de référence. Dans l'exemple ci-dessus, le cadre de référence est l'body
élément. position: absolute
avectop: 100px
signifie que l'élément est positionné à 100 pixels du haut de l'body
élément.
Le cadre de référence de la position ou le contexte de la position peut être modifié en définissant l' position
élément parent sur une valeur autre queposition: static
. Autrement dit, nous pouvons créer un nouveau contexte de position en donnant un élément parent:
position: relative;
position: absolute;
position: sticky;
position: fixed;
Par exemple, si un <div class="parent">
élément est donné position: relative
, tous les éléments enfants utilisent le <div class="parent">
comme contexte de position. Si un élément enfant était donné position: absolute
et top: 100px
, l'élément serait positionné à 100 pixels du haut de l' <div class="parent">
élément, car <div class="parent">
c'est maintenant le contexte de position.
L'autre facteur à prendre en compte est l' ordre d'empilement - ou la façon dont les éléments sont empilés dans la direction z. Il faut savoir ici que l'ordre des éléments de la pile est, par défaut, défini par l'inverse de leur ordre dans la structure HTML. Prenons l'exemple suivant:
<body>
<div>Bottom</div>
<div>Top</div>
</body>
Dans cet exemple, si les deux <div>
éléments étaient positionnés au même endroit sur la page, l' <div>Top</div>
élément couvrirait l' <div>Bottom</div>
élément. Comme <div>Top</div>
vient après <div>Bottom</div>
dans la structure HTML, il a un ordre d'empilement plus élevé.
div {
position: absolute;
width: 50%;
height: 50%;
}
#bottom {
top: 0;
left: 0;
background-color: blue;
}
#top {
top: 25%;
left: 25%;
background-color: red;
}
<div id="bottom">Bottom</div>
<div id="top">Top</div>
L'ordre d'empilement peut être modifié avec CSS à l'aide des propriétés z-index
ou order
.
Nous pouvons ignorer l'ordre d'empilement dans ce problème car la structure HTML naturelle des éléments signifie que l'élément sur lequel nous voulons apparaître top
vient après l'autre élément.
Donc, revenons au problème en cours - nous utiliserons le contexte de position pour résoudre ce problème.
La solution
Comme indiqué ci-dessus, notre objectif est de positionner l' #infoi
élément de sorte qu'il apparaisse à l'intérieur de l' .navi
élément. Pour ce faire, nous encapsulerons les éléments .navi
et #infoi
dans un nouvel élément <div class="wrapper">
afin de pouvoir créer un nouveau contexte de position.
<div class="wrapper">
<div class="navi"></div>
<div id="infoi"></div>
</div>
Créez ensuite un nouveau contexte de position en donnant .wrapper
un position: relative
.
.wrapper {
position: relative;
}
Avec ce nouveau contexte de position, nous pouvons nous positionner à l' #infoi
intérieur .wrapper
. Tout d'abord, donnez #infoi
un position: absolute
, nous permettant de nous positionner #infoi
absolument .wrapper
.
Ajoutez ensuite top: 0
et right: 0
pour positionner l' #infoi
élément dans le coin supérieur droit. N'oubliez pas que l' #infoi
élément étant utilisé .wrapper
comme contexte de position, il se trouvera en haut à droite de l' .wrapper
élément.
#infoi {
position: absolute;
top: 0;
right: 0;
}
Parce qu'il .wrapper
s'agit simplement d'un conteneur pour .navi
, le positionnement #infoi
dans le coin supérieur droit de .wrapper
donne l'effet d'être positionné dans le coin supérieur droit de .navi
.
Et #infoi
voilà , il semble maintenant être dans le coin supérieur droit de .navi
.
Le résultat
L'exemple ci-dessous se résume aux bases et contient un style minimal.
/*
* position: relative gives a new position context
*/
.wrapper {
position: relative;
}
/*
* The .navi properties are for styling only
* These properties can be changed or removed
*/
.navi {
background-color: #eaeaea;
height: 40px;
}
/*
* Position the #infoi element in the top-right
* of the .wrapper element
*/
#infoi {
position: absolute;
top: 0;
right: 0;
/*
* Styling only, the below can be changed or removed
* depending on your use case
*/
height: 20px;
padding: 10px 10px;
}
<div class="wrapper">
<div class="navi"></div>
<div id="infoi">
<img src="http://via.placeholder.com/32x20/000000/ffffff?text=?" height="20" width="32"/>
</div>
</div>
Une solution alternative (grille)
Voici une solution alternative utilisant CSS Grid pour positionner l' .navi
élément avec l' #infoi
élément à l'extrême droite. J'ai utilisé les grid
propriétés verbeuses pour le rendre aussi clair que possible.
:root {
--columns: 12;
}
/*
* Setup the wrapper as a Grid element, with 12 columns, 1 row
*/
.wrapper {
display: grid;
grid-template-columns: repeat(var(--columns), 1fr);
grid-template-rows: 40px;
}
/*
* Position the .navi element to span all columns
*/
.navi {
grid-column-start: 1;
grid-column-end: span var(--columns);
grid-row-start: 1;
grid-row-end: 2;
/*
* Styling only, the below can be changed or removed
* depending on your use case
*/
background-color: #eaeaea;
}
/*
* Position the #infoi element in the last column, and center it
*/
#infoi {
grid-column-start: var(--columns);
grid-column-end: span 1;
grid-row-start: 1;
place-self: center;
}
<div class="wrapper">
<div class="navi"></div>
<div id="infoi">
<img src="http://via.placeholder.com/32x20/000000/ffffff?text=?" height="20" width="32"/>
</div>
</div>
Une solution alternative (sans emballage)
Dans le cas où nous ne pouvons pas modifier de code HTML, ce qui signifie que nous ne pouvons pas ajouter d'élément wrapper, nous pouvons toujours obtenir l'effet souhaité.
Au lieu d'utiliser position: absolute
l' #infoi
élément, nous utiliserons position: relative
. Cela nous permet de repositionner l' #infoi
élément à partir de sa position par défaut sous l' .navi
élément. Avec position: relative
nous pouvons utiliser une top
valeur négative pour la déplacer vers le haut par rapport à sa position par défaut, et une left
valeur de 100%
moins quelques pixels, en utilisant left: calc(100% - 52px)
, pour la positionner près du côté droit.
/*
* The .navi properties are for styling only
* These properties can be changed or removed
*/
.navi {
background-color: #eaeaea;
height: 40px;
width: 100%;
}
/*
* Position the #infoi element in the top-right
* of the .wrapper element
*/
#infoi {
position: relative;
display: inline-block;
top: -40px;
left: calc(100% - 52px);
/*
* Styling only, the below can be changed or removed
* depending on your use case
*/
height: 20px;
padding: 10px 10px;
}
<div class="navi"></div>
<div id="infoi">
<img src="http://via.placeholder.com/32x20/000000/ffffff?text=?" height="20" width="32"/>
</div>
overflow: hidden
, utilisezoverflow: visible
plutôt.