Die Transformationsskalierung behält den ursprünglichen Raum um das skalierte Element herum bei

Lesezeit: 5 Minuten

Benutzeravatar des Nachtclubs
Nachtclub

Ich habe zwei verschachtelte divs. Das inner one ist transform: scale(0.5).

Beide sind display: inline-block;.

Was ich tun muss, ist das outer div Passt seine Breite an die Breite des inneren an. Das sollte mir aber nicht passieren. Was passiert ist, dass das äußere div „denkt“, das innere div hat seine ursprüngliche Größe.

Das äußere Div passt seine Breite nur dann an die Breite des inneren an, wenn das innere Div es ist transform: scale(1) aber keinen Skalierungsfaktor kleiner als 1 verwenden, zum Beispiel: 0.5 (siehe Beispiel).

Ich brauche eine Möglichkeit, dies auf elegante Weise per CSS zu erreichen.

.red {
  background-color: #f00;
}

.green {
  background-color: #0f0;
}

.box_1,
.box_2 {
  display: inline-block;
}

.box_1 {
  width: 300px;
  height: 300px;
  transform: scale(0.5);
  transform-origin: left top;
}
<div class="box_2 green">
  <div class="box_1 red">Hello World</div>
</div>

Irgendeine Idee, wie man das lösen kann?

Ein brutaler Weg wäre, den pro Element benötigten Platz virtuell zu reduzieren.

Ihr Beispiel zeigt eine bekannte Breite und Höhe, sodass es einfach ist. Andernfalls benötigen Sie eine Javascript-Methode.

.box_1 {
    width:  300px;
    height: 300px;
    transform: scale(0.5);
    transform-origin: left top;
  margin-bottom:-150px;
  margin-right:-150px;
}

https://jsfiddle.net/0bc4sxk3/1/

Eine Skalierung würde positive Margen bedeuten.

Die Transformation erfolgt nur auf dem Bildschirm, die Elemente verwenden immer noch den anfänglichen Raum und Platz, der im Fluss des Dokuments benötigt wird.

  • Auf diese Weise funktioniert es bei mir nicht, weil ich brauche, dass das äußere Div seine Größe an das innere anpasst. Mit anderen Worten: beide haben die gleiche Größe.

    – Nachtclub

    10. Mai 2016 um 15:00 Uhr

  • @nightclub Wenn Sie für beide die gleiche Größe festlegen, gibt es keine Möglichkeit, dass der Elternteil schrumpft. Das hat deiner Geige gefehlt 🙁 Ich vermute, du missverstehst, wie die Transformation funktioniert

    – G-Cyrillus

    10. Mai 2016 um 15:03 Uhr


  • Ich habe dem äußeren Div keine Größe angegeben, also erwartete ich, dass das äußere Div schrumpfen könnte

    – Nachtclub

    10. Mai 2016 um 15:08 Uhr

  • @nightclub wird es nicht, wie ich am Ende meiner Antwort geschrieben habe. Position: relativ; + Coordinates macht dasselbe, es verschiebt nur das Element auf dem Bildschirm, nicht im Layout;) jsfiddle.net/0bc4sxk3/3 ähnliches Problem wie bei der Transformation. das ist das normale verhalten 🙂

    – G-Cyrillus

    10. Mai 2016 um 15:09 Uhr


Benutzeravatar von Adrian B
Adrian B

Ich denke, dass eine Lösung darin besteht, das verkleinerte Element in ein Element mit einzuwickeln overflow: hidden. Die Verpackung sollte die genauen Abmessungen des verkleinerten Inhalts haben.

Diese Lösung war für mich die beste.

.wrapper {
  width: 150px;
  height: 150px;
  overflow: hidden;
}

.content {
  position: absolute;
  top: 0;
  left: 0;
  width: 300px;
  height: 300px;
  transform: scale(0.5);
  transform-origin: left top;
}

.box_1,
.box_2 {
  display: inline-block;
}

.red {
  background-color: #f00;
}

.green {
  background-color: #0f0;
}
<div class="box_2 green">
  <div class="box_1 red">Hello World</div>
</div>

  • Schöne Lösung! Allerdings denke ich position: absolute wird nicht benötigt.

    – Shahriar

    6. August 2021 um 15:36 Uhr

  • Ich habe Ihre Lösung in eine Snippet-Demo konvertiert, wobei ich den ursprünglichen HTML-Code und das ursprüngliche Design verwendet habe. Funktioniert es wie erwartet? Bitte überarbeiten Sie nach Bedarf, um dies zu demonstrieren.

    – Escherholz

    11. Februar um 16:27 Uhr

  • Dies sollte stattdessen die akzeptierte Antwort sein

    – ashuvssut

    15. August um 13:31 Uhr

  • Gute Lösung! Ich hatte genau das gleiche Problem und Überlauf: versteckt; hat die Arbeit für mich erledigt

    – NULL

    gestern

Benutzeravatar von Guy Moreillon
Guy Moreillon

Wenn Sie spät zur Party kommen, aber eine andere Möglichkeit besteht darin, ein Größenelement zu verwenden, das leer und nicht skaliert ist, die gleiche äußere Größe wie das verkleinerte Element hat und unter dem skalierten Element sitzt. Dies steuert die Größenanpassung des übergeordneten Elements, und das skalierte Element wird dann absolut über dem Größenelement positioniert.

.red { background-color: #f00; }
.green { background-color: #0f0; }
.blue { background-color: #00f; }

.container {
	position: relative;
	display: inline-block;
}

.sizingBox {
  width: 150px;
  height: 150px;
}

.content {
  position: absolute;
  top: 0;
  left: 0;
	width: 300px;
	height: 300px;
	transform: scale(0.5);
	transform-origin: left top;
}
	<div class="container green">
      <div class="sizingBox blue"></div>
    	<div class="content red">Hello World</div>
	</div>

Wenn jemand nach einer Copy-Pasta-React-Komponente sucht, scheint dies basierend auf Guys Code zu funktionieren:

import * as React from "react";

interface Props
  extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
  scale?: number;
  style?: React.CSSProperties;
  fullHeight: number;
  fullWidth: number;
}

export const ScaleBox: React.FC<Props> = ({
  scale = 1,
  style,
  fullWidth,
  fullHeight,
  children,
  ...rest
}) => {
  return (
    <div
      data-comment={"ScaleBox Container"}
      style={{ position: "relative", display: "inline-block", ...style }}
      {...rest}
    >
      <div
        data-comment={"ScaleBox Sizing Box"}
        style={{ width: fullWidth * scale, height: fullHeight * scale }}
      ></div>
      <div
        data-comment={"ScaleBox Content"}
        style={{
          transform: `scale(${scale})`,
          transformOrigin: "top left",
          position: "absolute",
          top: 0,
          left: 0,
        }}
      >
        {children}
      </div>
    </div>
  );
};

Sogar später habe ich auf der React-Komponente von mikeysee aufgebaut und eine geschrieben, die mit Inhalten funktioniert, die dynamisch skaliert werden (sie verwendet negative Ränder, um eine Größenänderung der Kinderinhalte zu vermeiden):

import * as React from 'react';
import useResizeObserver from '@react-hook/resize-observer';

interface Props
    extends React.DetailedHTMLProps<
        React.HTMLAttributes<HTMLDivElement>,
        HTMLDivElement
    > {
    scale?: number;
    style?: React.CSSProperties;
}

/**
 * The ScaleBox is an element that scales its content using CSS transform scale
 * and makes sure the flow around the box is as if the box had the size
 * according to the applied scale.
 *
 * The parent element of a ScaleBox must have the overflow: 'hidden' style.
 */
export const ScaleBox: React.FC<Props> = ({ scale = 1, style, children }) => {
    const [marginX, setMarginX] = React.useState('0px');
    const [marginY, setMarginY] = React.useState('0px');
    const divRef = React.useRef<HTMLDivElement>(null);

    useResizeObserver(divRef, (target) => {
        setMarginX(`${(scale - 1) * target.contentRect.width}px`);
        setMarginY(`${(scale - 1) * target.contentRect.height}px`);
    });

    React.useEffect(() => {
        if (divRef.current) {
            setMarginX(`${(scale - 1) * divRef.current.offsetWidth}px`);
            setMarginY(`${(scale - 1) * divRef.current.offsetHeight}px`);
        }
    }, [scale]);

    return (
        <div
            ref={divRef}
            style={{
                ...style,
                transform: `scale(${scale})`,
                transformOrigin: 'top left',
                marginRight: marginX,
                marginBottom: marginY
            }}
        >
            {children}
        </div>
    );
};

  • Reagieren ist nicht auf die Frage getaggt. Diese Antwort ist weit außerhalb des Rahmens.

    – Escherholz

    11. Februar um 16:24 Uhr

  • Reagieren ist nicht auf die Frage getaggt. Diese Antwort ist weit außerhalb des Rahmens.

    – Escherholz

    11. Februar um 16:24 Uhr

1430120cookie-checkDie Transformationsskalierung behält den ursprünglichen Raum um das skalierte Element herum bei

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy