Как вырезать прямоугольник сверху и снизу изображения? - PullRequest
1 голос
/ 26 февраля 2020

example

Я пытаюсь вырезать прямоугольник из изображения. Пожалуйста, скажите мне лучший способ сделать это. Мне нужно поддерживать IE 11. (без клипа).

Я уже пытался это сделать, но не очень доволен результатом.

body {
  margin: 0;
}

.block {
  height: 400px;
  display: flex;
}

.block-image,
.block:before,
.block:after {
  content: "";
  position: relative;
  height: 100%;
  background-image: url("https://images.unsplash.com/photo-1558980664-10e7170b5df9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1951&q=80");
  background-size: 100vw auto;
  background-repeat: no-repeat;
}

.block:before {
  top: 50px;
  flex: auto;
  background-position: left top -50px;
}

.block:after {
  flex: auto;
  background-position: right top;
}

.block-image {
  flex: 1 1 300px;
  max-width: 300px;
  background-position: center top;
}
<div class="block">
  <div class="block-image"></div>
</div>

1 Ответ

2 голосов
/ 26 февраля 2020

Я бы оптимизировал код, как показано ниже:

body {
  margin: 0;
  background:pink;
}

.block {
  margin:50px 0;
  height: 400px;
  background:url("https://images.unsplash.com/photo-1558980664-10e7170b5df9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1951&q=80") no-repeat;
  background-size:0 0;
}

.block:before,
.block:after {
  content: "";
  float:left;
  height: 100%;
  background: inherit;
}

.block:before {
  width:30%;
  background-size:333.33% auto; /* 100%/0.3 */
  background-position:left 0 top 0;
  transform:translateY(-50px);
}

.block:after {
  width:70%;
  background-size:142.85% auto; /* 100%/0.7 */
  background-position:right 0 top -50px;
}
<div class="block">
</div>

Для центрирования изображения:

body {
  margin: 0;
  background:pink;
}

.block {
  margin:50px 0;
  height: 400px;
  background:url("https://images.unsplash.com/photo-1558980664-10e7170b5df9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1951&q=80") no-repeat;
  background-size:0 0;
}

.block:before,
.block:after {
  content: "";
  float:left;
  height: 100%;
  background: inherit;
}

.block:before {
  width:30%;
  background-size:333.33% auto; /* 100%/0.3 */
  background-position:left center;
  transform:translateY(-50px);
}

.block:after {
  width:70%;
  background-size:142.85% auto; /* 100%/0.7 */
  background-position:right 0 top calc(50% - 50px);
}
<div class="block">
</div>

Если вы хотите увеличить ширину изображения:

body {
  margin: 0;
  background:pink;
}

.block {
  margin:50px 0;
  height: 400px;
  background:url("https://images.unsplash.com/photo-1558980664-10e7170b5df9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1951&q=80") no-repeat;
  background-size:0 0;
}

.block:before,
.block:after {
  content: "";
  float:left;
  height: 100%;
  background: inherit;
}

.block:before {
  width:30%;
  background-size:500% auto; /* 150%/0.3 */
  background-position:left 25% top 50%;
  transform:translateY(-50px);
}

.block:after {
  width:70%;
  background-size:214.275% auto; /* 150%/0.7 */
  background-position:right 25% top calc(50% - 50px);
}
<div class="block">
</div>

Вот более общее решение c с использованием CSS переменных и calc(). Я знаю, что вы хотите поддержать IE, но это только для демонстрационных целей, и вы можете легко использовать вычисленные значения, как в примерах выше:

body {
  margin: 0;
  background:pink;
}

.block {
  --w:0.3;  /* width of left part (without unit and from 0 to 1 (1 = 100%) )*/
  --h:50px; /* height of the cut*/
  --s:1.5;  /* scale factor of the image (1 = 100% width of container)*/
  
  margin:calc(var(--h) + 10px) 0;
  height: 400px;
  background:url("https://images.unsplash.com/photo-1558980664-10e7170b5df9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1951&q=80") 0/0 no-repeat;
}

.block:before,
.block:after {
  content: "";
  float:left;
  height: 100%;
  background: inherit;
}

.block:before {
  width:calc(var(--w)*100%);
  background-size:calc(var(--s) * (100%/var(--w)))  auto;
  background-position:
    left calc( 
          100% *
           ( (var(--s) - 1) /
             (2* (var(--s) - var(--w)) ) 
           ) 
          ) 
     top 50%;
  transform:translateY(calc(-1*var(--h)));
}

.block:after {
  width:calc(100%*(1 - var(--w)));
  background-size:calc(var(--s) * (100%/(1 - var(--w)))) auto;
  background-position:
   right calc( 
          100% *
           ( (var(--s) - 1) /
             (2* (var(--s) - 1 + var(--w)) ) 
           ) 
          )
   top calc(50% - var(--h));
}
<div class="block">
</div>

<div class="block" style="--s:2;--h:100px;--w:0.5">
</div>

<div class="block" style="--s:1.75;--h:150px;--w:0.8">
</div>

<div class="block" style="--s:3;--h:30px;--w:0.7">
</div>

Расчет позиции немного сложен, вы можете обратиться к следующему вопросу, чтобы понять, как он работает: Использование процентных значений с background- позиция на линейном градиенте



Чтобы сохранить этот ответ обобщенным c Я также рассмотрю способ clip-path, который является наиболее логичным даже если он не поддерживается IE

body {
  margin: 0;
  background:pink;
}

.block {
  --w:30%;  /* width of left part */
  --h:50px; /* height of the cut*/
  
  margin:10px 0;
  height: 400px;
  background:url("https://images.unsplash.com/photo-1558980664-10e7170b5df9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1951&q=80") center/cover no-repeat;
  
  clip-path:polygon(
   0 0,var(--w) 0,var(--w) var(--h),100% var(--h),
   100% 100%,var(--w) 100%,var(--w) calc(100% - var(--h)),0 calc(100% - var(--h)));
}
<div class="block">
</div>

<div class="block" style="--h:100px;--w:50%">
</div>

<div class="block" style="--h:150px;--w:80%">
</div>

<div class="block" style="--h:30px;--w:70%">
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...