CSS Calc Alternative

70

Ich versuche, die Breite eines Divs dynamisch mit CSS und ohne Abfrage zu ändern. Der folgende Code funktioniert in den folgenden Browsern: 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);

Ich möchte auch IE 5.5 und höher unterstützen , ich habe folgendes gefunden: Ausdruck. Ist das die richtige Verwendung:

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

Kann ich auch Opera und den Android-Browser unterstützen?

H3AP
quelle
67
Wow, IE 5.5? Verteilst du das an die Arche oder so?
BenM
1
Woher wusstest du das? Nun, ich versuche zumindest, es am 6. oder 7. zum
Laufen
3
Sind Sie sicher, dass Sie kein XY-Problem haben ? Warum versuchst du das zu tun? Vielleicht kann etwas Einfaches wie Ränder / Auffüllungen und / oder ein Wrapper-Element Ihr Layout-Problem lösen?
Jeroen
1
Wenn ich Sie wäre, würde ich meine Unterstützung für IE5.5 überdenken. IE6 wird von Microsoft offiziell für tot erklärt. Ich vermute (hoffe), dass IE7 auch bald folgt. Nicht um die alte Diskussion zurückzubekommen, aber willst du das wirklich? Wenn die Antwort ja ist, dann machen Sie es auf jeden Fall.
Marijke Luttekes

Antworten:

117

Fast immer box-sizing: border-boxkann eine Berechnungsregel ersetzt werden, wie calc(100% - 500px)sie für das Layout verwendet wird.

Zum Beispiel:

Wenn ich folgendes Markup habe:

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

Anstatt dies zu tun: (Angenommen, die Seitenleiste ist 300px breit)

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

Mach das:

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

PS: Ich werde nicht in IE 5.5 (hahahaha) arbeiten, aber es wird in IE8 + funktionieren, allen mobilen und allen modernen Browsern ( caniuse )

Breite Demo

Höhe Demo

Ich habe gerade diesen Beitrag aus Paul Irishs Blog gefunden, in dem er auch die Boxgröße als mögliche Alternative für einfache calc () - Ausdrücke vorführt: (fett ist meins)

Einer meiner bevorzugten Anwendungsfälle, den Border-Box gut löst, sind Spalten. Ich möchte mein Raster vielleicht mit 50% oder 20% Spalten aufteilen, aber über px oder em Auffüllen hinzufügen. Ohne das bevorstehende calc () von CSS ist dies nicht möglich ... es sei denn, Sie verwenden ein Rahmenfeld .

NB: Die obige Technik sieht tatsächlich genauso aus wie eine entsprechende calc () - Anweisung. Es gibt jedoch einen Unterschied. Wenn Sie eine calc () -Regel verwenden, ist der Wert der Breite des Inhalts div tatsächlich. 100% - width of fixed divBei der obigen Technik entspricht die tatsächliche Breite des Inhalts div jedoch der vollen Breite von 100%, es sieht jedoch so aus, als würde er sich füllen. die verbleibende Breite. (was wahrscheinlich gut genug ist, um die meisten Leute hier zu wollen)

Das heißt, wenn es wichtig ist, dass die Breite des Inhaltsdiv tatsächlich 100% - fixed div width ist, kann eine andere Technik verwendet werden, die Blockformatierungskontexte verwendet (siehe hier und hier für die wichtigsten Details):

1) schweben die feste Breite div

2) setzen overflow:hiddenoderoverflow:auto auf den Inhalt div

Demo

Danield
quelle
1
Warum werden diese 2 benötigt? -moz-box-sizing: border-box;& box-sizing: border-box;. Kann ich nicht einfach Polsterung & Breite angeben
Benutzer
2
@buffer - Nein, da das Standard-Box-Modell verwendet, box-sizing-content-boxwas bedeutet, dass die Breite Ihres Elements zunimmt, wenn Sie Polster hinzufügen. Bei box-sizing:border-boxder Polsterung handelt es sich um eine innere Polsterung, und die Breite des Elements bleibt entsprechend Ihrer Einstellung erhalten.
Danield
Was tun, wenn die Höhe eine Kombination aus px und% ist und% die verbleibende Höhe einnehmen soll?
Miyalys
2
Wie würde sich das ändern, wenn es mit Höhe statt Breite wäre?
Straßenlaterne
2
Wusste es, dachte aber nicht daran. Altes Android ist immer noch üblich, unterstützt Box-Größe, aber nicht berechnet. Ein einfaches Absolut und Polsterung spart den Tag.
Mathijs Segers
36

Machen Sie einfach einen Fallback, bevor der Calc den Trick macht.

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

Weitere Informationen finden Sie hier https://developer.mozilla.org/en-US/docs/Web/CSS/calc

Tommy Bjerregaard
quelle
17

benutze das

    .content
{
    width: 100%;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    padding-right: 500px;
    margin-right: -500px;
}
Mohamed Malik
quelle
4
Ist das nicht dasselbe, was Danield in seiner Antwort vorgeschlagen hat?
Skmasq
3
Nein, ist es nicht. Wenn Sie ein Bild mit 500 Pixel haben und einen flankierten Text mit (100% -500 Pixel) anzeigen möchten, habe ich nur festgestellt, dass ich sie in IE8 korrekt anzeigen kann, indem ich ein Negativ hinzufüge Rand zum Text. Andernfalls wird Text als Block angezeigt.
Giorgio
1
Rand rechts: -500px hat meine für Text arbeiten lassen. Ich weiß nicht, ob es etwas außer Kraft gesetzt hat, das ich verpasst habe, es ist mir egal. Lebensretter.
Myol
0

Ich habe gerade den größten Teil von 3 Stunden damit verbracht, dies für einen bestimmten Fall auf andriod-Geräten zu umgehen. Die Boxgröße konnte nicht funktionieren, daher habe ich sie als schmutzige Problemumgehung mit meinem JS verknüpft. Es ist jedoch keine jQuery erforderlich. :) :)

Aufgenommen auf Arbeitscode in 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 mit Ereignis-Listenern

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
};

Hoffe, das hilft jedem, der die Box-Größe nicht zum Laufen bringen kann! PS Ich habe Probleme mit iOS mit diesem ...

bhiqa
quelle
Es sieht so aus, als ob Sie das Präfix -webkit- für Android 2.3 benötigen
Kevin Newman
0

Ändern Sie die Breite von #menuLog mit% oder px und Sie werden Magie sehen. Funktioniert mit jedem Gerät auch <2.3

*{
	-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>

Mareks Dunkurs
quelle
0

Ich wollte die Alternative no-calc, no-border-box (dh CSS2) hinzufügen.

Blockelemente mit normalem Durchfluss haben anfangs width: autodie Breite des enthaltenen Blocks abzüglich der Rand-, Rand- und Füllbreiten.

Das obige Beispiel kann ohne Rahmen einfach als ausgeführt werden

.content {
    padding-left: 300px;
}

Ebenso mit

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

die effektive Breite ist 100% - 1px - 1em - 1rem.

Hat für absolut positionierte Elemente height: autoähnliche Eigenschaften:

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

Hier ist die effektive Höhe 100% - 1px - 1em - 1rem.

Sam
quelle