CSS Calc alternative

J'essaie de changer dynamiquement la largeur d'un div en utilisant CSS et pas de jquery. Le code suivant fonctionne dans les navigateurs suivants: http://caniuse.com/calc

/* Firefox */
width: -moz-calc(100% - 500px);
/* WebKit */
width: -webkit-calc(100% - 500px);
/* Opera */
width: -o-calc(100% - 500px);
/* Standard */
width: calc(100% - 500px);

Je veux également soutenir IE 5.5 et supérieur , j'ai trouvé ce qui suit: expression. Est-ce l'utilisation correcte:

/* IE-OLD */
width: expression(100% - 500px);

Puis-je également prendre en charge Opera et le navigateur Android?

66
demandé sur dippas 2013-04-16 14:15:26

6 réponses

Presque toujours box-sizing: border-box peut remplacer une règle calc telle que calc(100% - 500px) utilisée pour la mise en page.

Par exemple:

, Si j'ai le balisage suivant:

<div class="sideBar">sideBar</div>
<div class="content">content</div>

Au lieu de faire ceci: (en supposant que la barre latérale est de 300px de large)

.content {
  width: calc(100% - 300px);
}

Faites ceci:

.sideBar {
     position: absolute; 
     top:0;
     left:0;
     width: 300px;
}
.content {
    padding-left: 300px;
    width: 100%;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}

* {
  margin: 0;
  padding: 0;
}
html,
body,
div {
  height: 100%;
}
.sideBar {
  position: absolute;
  top: 0;
  left: 0;
  width: 300px;
  background: orange;
}
.content {
  padding-left: 300px;
  width: 100%;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  background: wheat;
}
<div class="sideBar">sideBar</div>
<div class="content">content</div>

PS: Je ne travaillerai pas dans IE 5.5 (hahahaha) , mais cela fonctionnera dans IE8+, tous les navigateurs mobiles et tous les navigateurs modernes (caniuse)

Largeur Démo

Hauteur De La Démo

Je viens de trouver ce post du blog de Paul Irish où il montre également le dimensionnement des boîtes comme une alternative possible pour les expressions simples calc (): (bold est le mien)

L'un de mes cas d'utilisation préférés que border-box résout bien est columns. Je peut vouloir diviser ma grille avec 50% ou 20% colonnes, mais veulent ajouter un remplissage via px ou em. sans la prochaine calc () de CSS, c'est impossible... à moins que vous utilisez border-box .

NB: la technique ci-dessus ressemble en effet à une instruction Calc() correspondante. Il y a une différence cependant. Lors de l'utilisation d'une règle calc (), la valeur de la largeur de la Div de contenu sera en fait 100% - width of fixed div, mais avec la technique ci-dessus, la largeur réelle de la Div de contenu est la largeur complète de 100%, mais elle a l'apparence de "remplir" la largeur restante. (ce qui est probablement assez bon pour le besoin de la plupart des gens ici)

Cela dit, si est important que la largeur du contenu div soit réellement 100% - fixed div width alors une technique différente - qui utilise des contextes de formatage de blocs-peut être utilisée (voir ici et ici pour les détails sanglants):

1) flotter la largeur fixe div

2) Définissez overflow:hidden ou overflow:auto sur la Div de contenu

Démo

111
répondu Danield 2017-05-23 12:02:14

Ayez juste un repli avant que le calc fasse l'affaire.

width: 98%;               /* fallback for browsers without support for calc() */
width: calc(100% - 1em);

Voir plus ici https://developer.mozilla.org/en-US/docs/Web/CSS/calc

33
répondu Tommy Sørensen 2016-08-24 11:16:12

Utilisez ce

    .content
{
    width: 100%;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    padding-right: 500px;
    margin-right: -500px;
}
15
répondu Mohamed Malik 2013-11-12 06:49:01

Juste passé la meilleure partie de 3 heures à essayer de contourner cela pour un cas spécifique sur les appareils andriod, ne pouvait pas faire fonctionner le dimensionnement de la boîte, donc je l'ai lié dans mon JS comme une solution de contournement sale... pas de jQuery requis cependant! :)

Pris sur le code de travail sur andriod 2.3.

<div class="sessionDiv" style="width:auto;">
<img> <!-- image to resize -->
</div>
<div class="sessionDiv" style="width:auto;">
<img> <!-- image to resize -->
</div>

JS avec les écouteurs d'événements

var orient =
{
    orientation:window.orientation,
    width: window.innerWidth,
    check: function()
    {
        // if orientation does not match stored value, update
        if(window.orientation !== this.orientation)  
        {
            this.orientation = window.orientation; //set new orientation
            this.width = window.innerWidth; //set new width
            this.adjustIrritatingCSS(this.width); //change ui to current value
        }
        //if width does not match stored value, update
        if(window.innerWidth !== this.width)
        {
            this.width = window.innerWidth; //set new width
            this.adjustIrritatingCSS(this.width); //change ui to current value
        }
    },
    adjustIrritatingCSS: function(screenWidth)
    {   
    //disgusting workaround function
        var titleBoxes = document.getElementsByClassName('sessionDiv'); 
        var i = titleBoxes.length;
        var sessWidth = screenWidth - 300; // calc(100% - 300px); -> equivalent
        while(i--)
        {
            titleBoxes[i].style.width = String( sessWidth + "px"); 
            //resize image in auto sized div
        }
        sessWidth = null; //clear width
        titleBoxes = null; //clear nodelist
        i = null; // clear index int
    }
};

window.onload = function()
{
    window.addEventListener('resize', function(){orient.check();}); 
    //on resize, check our values for updates and if theres changes run functions
    window.addEventListener('orientationchange', function(){orient.check();});
    //on rotate, check our values for updates and if theres changes run functions
    setInterval(function(){orient.check();}, 2000);
    //occasionally check our values for updates and if theres changes run functions(just incase!!)
    orient.adjustIrritatingCSS(orient.width); 
    //sets value on first run
};

J'espère que cela aidera tous ceux qui ne peuvent pas faire fonctionner le dimensionnement de la boîte! PS j'ai rencontré des problèmes avec ios en utilisant ceci...

0
répondu bhiqa 2014-04-10 08:18:19

Modifiez la largeur # menuLog avec % ou px et vous verrez de la magie. Fonctionne avec tous les appareils même

*{
	-moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
}
#menuLog{
  width:30%;
  /*width:300px;*/
	height: 60px;
	padding: 5px;
	background-color: #ddd;
}
#menuLog > div[inline-log="1"]{
	display: inline-block;
	vertical-align: top;
	width: 100%;
	height: 100%;
	margin-right: -60px;
}
#menuLog > div[inline-log="1"] > div[inline-log="1.1"]{
	margin-right: 60px;
	height: 100%;
	background-color: red;
}
#menuLog > div[inline-log="2"]{
	display: inline-block;
	vertical-align: top;
	width: 60px;
	height: 100%;
}
#menuLog > div[inline-log="2"] > div[inline-log="2.1"]{
	display: inline-block;
	vertical-align: top;
	width: 55px;
	height: 100%;
	background-color: yellow;
	margin-left:5px;
}
<div id="menuLog">
  <div inline-log="1">
    <div inline-log="1.1">
      One
    </div>
  </div><div inline-log="2">
     <div inline-log="2.1">
      Two
     </div>
  </div>
</div>
0
répondu Mareks Dunkurs 2017-03-23 22:37:11

Je voulais ajouter l'alternative no-calc, no-border-box (c'est-à-dire, CSS2).

Les éléments de bloc à flux Normal ont initialement width: auto, qui est effectivement la largeur du bloc contenant moins les largeurs de marge, de bordure et de remplissage.

Le exemple ci-dessus peut être fait, sans frontière-zone, simplement comme

.content {
    padding-left: 300px;
}

De même, avec

.content {
  margin-left: 1px;
  border-left: 1em solid;
  padding-left: 1rem;
}

La largeur effective est 100% - 1px - 1em - 1rem.

Pour les éléments absolument positionnés, height: auto A similaire propriétés:

.content {
  position: absolute;
  top: 0;
  bottom: 0;
  margin-bottom: 1px;
  border-bottom: 1em solid;
  padding-bottom: 1rem;
}

Ici, la hauteur est de 100% - 1px - 1em - 1rem.

0
répondu sam 2017-08-11 03:04:49