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?
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)
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
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
Utilisez ce
.content
{
width: 100%;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding-right: 500px;
margin-right: -500px;
}
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...
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>
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
.