Using 2 slightly rotated SVGs as background navigation?

I am creating a navigation menu for my site, and what I would like to do is a background of two rectangular SVGs, each of which is slightly rotated from the axis and overlays. The edges will extend beyond the edges of the screen so that they are not visible. SVGs must remain at the same height (120 pixels) at all breakpoints, and the navigation should be centered vertically inside the container (although it will appear in the center due to rotation). My current attempt has the height of SVGs when I resize the browser window, in addition, I am having some alignment problems. Is there a better way to do this?

.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> 

As soon as I can execute these background stripes, my plan is to animate them and slightly change their shape (make them not perfect rectangles) as the user scrolls using MorphSVG . Because of this, the solution should use SVG instead of alternative solutions.

Here is the layout of my desired result. The navigator will be inside the container, but the red / black bars should extend to the edge of the screen at any screen size:

enter image description here

+5
source share
2 answers

I would probably go with a pseudo-element and a skew transform as follows:

 .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> 

Update

Since the solution should use SVG, here is a solution that includes some js. The idea is to create what I did earlier using skew and svg, but with a fixed width. Then I just use the JS code to scale when the widow is resized, so it remains complete:

 $('.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> 

Another idea that uses background without JS (but you cannot apply morphing on it as background)

 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
source

If I understood well, in your case I would put both svg-bars on my own. Maybe grouped in a div.

(In the next snippet, you still need to add some media queries to put ul in the middle of the black bar and the entire .navigation element. But I think you will understand this idea)

 .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> 

I think it is easy to read / work with two separate svg elements. In this case, wrapped in a div. Built behind the navigation list.

If I see correctly, your menu rotates slightly (like a black bar?). So, I suppose you do not change this bar. Otherwise, I do not see what will happen to your menu.

If this is not what you are looking for, could you explain in more detail what transformation you will add to this bar?

Just in case, codepen, where I worked on it: https://codepen.io/fspin/pen/YYJyNY . (There is a funny scroll in the fragment!)


Update . I thought further. It could also be something in the right direction: https://codepen.io/fspin/pen/zpmdOd

There are a few things you will have to consider, I think:

  • For the svg stream to exit the viewport, you would use vw and vh as units, and your container would have the overflow hidden property.
  • To track the position of your black bar, you may need to put it directly into the container. This will cause another problem: it will not exit the viewport. So maybe with two svg? One inside the container and one (real) in the svg shell?

Maybe I overdid it, but I like the challenge. I would like to know more about whether I am thinking in the right direction.

Disclaimer: I am not an expert in SVG, nor in CSS, but I think I understand enough to try to solve this in a not-too-hacked way.

+1
source

Source: https://habr.com/ru/post/1274671/


All Articles