Я пытаюсь воспроизвести логотип VueJS, используя только CSS, а не импортируя SVG или что-то еще.
Я использовал clippy, чтобы получить правильное clip-path, но у меня все еще нет возможности найти правильное вращение между плечами логотипа.
Это то, что я пробовал до сих пор
.wrapper {
height: 100svh;
display: flex;
flex-direction: row;
align-items: center;
transform: rotate(-60deg)
}
.wrapper div {
width: 250px;
height: 45px;
}
.left {
transform: rotate(-60deg) translate(60%, 200%) scale(-1);
}
.green {
background-color: #42b883;
clip-path: polygon(33px 0, calc(100% - 33px) 0, 100% 100%, 0% 100%);
}
.blue {
background-color: #35495e;
clip-path: polygon(
66px 0,
calc(100% - 66px) 0,
calc(100% - 33px) 100%,
33px 100%
);
}<div class = "wrapper">
<main class = "left">
<div class = "blue"></div>
<div class = "green"></div>
</main>
<main class = "right">
<div class = "blue"></div>
<div class = "green"></div>
</main>
</div>Я пробовал различные переводы, преобразования и т. д., но ни одно из них не кажется логичным, хотя я думал, что поворота на 60 градусов будет достаточно.
Оказывается, это совсем не так.






Если вы хотите использовать технику clip-path, это работает, но я мог бы придерживаться только клип-пути, а не пытаться вращать и отражать путь вашей фигуры после того, как вы его создали. clip-path достаточно мощный, чтобы справиться со всем этим. Обратитесь к этой странице MDN для получения информации о том, как использовать clip-path с polygon() — это не слишком сложно — это просто список пар координат, разделенных запятыми, где каждое значение можно просто определить в процентах.
В приведенном ниже примере я создаю два элемента div: один для синего, а другой для зеленого. Я накладываю два элемента div друг на друга и устанавливаю их одинаковый размер.
/*
Layer the two divs over each other,
and set the size of the divs.
*/
.blue, .green {
position: absolute;
top: 0;
left: 0;
width: 512px;
height: 444px;
}
.blue {
background-color: #34495e;
clip-path: polygon(
20% 0%, /* top left */
40% 0%,
50% 23%, /* top of the inside of the V */
60% 0%,
80% 0%, /* top right */
50% 60% /* bottom of the V */
);
}
.green {
background-color: #41b883;
clip-path: polygon(
0% 0%, /* top left */
20% 0%,
50% 60%, /* top of the inside of the V */
80% 0%,
100% 0%, /* top right */
50% 100% /* bottom of the V */
);
}<div class = "blue"></div>
<div class = "green"></div>Если вместо этого вы хотите поработать над вращением/перемещением, вот как вы можете это сделать (без использования clip-path).
Шаг 1. Создайте темно-синий элемент div с зеленой нижней границей. Переместите и поверните его в нужное положение. Верхняя часть будет обрезана просто потому, что она выступает над верхним краем страницы.
/*
A rotated dark-blue box with a light-green border
under it. This is getting cropped by its #left-crop-container parent.
*/
#left-content {
position: relative;
background-color: #34495e;
width: 550px;
height: 82px;
left: -72px;
top: 96px;
border-bottom: 89px solid #41b883;
transform: rotate(60deg);
}<div id = "left-content"></div>Шаг 2: Поместите нашу фигурку в контейнер. Присвойте контейнеру фиксированный размер и настройте его так, чтобы обрезать все, что выходит из него (с помощью overflow: hidden).
В приведенном ниже примере я обрисую поле, в котором выполняется обрезка, красным, чтобы было легче увидеть, что происходит.
/*
The left half of the logo will be put inside of this box.
Anything that hangs out will be cropped via the `overflow: hidden` rule
*/
#left-crop-container {
width: 256px;
height: 445px;
overflow: hidden;
outline: solid red;
}
/*
A rotated dark-blue box with a light-green border
under it. This is getting cropped by its #left-crop-container parent.
*/
#left-content {
position: relative;
background-color: #34495e;
width: 550px;
height: 82px;
left: -72px;
top: 96px;
border-bottom: 89px solid #41b883;
transform: rotate(60deg);
}<div id = "left-crop-container">
<div id = "left-content"></div>
</div>Шаг 3: Теперь нам просто нужно отразить его на другую сторону. Я собираюсь сделать это, скопировав тот же HTML-код, но я помещу вставленный HTML-код внутри контейнера div, содержащего CSS, чтобы перевернуть его.
/*
If the container is smaller than a logo
(e.g. because you're using a really small screen)
make sure the right half doesn't try
to wrap under the left half.
*/
#logo {
text-wrap: nowrap;
}
/*
Makes the mirrored right half appear to
the right of the left half, instead of under it.
*/
#logo > * {
display: inline-block
}
/*
The left half of the logo will be put inside of this box.
Anything that hangs out will be cropped via the `overflow: hidden` rule
*/
#left-crop-container {
width: 256px;
height: 445px;
overflow: hidden;
}
/*
A rotated dark-blue box with a light-green border
under it. This is getting cropped by its #left-crop-container parent.
*/
#left-content {
position: relative;
background-color: #34495e;
width: 550px;
height: 82px;
left: -72px;
top: 96px;
border-bottom: 89px solid #41b883;
transform: rotate(60deg);
}
/* Mirrors its content, and shifts it slightly */
#mirror-contents-to-right {
position: relative;
transform: rotateY(180deg);
left: -5px;
}<div id = "logo">
<div id = "left-crop-container">
<div id = "left-content"></div>
</div>
<div id = "mirror-contents-to-right">
<div id = "left-crop-container">
<div id = "left-content"></div>
</div>
</div>
</div>Та-Да!
Спасибо за старания и подробные объяснения. clip-path действительно достаточно мощный инструмент, спасибо за напоминание!
Вы можете получить его, используя один div, используя всего 2 градиента:
.vue {
width: 500px;
height: 500px;
background-image: linear-gradient(60deg, transparent 54%, #00BD82 54%, #00BD82 70%, #3E5468 70%, #3E5468 85%, transparent 85%), linear-gradient(-60deg, transparent 54%, #00BD82 54%, #00BD82 70%, #3E5468 70%, #3E5468 85%, transparent 85%);
background-size: 50% 100%, 50% 100%;
background-position: 0 0, 100% 0;
background-repeat: no-repeat;
transform: scale(0.5);
}<div class = "vue"></div>Другая возможность без использования градиентов, чтобы избежать сглаживания:
Цвета задаются как граница и тень на квадратном элементе div. Угол можно сделать с перекосом:
.vue {
width: 140px;
height: 140px;
border: solid #00BD82;
border-width: 0px 30px 30px 0px;
box-shadow: inset -30px -30px #3E5468;
transform: rotate(45deg) skew(15deg, 15deg);
clip-path: polygon(0 100%, 100% 0, 100% 100%);
}<div class = "vue"></div>Сделайте это с помощью :before и :after + clip-path к ним.
Это довольно просто, но чтобы сделать его адаптивным - используйте aspect-ratio.
Вот пример, где я добавил рядом оригинал svg для сравнения:
.logo {
width: min(230px, 100%);
aspect-ratio: 1.154;
position: relative;
&:before,
&:after {
content: '';
position: absolute;
}
&:before {
inset: 0 20% 40%;
background-color: #34495e;
clip-path: polygon(0 0, 30% 0, 50% 40%, 70% 0, 100% 0, 50% 100%);
}
&:after {
inset: 0;
background-color: #41b883;
clip-path: polygon(0 0, 20% 0, 50% 60%, 80% 0, 100% 0, 50% 100%);
}
}
/* Just for example */
body {
display: flex;
gap: 2px;
margin: 0;
}
.logo-svg {
width: min(230px, 100%);
aspect-ratio: 1.154;
display: flex;
svg {
width: 100%;
height: 100%;
}
}<div class = "logo"></div>
<div class = "logo-svg">
<svg xmlns = "http://www.w3.org/2000/svg" version = "1.1" viewBox = "0 0 261.76 226.69"><g transform = "matrix(1.3333 0 0 -1.3333 -76.311 313.34)"><g transform = "translate(178.06 235.01)"><path d = "m0 0-22.669-39.264-22.669 39.264h-75.491l98.16-170.02 98.16 170.02z" fill = "#41b883"/></g><g transform = "translate(178.06 235.01)"><path d = "m0 0-22.669-39.264-22.669 39.264h-36.227l58.896-102.01 58.896 102.01z" fill = "#34495e"/></g></g></svg>
</div>Я сделал кучу одноэлементных логотипов только на CSS, и VueJS — первый в списке.
Всего 4 объявления и одно значение для контроля размера.
.vue {
width: 200px; /* control the size */
aspect-ratio: 1.18;
background: conic-gradient(from -30deg at 50% 60%, #34495e 60deg, #41b783 0);
clip-path: polygon(0 0, 39% 0, 50% 23%, 61% 0, 100% 0, 50% 100%);
}<div class = "vue"></div>Градиент — хорошее решение. Но он ребристый )) Это видно и в вашем ответе, и в ответе @vals. Вот и приходится сглаживать — и это раздражает.
@imhvost Я пока не вижу никакого АА (или необходимости в нем) ни по каким ответам. Даже при масштабе 500% + полностью приближенном для меня результат достаточно хороший. Возможно, это связано с настройками вашей ОС/системы.
Но ребристость видна prnt.sc/kbAl1_jjIS1A
@imhvost На моей стороне такого точно нет.
Без проблем. Я просто констатирую факт. Градиент плохо сглаживается.
Очень хороший и короткий ответ. Все clip-path + conic-gradient + aspect-ratio весьма впечатляют. Также довольно легко изменить его размер. В целом, с такими вещами не следует справляться теми инструментами, которые я пробовал изначально, ха-ха! PS: только что понял, что уже подписан на тебя в Твиттере, это имеет смысл относительно крутых проектов CSS, которые ты реализуешь. Спасибо, чувак!
Вот, кстати, хорошая статья о том, как использовать Gradient Bug от уважаемого ответчика.
Я опубликовал еще один фрагмент, чтобы избежать сглаживания в фоновых методах.