web-dev-qa-db-fra.com

Pourquoi React Natif n’offre pas de justification

Je souhaite aligner un élément sur l'axe principal. Par exemple, je veux avoir une ligne avec quelques enfants tous alignés à gauche, puis un enfant aligné du côté droit.

Vous pouvez obtenir cet effet avec quelque chose comme "position: absolute; right: 0", mais je me demande s’il existe un meilleur moyen. Il semble qu'il devrait y avoir une propriété justifySelf qui n'affecte qu'un enfant et affecte son alignement sur l'axe principal, de la même manière que alignSelf affecte l'alignement d'un enfant sur son axe secondaire.

Pourtant, aucun de ces justifySelf ne semble exister. Pourquoi est-ce?

C'est semblable à cette question mais pas tout à fait: Comment pouvez-vous flotter: droit dans React Native?

18
Varun Singh

Je ne sais pas React Native, mais je connais la flexbox!

Utilisez le code suivant comme guide:

<div style="display: flex;">

  <div>
    I'll be on the left side
  </div>
  <div>
    I'll be hugging the guy on the left side
  </div>
  <div>
    I'll be hugging the guy hugging the guy on the left side
  </div>
  <div style="margin-left: auto;">
    I'll be hugging the right side far away from those other guys
  </div>

</div>

La marge définie sur le dernier enfant va pousser tous les autres enfants vers la gauche aussi loin que leur style le permet, et se pousser aussi loin que tout autre style le permet.

Vous pouvez le tester en ajoutant également margin-right: auto; jusqu'au dernier enfant, et vous verrez le dernier enfant parfaitement centré dans l'espace restant de la div des parents, après que les trois premiers enfants aient pris leur espace alloué. Cela est dû au fait que les "voitures de marge" concurrentes se partageront de manière égale l’espace restant, car elles ne peuvent pas s’annuler ni se remplacer.

Flex box a été conçu pour gérer l’espacement des marges comme celui-ci. Profitez-en, ainsi que les autres options d’espacement uniques disponibles sous la justify-content propriété.

Article utile: https://hackernoon.com/flexbox-s-best-kept-secret-bd3d892826b6

20
Ben Steward

Je crois que vous voulez réaliser quelque chose comme ceci: enter image description here

Vous pouvez implémenter ceci en imbriquant des vues partageant la même propriété justifyContent.

  <View style={{
    flex: 1,
    flexDirection: 'column',
    justifyContent: 'space-between',
  }}>
    <View>
      <View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
      <View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} />
    </View>
    <View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
  </View>
10
db42

Une réponse partielle: il n'y a pas de justifySelf dans React Natif car il n'y a pas de justify-self pour flexbox en vrai CSS. Là est a justify-self Propriété CSS, mais ne fait rien dans les mises en page flexbox. Vous pouvez voir dans la spécification à l’adresse suivante: https://drafts.csswg.org/css -align-3/# overview que justify-self est défini pour s'appliquer à:

des cases de niveau bloc, des cases positionnées de manière absolue et des éléments de grille

qui n'inclut notamment pas les "éléments flexibles".

D'accord, mais pourquoi est-ce le cas en CSS? MDN offre ne explication que vous pourriez ou non trouver satisfaisant:

Il n'y a pas de justification-soi dans Flexbox

Sur l’axe principal Flexbox traite notre contenu en tant que groupe. La quantité d’espace nécessaire pour structurer les éléments est calculée et l’espace restant est ensuite disponible pour la distribution. La justify-content propriété contrôle comment cet espace est utilisé. Ensemble justify-content: flex-end et l’espace supplémentaire est placé avant les éléments, justify-content: space-around et il est placé de chaque côté de l’article dans cette dimension, etc.

Cela signifie qu'un justify-self La propriété n’a aucun sens dans Flexbox car il s’agit toujours de déplacer le groupe entier d’éléments.

Sur l'axe transversal align-self est logique car nous avons potentiellement un espace supplémentaire dans le conteneur flex dans cette dimension, dans lequel un seul élément peut être déplacé au début et à la fin.

Il y a clairement un sens à cela. C'est toujours significatif et cohérent de mettre alignSelf: 'center' sur un élément flexible pour demander qu’il soit centré sur l’axe transversal. Mais que signifierait-il, par exemple, de mettre justifySelf: 'center' sur un élément flexible, demander à ce qu’il soit centré sur l’axe principal? Comment cela est-il censé être géré si les éléments flexibles précédents ont déjà rempli plus de la moitié de l'espace le long de cet axe?

Les marges offrent une solution idéale pour des cas comme le vôtre. justifySelf, d’autre part, ne peut raisonnablement exister pour flexbox, car les valeurs justifyContent spécifient comment distribuer flex, et un peu de réflexion sur ce que cela signifierait de les appliquer à des éléments spécifiés individuellement révèle que cela est fondamentalement incohérent.

6
Mark Amery

Vous pouvez jeter un oeil à Flex Docs !

L'ajout de flexDirection au style d'un composant détermine le axe principal de sa présentation.

et alors:

L'ajout d'alignItems au style d'un composant détermine l'alignement des enfants le long de l'axe secondaire (si l'axe principal est une ligne, alors le secondaire est une colonne et vice versa. ).

Donc, votre code désiré sera:

import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';

export default class AlignItemsBasics extends Component {
  render() {
    return (
      <View style={{
        flex: 1,
        flexDirection: 'column',
        justifyContent: 'center',
        alignItems: 'center',
      }}>
        <View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
        <View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} />
        <View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
      </View>
    );
  }
};

// skip this line if using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => AlignItemsBasics);

MISE À JOUR

Si vous voulez dire quelque chose comme cette image:

example

Ensuite, je vous suggère ceci:

import React, { Component } from "react";
import { View, StyleSheet } from "react-native";

class Playground extends Component {
  render() {
    return (
      <View style={styles.container}>
        <View style={styles.boxes} />
        <View style={styles.boxes} />
        <View
          style={[
            styles.boxes,
            {
              backgroundColor: "crimson",
              position: "absolute",
              right: 0
            }
          ]}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: "row",
    justifyContent: "flex-start",
    alignItems: "center"
  },
  boxes: {
    width: 50,
    height: 50,
    marginLeft: 1, // to separate each box!
    backgroundColor: "steelblue"
  }
});

export default Playground;

Autant que je sache avec ces accessoires , c'est le meilleur moyen!

4
MohamadKh75

Il existe un moyen simple de le faire sans positionnement absolu qui fonctionne exactement comme vous le souhaitez, avec tous les éléments de hauteurs différentes alignés correctement sur l'axe des ordonnées.

<View style={{ flexDirection: 'row', alignItems: 'center' }}>
  <View style={{ backgroundColor: 'green', height: 50, width: 50 }} />
  <Text style={{flex: 1}}> text in here because why not!</Text>
  <View style={{ backgroundColor: 'yellow', width: 30, height: 30 }} />
</View>

enter image description here

2
John Culviner