Calculatrice clavier avec flexbox

je construis une calculatrice avec flexbox. Je veux une de ses clés deux fois la hauteur et une autre deux fois la largeur.

j'ai cherché sur Google beaucoup à ce sujet, mais je n'ai pas pu trouver les deux cas ensemble.

pour deux touches de hauteur, les seules réponses que j'ai trouvées étaient de faire flex-direction comme column . Mais dans ce cas, je ne serai pas en mesure de faire double largeur clé.

Voici mon code (codepen.io). Aidez-moi.

$(function() {
  var curr = "",
    prev = "";
  var updateView = function() {
    $('#curr').html(curr);
    $('#prev').html(prev);
  };
  $('.keysNum').on('click', function(e) {
    curr += $(this).html();
    console.log(this);
    updateView();
  });
  $('.keysOp').on('click', function(e) {

  });
});
css lang-css prettyprint-override">.flexBoxContainer {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  display: flex;
  justify-content: space-around;
  align-items: center;
  width: 100%;
  min-height: 100vh;
}

.calculator {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-content: center;
  width: 100%;
  min-height: 100vh;
}

@media (min-width: 321px) {
  .calculator {
    width: 320px;
  }
}

.calculator .keys {
  border: #d3d2cb 0.5px solid;
  background: #fefdff;
  color: #33393d;
  height: 50px;
  height: 14.2857142857vh;
  width: 25%;
  line-height: 14.2857142857vh;
  text-align: center;
  font-size: 1.4rem;
  font-weight: bold;
  transition: background 0.2s linear;
}

.calculator .keysOp {
  background: #f1f1ef;
}

.calculator .keysC {
  color: #f94913;
}

.calculator .keys:hover {
  background: #d3d2cb;
  transition: background 0s linear;
}

.calculator .keys:focus {
  outline: none;
}

.calculator .keys:active {
  background: #93938E;
}

.calculator .screen {
  background: #e9e8e5;
  height: 14.2857142857vh;
  width: 100%;
  line-height: 14.2857142857vh;
  direction: rtl;
}

.calculator .screen:last-child {
  font-size: 4rem;
}

.calculator #anomaly-keys-wrapper {
  display: flex;
  width: 100%;
}

.calculator #anomaly-keys-wrapper>section:first-child {
  display: flex;
  flex-wrap: wrap;
  width: 75%;
}

.calculator #anomaly-keys-wrapper>section:first-child>div.keys {
  flex: 1 0 33.33%;
}

.calculator #anomaly-keys-wrapper>section:first-child>div.long {
  flex-basis: 66.67%;
}

.calculator #anomaly-keys-wrapper>section:last-child {
  width: 25%;
  display: flex;
  flex-direction: column;
}

.calculator #anomaly-keys-wrapper>section:last-child>.tall {
  background: #f94913;
  color: #fefdff;
  width: 100%;
  line-height: 28.5714285714vh;
  flex: 1;
}

.calculator #anomaly-keys-wrapper>section:last-child>.tall:hover {
  background: #c73a0f;
}

.calculator #anomaly-keys-wrapper>section:last-child>.tall:focus {
  outline: none;
}

.calculator #anomaly-keys-wrapper>section:last-child>.tall:active {
  background: #8b280a;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="flexBoxContainer">
  <div class="calculator">
    <div class="screen" id="prev"></div>
    <div class="screen" id="curr"></div>
    <!--     <div class="keys keysC keysOp" tabindex="2">C</div> -->
    <div class="keys keysC keysOp" tabindex="2">C</div>
    <div class="keys keysOp" tabindex="3"><i class="icon ion-backspace-outline"></i></div>
    <div class="keys keysOp" tabindex="4">&divide</div>
    <div class="keys keysOp" tabindex="5">&times</div>
    <div class="keys keysNum" tabindex="6">7</div>
    <div class="keys keysNum" tabindex="7">8</div>
    <div class="keys keysNum" tabindex="8">9</div>
    <div class="keys keysOp" tabindex="9">-</div>
    <div class="keys keysNum" tabindex="10">4</div>
    <div class="keys keysNum" tabindex="11">5</div>
    <div class="keys keysNum" tabindex="12">6</div>
    <div class="keys keysOp" tabindex="13">+</div>
    <section id="anomaly-keys-wrapper">
      <section>
        <div class="keys keysNum" tabindex="14">1</div>
        <div class="keys keysNum" tabindex="15">2</div>
        <div class="keys keysNum" tabindex="16">3</div>
        <div class="keys long keysNum" tabindex="17">0</div>
        <div class="keys" tabindex="18">.</div>
      </section>
      <section>
        <div class="keys tall" tabindex="19">=</div>
      </section>
    </section>
  </div>
</div>
4
demandé sur Michael_B 2016-08-22 15:37:59

2 réponses

envelopper les touches inégales dans leurs propres contenants flexibles et aller de là...

* { box-sizing: border-box; }                                      /* 1 */

.flexBoxContainer {
    display: flex;
    justify-content: space-around;
    align-items: center;
    width: 100%;
}

.calculator {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-content: center;
    width: 100%;
}

.calculator .keys {
    border: red 1px solid;
    height: 50px;
    width: 25%;
    break-inside: avoid;
}

.calculator input {
    height: 100px;
    width: 100%;
    direction: rtl;
}

#anomaly-keys-wrapper {                                            /* 2 */
    display: flex;
    width: 100%; 
}

#anomaly-keys-wrapper > section:first-child {                      /* 3 */
    display: flex;
    flex-wrap: wrap;
    width: 75%;
}

#anomaly-keys-wrapper > section:first-child > div {                /* 4 */
    flex: 1 0 33.33%;
}

#anomaly-keys-wrapper > section:first-child > div:nth-child(4) {   /* 5 */
    flex-basis: 66.67%;
}

#anomaly-keys-wrapper > section:last-child {                       /* 6 */
    width: 25%;
    display: flex;
    flex-direction: column;
}

#anomaly-keys-wrapper .tall {                                      /* 7 */
    width: 100%;
    flex: 1;
}

@media (min-width: 321px) {
    .calculator {
        width: 320px;
    }
}
<div class="flexBoxContainer">
    <div class="calculator">
        <input />
        <div class="keys"></div>
        <div class="keys"></div>
        <div class="keys"></div>
        <div class="keys"></div>
        <div class="keys"></div>
        <div class="keys"></div>
        <div class="keys"></div>
        <div class="keys"></div>
        <div class="keys"></div>
        <div class="keys"></div>
        <div class="keys"></div>
        <div class="keys"></div>
        <section id="anomaly-keys-wrapper">
            <section>
                <div class="keys"></div>
                <div class="keys"></div>
                <div class="keys"></div>
                <div class="keys long"></div>
                <div class="keys"></div>
            </section>
            <section>
                <div class="keys tall"></div>
            </section>
        </section>
    </div>
</div>

Révisé Codepen (avec compilé CSS)

Notes:

  1. Comprennent le remplissage et les frontières en width / "151930920 calculs".
  2. envelopper touches inégales dans un conteneur flex séparé (par défaut flex-direction: row et flex-wrap: nowrap )
  3. Wrap long la clé dans un autre conteneur flex avec du papier d'emballage activé (et de prendre assez de frères et sœurs pour créer l'égalité de la hauteur avec tall clé).
  4. forcer trois touches par rangée max.
  5. Make long double la largeur des frères et sœurs. (N'a pas utilisé de sélecteur de classe long plus simple en raison d'une plus faible spécificité.)
  6. Envelopper la clé tall dans un récipient souple séparé à orientation verticale.
  7. Faire tall clé de consommer toute la largeur et la hauteur du conteneur.

mise à jour

Dans les commentaires:

Salut, 1. Pouvez-vous m'expliquer comment flex base fonctionne? et pourquoi l'avez-vous utilisé au lieu de donner de la largeur à long bouton. 2. Pourquoi est-il nécessaire de donner flex: 1; taille de bouton, comme je l'ai lu c'est la valeur par défaut.

Question n ° 1:

les clefs du premier conteneur de la sous-section (contenant .long ) sont calibrées avec flex: 1 0 33.33% .

c'est la abréviation de flex-grow: 1 , flex-shrink: 0 , et flex-basis: 33.33% .

pour la touche .long , nous remplaçons simplement le composant flex-basis par 66.67% . (il n'est pas nécessaire de déclarer de nouveau les deux autres composantes).

flex-basis aussi, il n'y a vraiment pas de différence dans ce cas entre width et flex-basis , mais puisque nous avons dépassé flex-basis , j'ai utilisé flex-basis .

en utilisant width laisserait l'original flex-basis: 33.33% intact, créant deux width règles qui peuvent, par conséquent, ne pas étendre la touche .long , selon la règle qui prévaut dans la cascade.

pour une explication complète de flex-basis vs. width , voir quelles sont les différences entre la base flexible et la largeur?

à la Question #2:

parce que la valeur initiale de l'élément flex-grow est 0 ( source ).

1
répondu Michael_B 2017-05-23 12:02:21

il n'y a pas de réponse générique que je puisse trouver, mais c'est aussi proche que possible.

j'ai modifié votre code pour utiliser le modèle floating au lieu du modèle flexbox. C'est moins moderne, mais semble être une solution viable à ce problème particulier, avec peu ou pas d'effets négatifs.

s'il vous plaît noter que j'ai également modifié le width des boutons pour réellement prendre tout l'espace qu'ils peuvent, et leur a donné un box-sizing de border-box . En savoir plus sur ce ici .

https://codepen.io/anon/pen/VjOKGX

.calculator {
    // Required to keep the buttons inside
    overflow: hidden;
    width: 100%;
    @media #{$gtphone} {
        width: 320px;
    }
    .keys {
        // Changes the box model so that width includes the borders too
        box-sizing: border-box;
        border: red 1px solid;
        height: 50px;
        // The width is modified to take up all the space
        width: 25%;
        // Floating is defined
        float: left;
        break-inside: avoid;
    }
    .long {
        // This one needs float to be set to right,
        // so that other elements may be on its left in multiple rows
        float: right;
        height: 100px !important;
    }
    .big {
        // Again, width is modified
        width: 50% !important;
    }
    input {
        height: 100px;
        width: 100%;
        direction: rtl;
    }
}
2
répondu skreborn 2016-08-22 12:49:57