Reputation: 3085
I am creating the nav menu for my website and what I would like to do is have the background be a combination of 2 rectangular SVGs, each slightly rotated off axis and overlaid. The edges would extend beyond the edges of the screen so that they cannot be seen. The SVGs should remain the same height(120px) at all breakpoints and the navigation should be centered vertically within the container(even though it will appear off center due to the rotation). My current attempt has the SVGs heights shrinking as I resize the browser window, additionally I am having some issues with the alignment. Is there a better way to accomplish 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>
Once I am able to accomplish these background bars, my plan is to animate them and slightly change the shape(make them not perfect rectangles), as the user scrolls, using MorphSVG. Because of this, the solution must use SVG in place of alternate solutions.
Here's a mockup of my desired result. The nav will be within a container, but the red/black bars should extend to the edge of the screen at any screen size:
Upvotes: 5
Views: 193
Reputation: 161
If I understood good, in your case I would put both svg-bars independently. Maybe, grouped in a div.
(In the next snippet you'll still need to add some media queries to position the ul
in the middle of the black bar, and the whole .navigation
element. But I think you'll get the 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's easy to read/work with two separate svg elements. In this case wrapped in a div. Positioned absolute behind you nav-list.
If I'm seeing right, your Menu has a slightly rotation (as the black bar?). So, I assume you will not transform this bar. Otherwise, I don't see what will happend with your Menu.
If this is not what you are looking for, could you explain, more in detail what kind of transformation you'll add to this bar(s)?
Just in case the codepen where I worked on it: https://codepen.io/fspin/pen/YYJyNY . (In the snippet there is a funny scroll!)
Update: I was thinking further. This may also be something in the right direction: https://codepen.io/fspin/pen/zpmdOd
There are a few things you will have to consider, I guess:
vw
and vh
as units, and your container would have the property overflow
hidden
.Maybe I'm overthinking this, but I like the challenge. Would love to hear more about if I'm thinking in the right direction.
Disclaimer: I'm not an expert on SVG's, nor on CSS, but I think I understand enough to try to solve this in a not too-hacky way.
Upvotes: 1
Reputation: 274384
I would probably go with pseudo element and skew transformation like this:
.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>
Since the solution should be using SVG, here is a solution that involve some js. The idea is to create what I have done previously using skew and svg but with a fixed width. Then I simply use the JS code to scale on widow resize so it remains full width:
$('.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 using background and without any JS (but you won't be able to apply morphing on it as it's a 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>
Upvotes: 1