使用2个稍微旋转的SVG作为导航背景?

问题描述 投票:5回答:2

我正在为我的网站创建导航菜单,我想要做的是让背景是2个矩形SVG的组合,每个SVG略微旋转离轴并重叠。边缘将延伸超出屏幕的边缘,从而无法看到它们。 SVG应在所有断点处保持相同的高度(120px),并且导航应在容器内垂直居中(即使由于旋转它将显示在偏离中心)。当我调整浏览器窗口大小时,我当前的尝试使SVG高度缩小,另外我在对齐时遇到了一些问题。有没有更好的方法来实现这一目标?

.hero-bg {
  height:20vh;
  min-height:200px;
  max-height:350px;
  width:100%;
  background:url('http://placehold.it/1920x1080');
  background-size:cover;
}
.navigation {
	position:relative;
  height:120px;
  overflow:hidden;
}
.nav-bg-1 {
  fill:red;
}
.nav-bg-2 {
  fill:black;
}
.navigation svg {
	position:absolute;
	top:-10px;
	width:110%;
	left:-5%;
}
.navigation ul {
  list-style-type:none;
  padding:0;
  margin:0;
  position:absolute;
  top:50%;
  transform:translateY(-50%);
}
  .navigation ul > li {
    display:inline-block;
  }
    .navigation ul > li > a{
      color:#fff;
      text-transform:uppercase;
      text-decoration:none;
    }
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/css/bootstrap.min.css" rel="stylesheet"/>
<section id="hero">
  <div class="hero-bg"></div>
  <div class="navigation">
      <svg viewBox="0 0 2027.79 155.34">
          <rect class="nav-bg-1" x="953.89" y="-935.33" width="120" height="2026" transform="translate(918.54 1090.05) rotate(-89)"/>
          <rect class="nav-bg-2" x="0.89" y="14.67" width="2026" height="120" transform="translate(-0.32 4.42) rotate(-0.25)"/>
      </svg>
      <div class="container">
          <div class="row">
              <div class="col-sm-4 hidden-xs">
                <!-- LOGO -->
              </div>
              <div class="col-sm-8">
                  <ul>
                      <li><a href="#">Home</a></li>
                      <li><a href="#">About</a></li>
                      <li><a href="#">Products</a></li>
                      <li><a href="#">Contact</a></li>
                  </ul>
              </div>
          </div>
      </div>
  </div>
</section>

一旦我能够完成这些背景条,我的计划是动画它们并稍微改变形状(使它们不是完美的矩形),因为用户使用MorphSVG滚动。因此,解决方案必须使用SVG代替备用解决方案。

这是我想要的结果的模型。导航将位于容器内,但红色/黑色条应以任何屏幕大小延伸到屏幕边缘:

enter image description here

html css svg
2个回答
1
投票

我可能会像这样使用伪元素和偏斜变换:

.navigation {
  display: flex;
  justify-content:center;
  margin-top:50px;
  height:80px;
  padding:30px 0;
  position:relative;
  margin-bottom:50px;
}
.navigation:before {
  content:"";
  position:absolute;
  right:0;
  left:0;
  top:10px;
  bottom:0;
  background:#000;
  transform:skewY(-3deg);
  z-index:2;
}
.navigation:after {
  content:"";
  position:absolute;
  right:0;
  left:0;
  top:10px;
  bottom:0;
  background:red;
  transform:skewY(3deg);
  z-index:1;
}
.navigation ul {
 position:relative;
 z-index:3;
}

.navigation ul>li {
  display: inline-block;
}

.navigation ul>li>a {
  color: #fff;
  text-transform: uppercase;
  text-decoration: none;
}
<div class="navigation">
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Products</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</div>

更新

由于解决方案应该使用SVG,这里有一个涉及一些js的解决方案。我的想法是使用skew和svg创建我之前所做的但具有固定宽度。然后我只是使用JS代码来缩放寡妇调整大小,使其保持全宽:

$('.back-nav').css('transform', 'scaleX(' + $('.navigation').width() / 500 + ')');
$(window).resize(function() {
  $('.back-nav').css('transform', 'scaleX(' + $('.navigation').width() / 500 + ')');
});
body {
  margin: 0;
}

.navigation {
  display: flex;
  justify-content: center;
  margin-top: 50px;
  height: 80px;
  width: 100%;
  padding: 30px 0;
  position: relative;
  margin-bottom: 50px;
}

.back-nav {
  position: absolute;
  top: 0;
  left: 0;
  transform-origin: left;
}

.navigation ul {
  position: relative;
  z-index: 3;
}

.navigation ul>li {
  display: inline-block;
}

.navigation ul>li>a {
  color: #fff;
  text-transform: uppercase;
  text-decoration: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="navigation">
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Products</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
  <svg class="back-nav" width="500" height="200" xmlns="http://www.w3.org/2000/svg">
  <rect x="0" y="20" width="500" fill="red" height="120" transform="skewY(3)"/>
  <rect x="0" y="50" width="500" height="120" transform="skewY(-3)"/>
</svg>
</div>

使用背景而没有任何JS的另一个想法(但你不能在它上面应用变形,因为它是背景)

body {
 margin:0;
}
.navigation {
  display: flex;
  justify-content:center;
  margin-top:50px;
  height:120px;
  width:100%;
  position:relative;
  margin-bottom:50px;
  background-image: url('data:image/svg+xml;charset=UTF-8,<svg version="1.1"  xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" preserveAspectRatio="none" viewBox="0 0 25.1 30" style="enable-background:new 0 0 25.1 30;" xml:space="preserve"><polygon points="25,0 25,20 0,25 0,5" fill="red"/><polygon points="25,5 25,25 0,20 0,0" fill="black"/></svg>');
  background-size:100%;
}

.navigation ul {
 position:relative;
 z-index:3;
}

.navigation ul>li {
  display: inline-block;
}

.navigation ul>li>a {
  color: #fff;
  text-transform: uppercase;
  text-decoration: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="navigation">
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Products</a></li>
    <li><a href="#">Contact</a></li>
  </ul>

</div>

1
投票

如果我理解得很好,在你的情况下,我会独立放置两个svg-bars。也许,分组在div中。

(在下一个片段中,你仍然需要添加一些媒体查询来将ul定位在黑条中间,以及整个.navigation元素。但我想你会得到这个想法)

.hero {
  position: relative;
}
.hero-bg {
  height:20vh;
  min-height:200px;
  max-height:350px;
  width:100%;
  background:url('http://placehold.it/1920x1080');
  background-size:cover;
  z-index: -1;
  position: absolute;
}

.navigation {
  position:relative;
  width: 100vw;
  min-height: auto;
  height: auto;
  overflow:hidden;
  padding-top: 185px;
}

.svg-wrapper {
  position: absolute;
  width: 100%;
  height: 100%;
}

.nav-bg-1 {
  width: 105vw;
  position: absolute;
  z-index: -1;
  height: 50px;
  height: auto;
  left:-1em;
}

.nav-bg-rect-1 {
  fill: red
}

.nav-bg-rect-2 {
  fill: black;
}

.navigation ul {
  list-style-type:none;
  padding:0;
  margin:0;
  position:relative;
  padding: .6rem 1rem 1rem;
  height: 100%;
  width: 100%;
  transform: rotate(-1.01deg);
}

.navigation ul > li {
  display:inline-block;
}

.navigation ul > li > a{
  color:white;
  display: block;
  //padding: 2rem 1rem;
  text-transform:uppercase;
  text-decoration:none;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta.2/css/bootstrap.css" rel="stylesheet"/>

<section id="hero" class="hero">
  <div class="hero-bg"></div>
  <div class="navigation">
    
    <div class="svg-wrapper">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1117.79 73" class="nav-bg-1">
        <defs></defs><title>rectred</title><g id="Laag_2" data-name="Laag 2"><g id="Laag_1-2" data-name="Laag 1"><rect class="nav-bg-rect-1" x="534.9" y="-522" width="48" height="1117" transform="matrix(0.02, -1, 1, 0.02, 509.89, 594.44)"/></g></g>
      </svg>
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1117.8 79.83" class="nav-bg-1">
        <title>rectblack</title><g id="Laag_2" data-name="Laag 2"><g id="Laag_1-2" data-name="Laag 1"><rect class="nav-bg-rect-2" x="0.4" y="7.92" width="1117" height="64" transform="translate(-0.51 7.93) rotate(-0.81)"/></g></g>
      </svg>
    </div>
    
    <div class="container">
          <div class="row">
              <div class="col-sm-4 hidden-xs">
                <!-- LOGO -->
              </div>
              <div class="col-sm-8">
                  <ul class="nav-bar">
                      <li><a href="#">Home</a></li>
                      <li><a href="#">About</a></li>
                      <li><a href="#">Products</a></li>
                      <li><a href="#">Contact</a></li>
                  </ul>
              </div>
          </div>
      </div>
  </div>
</section>

我认为使用两个独立的svg元素很容易阅读/工作。在这种情况下包裹在div中。绝对定位在你的导航列表后面。

如果我看到正确,您的菜单会略微旋转(如黑条?)。所以,我假设你不会改变这个标准。否则,我看不到您的菜单会发生什么。

如果这不是你想要的,你能解释一下,你会在这个栏中添加什么样的转换?

以防我在其上工作的codepen:https://codepen.io/fspin/pen/YYJyNY。 (在片段中有一个有趣的卷轴!)


更新:我在想更多。这也可能是正确的方向:https://codepen.io/fspin/pen/zpmdOd

我想你需要考虑一些事情:

  1. 为了让svg流出视口,你可以使用vwvh作为单位,你的容器将拥有属性overflow hidden
  2. 为了跟踪黑条的位置,也许你必须把它放在容器内。这会产生另一个问题:它不会从视口流出。那么,也许有两个svgs?一个在容器内,一个(真实的)在svg的包装内?

也许我在想这个,但我喜欢这个挑战。如果我正在思考正确的方向,我们愿意多听听。

免责声明:我不是SVG的专家,不是CSS的专家,但我认为我已经足够了解,试图以一种不太苛刻的方式来解决这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.