Procent zmiany rozmiaru obrazu CSS?

109

Próbuję zmienić rozmiar obrazu z procentem siebie. Na przykład chcę po prostu zmniejszyć obraz o połowę, zmieniając jego rozmiar do 50%. Ale zastosowanie width: 50%;spowoduje zmianę rozmiaru obrazu na 50% elementu kontenera (element nadrzędny, który może być <body>na przykład).

Pytanie brzmi, czy mogę zmienić rozmiar obrazu o określony procent bez używania javascript lub po stronie serwera? (Nie mam bezpośrednich informacji o rozmiarze obrazu)

Jestem prawie pewien, że nie możesz tego zrobić, ale chcę tylko sprawdzić, czy istnieją inteligentne rozwiązania CSS. Dzięki!

Min Ming Lo
źródło
Jeśli użyjesz, zajmie procent elementu zawierającego width: <number>%. Nie sądzę, aby można było to zrobić!
Aniket,

Odpowiedzi:

111

Mam dla ciebie 2 metody.

Metoda 1. Demo na jsFiddle

Ta metoda zmienia rozmiar obrazu tylko wizualnie, a nie rzeczywiste wymiary w DOM, a stan wizualny po zmianie rozmiaru wyśrodkowany w środku oryginalnego rozmiaru.

html:

<img class="fake" src="example.png" />

css:

img {
  -webkit-transform: scale(0.5); /* Saf3.1+, Chrome */
     -moz-transform: scale(0.5); /* FF3.5+ */
      -ms-transform: scale(0.5); /* IE9 */
       -o-transform: scale(0.5); /* Opera 10.5+ */
          transform: scale(0.5);
             /* IE6–IE9 */
             filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.9999619230641713, M12=-0.008726535498373935, M21=0.008726535498373935, M22=0.9999619230641713,SizingMethod='auto expand');
}​

Uwaga dotycząca obsługi przeglądarek : statystyki przeglądarek są wyświetlane w tekściecss.

Metoda 2. Demo na jsFiddle

html:

<div id="wrap">
    <img class="fake" src="example.png" />
    <div id="img_wrap">
        <img class="normal" src="example.png" />
    </div>
</div>

css:

#wrap {
    overflow: hidden;
    position: relative;
    float: left;
}

#wrap img.fake {
    float: left;
    visibility: hidden;
    width: auto;
}

#img_wrap {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}

#img_wrap img.normal {
    width: 50%;
}​

Uwaga: img.normal iimg.faketo ten sam obraz.
Uwaga dotycząca obsługi przeglądarek: ta metoda będzie działać we wszystkich przeglądarkach, ponieważ wszystkie przeglądarki obsługującss właściwości używane w metodzie.

Metoda działa w ten sposób:

  1. #wrapi #wrap img.fakepłynąć
  2. #wrapma overflow: hidden, aby jego wymiary były identyczne z wewnętrznym obrazem ( img.fake)
  3. img.fakejest jedynym elementem wewnątrz #wrapbez absolutepozycjonowania tak, aby nie przerywał drugiego kroku
  4. #img_wrapma absolutepozycjonowanie wewnątrz #wrapi rozciąga się na cały element ( #wrap)
  5. W wyniku czwartego kroku #img_wrapma takie same wymiary jak obraz.
  6. Ustawiając width: 50%na img.normaljego rozmiar jest 50%o #img_wrap, a więc 50%od oryginalnego rozmiaru obrazu.
Vladimir Starkov
źródło
Nie zmienia to rozmiaru obrazu do 50% jego oryginalnego rozmiaru, teraz jest to 50% rodzica img_wrap ..
Wesley
Zobacz moją zaktualizowaną odpowiedź, aby spróbować rozwiązać problem. Co myślisz?
Wesley
Myślę, że powinno być możliwe użycie display: none zamiast widoczności, jak w moim kodzie. W twoim przykładzie miejsce na fałszywy ukryty obraz jest nadal „zarezerwowane”, co utrudnia przepływ treści
Wesley
jest to niemożliwe, ponieważ główna sztuczka tkwi w dwóch zagnieżdżonych i pływających tagach.
Vladimir Starkov
1
transform:scale()Rozwiązanie ma duży problem chociaż. Nie współdziała dobrze z modelem pudełkowym CSS. Rozumiem przez to, że w ogóle nie wchodzi z nim w interakcję , więc otrzymujesz układ, który wygląda źle. Zobacz: jsfiddle.net/kahen/sGEkt/8
kahen
47

HTML:

<span>
    <img src="example.png"/>
</span>

CSS:

span {
    display: inline-block;
}
img {
    width: 50%;
}

To musi być jedno z najprostszych rozwiązań wykorzystujących podejście kontenerowe.

Podczas korzystania z podejścia z elementem kontenera to pytanie jest odmianą tego pytania . Sztuczka polega na tym, aby element kontenera otoczył obraz potomny powłoką, tak aby miał rozmiar równy rozmiarowi obrazu bez rozmiaru. Tak więc podczas ustawianiawidth właściwości obrazu jako wartości procentowej obraz jest skalowany względem jego oryginalnej skali.

Niektóre inne właściwości zmniejszenia objętości włączanie i wartości nieruchomości to: float: left/right, position: fixedi min/max-width, jak wspomniano w połączonej pytanie. Każdy ma swoje skutki uboczne, ale display: inline-blockbyłby bezpieczniejszym wyborem. Matt wspomniał float: left/rightw swojej odpowiedzi, ale błędnie to przypisał overflow: hidden.

Demo na jsfiddle


Edycja: jak wspomniał trojan , możesz również skorzystać z nowo wprowadzonego wewnętrznego i zewnętrznego modułu określania rozmiaru CSS3 :

HTML:

<figure>
    <img src="example.png"/>
</figure>

CSS:

figure {
    width: intrinsic;
}
img {
    width: 50%;
}

Jednak nie wszystkie popularne wersje przeglądarek obsługują go w chwili pisania tego tekstu .

Społeczność
źródło
@Każdy, jak naprawić nie zwijające się granice rozpiętości? skrzypce
KR
Właśnie tego potrzebowałem ... czegoś szybkiego i prostego, dzięki. Użyłem tego w ten sposób: HTML: <img src="https://www.google.com/images/srpr/logo11w.png"/> CSS: img { display: inline-block; width: 15%; }
Chnikki
Dla przyszłych czytelników: prawidłowa wartość do ustawienia figurejest width: fit-content;aktualna. Obsługa przeglądarek również jest dziś znacznie lepsza.
Dániel Kis-Nagy
12

Spróbuj zoomnieruchomości

<img src="..." style="zoom: 0.5" />

Edycja: Najwyraźniej FireFox nie obsługuje zoomwłaściwości. Powinieneś użyć;

-moz-transform: scale(0.5);

dla FireFox.

Emir Akaydın
źródło
4
Nie ma takiej właściwości CSS jak „zoom” i nie jest ona obsługiwana przez nikogo poza IE. Jest to zastrzeżona cecha firmy Microsoft i niestandardowa.
Rob
9
Niestety ta informacja jest nieaktualna. Zoom jest obecnie obsługiwany przez przeglądarki Internet Explorer, Chrome i Safari. FireFox i Opera jeszcze tego nie obsługują. Dlatego dodałem część edytującą. IE obsługuje go jako pierwszy, ale nie jedyny.
Emir Akaydın
Zgodnie z tym linkiem Opera wydaje się również obsługiwać zoom. FireFox jest jedynym, który nie obsługuje. fix-css.com/2011/05/css-zoom
Emir Akaydın,
2
Dlatego IE stracił połowę swojego udziału w rynku w ciągu ostatnich 8 lat. Jeśli nie możesz niezawodnie liczyć na to, że przeglądarki coś obsługują, nie masz wspólnej płaszczyzny. Specyfikację napisali sami producenci przeglądarek. Jeśli go tam nie umieścą, nie polegaj na tym, bo będziesz pisać wiele wierszy znaczników, tak jak to zrobiłeś. To nie jest znowu 1998 rok.
Rob
1
nie wiem, czy zauważyłeś, ale „zoom” jest obsługiwany przez Internet Explorer, Chrome, Safari i Opera. jest to dowód na to, że „zoom” nie jest specyficzny dla dostawcy. różni się tylko FireFox. więc powtarzam pytanie. jakie jest czyste rozwiązanie z kompatybilną właściwością css? moja odpowiedź jest najlepszą odpowiedzią, dopóki ktoś nie znajdzie odpowiedniego standardowego rozwiązania.
Emir Akaydın
5

Innym rozwiązaniem jest użycie:

<img srcset="example.png 2x">

Nie zostanie zweryfikowany, ponieważ srcatrybut jest wymagany, ale działa (z wyjątkiem dowolnej wersji IE, ponieważ srcsetnie jest obsługiwany).

benface
źródło
2

Jest to rzeczywiście możliwe i odkryłem to zupełnie przez przypadek podczas projektowania mojej pierwszej responsywnej witryny projektowej na dużą skalę.

<div class="wrapper">
  <div class="box">
    <img src="/logo.png" alt="">
  </div>
</div>

.wrapper { position:relative; overflow:hidden; }

.box { float:left; } //Note: 'float:right' would work too

.box > img { width:50%; }

Przepełnienie: ukryte podaje wysokość i szerokość opakowania, pomimo pływającej zawartości, bez użycia hacka clearfix. Następnie możesz pozycjonować zawartość za pomocą marginesów. Możesz nawet uczynić element div wrappera blokiem inline.

Matt
źródło
2

To bardzo stary wątek, ale znalazłem go, szukając prostego rozwiązania do wyświetlania zrzutu ekranu siatkówki (w wysokiej rozdzielczości) na wyświetlaczu o standardowej rozdzielczości.

Jest więc rozwiązanie tylko HTML dla nowoczesnych przeglądarek:

<img srcset="image.jpg 100w" sizes="50px" src="image.jpg"/>

To mówi przeglądarce, że obraz jest dwukrotnie większy od zamierzonego rozmiaru wyświetlacza. Wartości są proporcjonalne i nie muszą odzwierciedlać rzeczywistego rozmiaru obrazu. Aby osiągnąć ten sam efekt, można użyć 2w 1px. Atrybut src jest używany tylko przez starsze przeglądarki.

Miłym efektem jest to, że wyświetla ten sam rozmiar na siatkówce lub standardowym wyświetlaczu, zmniejszając się na drugim.

Max_B
źródło
0
function shrinkImage(idOrClass, className, percentShrinkage){
'use strict';
    $(idOrClass+className).each(function(){
        var shrunkenWidth=this.naturalWidth;
        var shrunkenHeight=this.naturalHeight;
        $(this).height(shrunkenWidth*percentShrinkage);
        $(this).height(shrunkenHeight*percentShrinkage);
    });
};

$(document).ready(function(){
    'use strict';
     shrinkImage(".","anyClass",.5);  //CHANGE THE VALUES HERE ONLY. 
});

To rozwiązanie używa js i jquery i zmienia rozmiar na podstawie tylko właściwości obrazu, a nie elementu nadrzędnego. Może zmieniać rozmiar pojedynczego obrazu lub grupy na podstawie parametrów class i id.

Aby uzyskać więcej, przejdź tutaj: https://gist.github.com/jennyvallon/eca68dc78c3f257c5df5

Jenny Vallon
źródło
0

To nie jest trudne podejście:

<div>
    <img src="sample.jpg" />
</div>

then in css:
div {
    position: absolute;
}

img, div {
   width: ##%;
   height: ##%;
}
nickthehero
źródło
0

Właściwie większość odpowiedzi tutaj naprawdę nie skalować obraz do szerokości sobie .

Musimy mieć szerokość i wysokość auto na img elemencie, abyśmy mogli zacząć od jego oryginalnego rozmiaru.

Następnie element kontenera może przeskalować obraz za nas.

Prosty przykład HTML:

<figure>
    <img src="[email protected]" />
</figure>

A oto zasady CSS. W tym przypadku używam absolutnego pojemnika:

figure {
    position: absolute;
    left: 0;
    top: 0;
    -webkit-transform: scale(0.5); 
    -moz-transform: scale(0.5);
    -ms-transform: scale(0.5); 
    -o-transform: scale(0.5);
    transform: scale(0.5);
    transform-origin: left;
} 

figure img {
    width: auto;
    height: auto;
}

Możesz dostosować położenie obrazu za pomocą reguł takich jak transform: translate(0%, -50%);.

Floris
źródło
-1

Myślę, że masz rację, po prostu nie jest to możliwe z czystym CSS, o ile wiem (nie mam na myśli cross-browser).

Edytować:

Okej, nie podobała mi się moja odpowiedź, więc trochę się zdziwiłem. Mogłem znaleźć ciekawy pomysł, który mógłby pomóc ... może w końcu JEST to możliwe (choć nie jest to najpiękniejsza rzecz na świecie):

Edycja: przetestowana i działająca w Chrome, FF oraz IE 8 i 9. . Nie działa w IE7.

Przykład jsFiddle tutaj

html:

<div id="img_wrap">
    <img id="original_img" src="http://upload.wikimedia.org/wikipedia/en/8/81/Mdna-standard-edition-cover.jpg"/>
    <div id="rescaled_img_wrap">
        <img id="rescaled_img" src="http://upload.wikimedia.org/wikipedia/en/8/81/Mdna-standard-edition-cover.jpg"/>
    </div>
</div>

css:

#img_wrap {
    display: inline-block;       
    position:relative;    
}

#rescaled_img_wrap {
    width: 50%;
}
#original_img {
    display: none;
}
#rescaled_img {
    width: 100%;
    height: 100%;
}
Wesley
źródło
Twój przykład zmienia rozmiar obrazu nieproporcjonalnie
Vladimir Starkov
Twoja metoda umożliwia zmniejszenie obrazu poprzez zmianę rozmiaru okna
Vladimir Starkov,
to dlatego, że używasz inline-block, dlatego szerokość #img_wrapzależy nie tylko od wewnętrznej szerokości HTML, ale także od szerokości kontekstu-kontenera.
Vladimir Starkov
O ile wiem, ten wyświetlacz: żaden obraz nic nie robi i można go usunąć. A może coś mi brakuje?
tremby