Aligning SVGs using flex - css

I'm using flex to layout a menu for a website and I'm having a heck of a time trying to align an SVG to the right. I'm not sure what I'm doing wrong because I'm using SVGs inside of flexboxes for my social icons and they're lining up proplerly.
Here is my code for the css and the structure:
.seventh {
display: flex;
width: 100%;
height: calc(100% / 7);
overflow: hidden;
margin: auto;
}
div.link,
div.blank {
display: flex;
justify-content: flex-end;
width: 46.25%;
height: 100%;
position: relative;
flex-flow: column nowrap;
overflow: hidden;
margin-right: 0;
}
.svgLink.left {
display: block;
margin-right: 0;
height: 100%;
}
<section id="blue" class="seventh">
<div class="link">
<svg class="svgLink left" viewBox="0 0 431.1 73.1">
<text transform="matrix(1 0 0 1 -0.2852 63.7813)" font-family="'Panton_xbk'" font-size="74.5982px">MARKETING</text>
</svg>
</div>
<div class="pixel">
<svg class="pixel" viewBox="0 0 512 512">
<circle cx="256" cy="256" r="250" class="vf6"></circle>
</svg>
</div>
<div class="blank"></div>
</section>
This is what I am trying to get it to look like:

There are a few things you should watch out when using flexbox.
If you are trying to align the SVG's to the right the most important thing would be to remove the the last div with class="blank". In general it is actually a bad practice to use empty div's for styling as you can do it with css (especially if you are using flexbox).
If you want to style specific child elements use the appropriate css properties.
There is a really great guide on how to use flexbox layout.
But let's continue with your code example:
I have stripped out unnecessary code from your snippet and modified the css to use the flexbox layout. If you want to align the SVG's to the left use justify-content: flex-start; and if they should be aligned to the right use justify-content: flex-end; in the class selector .seventh as provided in the example below.
.seventh {
display: flex;
flex-flow: row nowrap;
justify-content: flex-end;
align-items: center;
width: 100%;
overflow: hidden;
margin: auto;
}
div.link {
width: 46.25%;
}
div.pixel {
width: 7.5%;
}
div.pixel>svg {
height: 100%;
}
<section id="blue" class="seventh">
<div class="link">
<svg class="svgLink left" viewBox="0 0 451.1 73.1">
<text transform="matrix(1 0 0 1 -0.2852 63.7813)" font-family="'Panton_xbk'" font-size="74.5982px">MARKETING</text>
</svg>
</div>
<div class="pixel">
<svg viewBox="0 0 512 512">
<circle cx="256" cy="256" r="250" class="vf6"></circle>
</svg>
</div>
</section>

Related

Prevent wrapping in flex items

I have two flexbox items next to each other. The left item contains text and must never wrap. The right item contains svgs and I want these svgs to resize as per the available space. I can't get it working.
This is what I have but as you can see the text wraps:
.container {
width: 300px;
margin: 0 auto;
border: 2px blue solid;
display: flex;
flex-wrap: nowrap; /* has no effect */
justify-content: space-between;
}
.nowrap {
flex: 1 1 auto;
margin-right: 15px;
}
.images {
/* flex: 0 0 auto; unsure of this */
display: flex;
max-height: 80px;
}
img {
min-width: 0;
height: auto;
width: 100%;
}
<div class="container">
<span class="nowrap">Never wrap</span>
<div class="images">
<img src="https://assets.codepen.io/3/kiwi.svg" />
<img src="https://assets.codepen.io/3/kiwi.svg" />
<img src="https://assets.codepen.io/3/kiwi.svg" />
<img src="https://assets.codepen.io/3/kiwi.svg" />
<div>
</div>
I've started a CodePen with different (but similar) markup. In there I would assuming flex: 1 1 auto; means that that flex item has 'priority' and won't wrap. But because it's not working I suspect I have a fundamental misunderstanding of flexbox. (and maybe svgs are making it extra complicated as svgs are documents, not images)
As a bonus question. I want left & right flexboxes to be pushed part (justify-content: space-between) and in case the container width is really big, apply a max-height or max-width on the svgs.
Thank you!
There's nothing in your nowrap class instructing the text not to wrap.
It's just this:
.nowrap {
flex: 1 1 auto;
margin-right: 15px;
}
Add this:
.nowrap {
flex: 1 1 auto;
margin-right: 15px;
white-space: nowrap;
align-self: center; /* optional */
}

Flexbox and SVG content

<body>
<div class="home">
<div class="title-header">
<div>HEADER</div>
</div>
<div class="main">
<div class="left-pane">
<div class="content">
<!-- SVG overflows the container on resize -->
<svg height="100%" width="100%" viewbox="0 0 200 200" preserveAspectRatio="xMidYMin meet">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg>
<!-- Using a Div instead works great!
<div style="width: 100%; height: 100%; background-color: white">
</div> -->
</div>
</div>
<div id="rightpane" class="right-pane">
<button onClick="toggleSize()">Resize</button>
</div>
</div>
</div>
<div class="footer">
<div>FOOTER</div>
</div>
</body>
</html>
.home {
display: flex;
flex-direction: column;
width: 1000px;
height: 800px;
background-color: lightgray;
}
.title-header {
width: 100%;
display: flex;
flex: 0 0 35px;
height: 35px;
background-color: lightblue;
align-items: center;
justify-content: center;
}
.main {
display: flex;
width: 100%;
flex: 1;
background-color: lightgreen;
}
.left-pane {
display: flex;
flex: 1;
flex-direction: column;
background-color: white;
}
.right-pane {
flex: 0 0 350px;
width: 350px;
border-left: 1px solid lightgray;
&.min {
flex: 0 0 100px;
width: 100px;
}
}
.content {
width: 100%;
height: 100%;
background-color: yellow;
}
.footer {
display: flex;
position: absolute;
top: 810px;
left: 0px;
flex: 0 0 35px;
width: 1000px;
height: 35px;
border: 1px solid black;
align-items: center;
justify-items: center;
}
Example is here: https://codepen.io/johnny4111/pen/ZEYNqyq
I have a structure as in the example, it's a container that has a left and right pane. The right pane can be minimized programmatically. The Left pane has an SVG set to take up 100% height and 100% width. The left pane has flex-grow set to 1 so that it takes up 100% of the free height but should not exceed the bounds of it's parent div.
The expectation is when the right pane is minimized and the left pane expands it's width to take up the now available free space the SVG should still constrain itself to the available height (100% height) since the height has not changed, just the width. However, in reality it overflows the div. There is a absolute positioned footer at the bottom so you can see it overflows into that.
Any ideas what the problem is? If I use a regular div set to 100% width, 100% height instead of an SVG it works without any issues. The Div does not overflow it's parent.

How To Kern SVG text

I have some SVG text on a web page and I would like to kern a couple of the letters - how do I go about doing this? With HTML I would just wrap the letters in <span> tags and move them with the position property, but this doesn't work with SVG.
For instance, how would I move the letter 'o' in work in the code snippet provided?
Any help would be awesome.
body {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width: 100%;
height: 300vh;
margin: 0;
padding: 0;
font-family: arial-black;
}
text {
font-size: 2rem;
}
<svg class="git-svg" width="500" height="400" viewBox="0 0 500 400">
<text x="15" y="26" fill="#000">How We Work</text>
</svg>
codepen: https://codepen.io/emilychews/pen/PgmoOE
SVG has a tspan tag that you're supposed to use for precise positioning of text within a text element:
https://developer.mozilla.org/en-US/docs/Web/SVG/Element/tspan
You can only try property letter-spacing.
body {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width: 100%;
height: 300vh;
margin: 0;
padding: 0;
font-family: arial-black;
}
text {
font-size: 2rem;
letter-spacing: 2px;
}
<svg class="git-svg" width="500" height="400" viewBox="0 0 500 400">
<text x="15" y="26" fill="#000">How We Work</text>
</svg>

strange behavior / problems with the positioning of a text in an SVG // IE problems

I'm just about to position a text (a headline) in a SVG vertically AND, that the IE also kept the peculiar width. BUT in IE, this headline is made smaller and somehow funny. Well, now I've read about a paddin-bottom-hack that I've used now. Here is my source code:
h1 {
display: flex;
flex: 0 0 3em;
min-height: 5em;
flex-direction: column;
justify-content: center;
align-content:center;
font-family: 'Variable-Bold';
font-size: 1.6em;
line-height: 1;
letter-spacing:0;
margin-right: 0.6em;
max-width: 3.5em;
border: 6px dotted yellow;
}
.scaling-svg-container {
position: relative;
width: 100%;
padding: 0;
padding-bottom: 100%;
}
h1 svg {
display: inline-block;
height: 100%;
max-height: 13em;
position: absolute;
height: 100%;
width: 100%;
left: 0;
top: 0;
}
<h1 class="scaling-svg-container"
style="padding-bottom: 24.0385%">
<svg viewBox="0 0 50 208" preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg">
<path id="verticalPath" fill="none" stroke="none" d="M37.05,208 V0"/>
<rect x=4 y=4 width=42 height=200 stroke-width="3" stroke="#ff6e00" fill="none"/>
<text x="104.3" text-anchor="middle" fill="#ff6e00">
<textpath href="#verticalPath">Meine Überschrift</textpath>
</text>
</svg>
</h1>
In IE it currently looks like this:
SCREEN IE
The headline is displayed within the area with (orange) border from the middle (indicated here with a yellow line) towards the top! WHY DO THIS BELOW? Why is not the headline displayed from bottom to top? What is wrong here in the source code? And that is only in IE!
Second PROB)
In all other browsers, the orange-bordered headline is now no longer displayed (vertical) centered (in the up-front yellow, dotted area), the display flex; and flex-direction: column; justify-content: center; align-content: center; , all that does not work now, suppose that has the position: relative; / position: absolute; to do. With which option can I now in (two) directions (what just get content-content: center; align-content: center; get) this heading (center) position? How do you do that?
Oh yes: An example can be seen here Visual link website
Can you help me please?
The misanthrop

Achieving an Overlapping image in a flex container with object-fit

Hey there i have asked a similar question before and was able to achieve it , the thing is that i had to use a png image, the downside is that its way too big.
After some research i found a method using a svg container and a alpha and beta channel of the image.
However the main difficult i ran into is to get object-fit working so the image will always cover the full 50% of its flexbox container... is that even possible? what am i missing..thanks a lot.
https://codepen.io/HendrikEng/pen/RVzYoR?editors=0100
.c-hero {
align-items: center;
display: flex;
flex-direction: row;
justify-content: center;
background: grey;
height: 30px * 15;
text-align: center;
&__image {
display: flex;
margin-bottom: -60px;
margin-top: 60px + 19px;
max-height: 682px;
min-height: calc(100% + 140px);
object-fit: cover;
object-position: top;
width: 50%;
}
&__item {
align-self: center;
width: 50%;
}
}
<section>
<div class="c-hero">
<svg class="c-hero__image" preserveAspectRatio="xMinYMin" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<mask id="transparentmask">
<image width="100%" height="100%" xlink:href="http://i.imgur.com/n080w42.png"></image>
</mask>
</defs>
<image mask="url(#transparentmask)" width="100%" height="100%" xlink:href="http://i.imgur.com/LTgnz9E.jpg"></image>
</svg>
<div class="c-hero__item">
<p>Lorem Ipsum</p>
</div>
</div>
</section>
Please put the following css to your codepen:
/**
* #define c-hero; weak
*/
.c-hero {
align-items: stretch;
display: flex;
flex-direction: row;
justify-content: center;
background: grey;
height: 28.45vw;
text-align: center;
&__image {
flex: 1 0 auto;
min-height: 130.96%;
}
&__item {
align-self: center;
width: 50%;
}
}
Though the question suggests of using overlapping images the actual scenario if I interpret it correctly is to have an image and a filled container side by side. The image to be used is the one having a little transparency at it's bottom. So while our eyes might differentiate the difference, for a browser its just the whole image.
Since you want the Height of the container next to the image = to be of the height of the image - the height of the transparent/white region.
There are few ways it can be achieved
1) Using 2 separate images:
The part which looks like it's overlapping can be a different image with absolute positioning having z-index greater than the background image element.
The background image element and the next filled-container can have the same height.
2) If we have a fixed height for image then we can for this particular case use 86% of the image height for the other half. It will produce the same illusion. 86% because the background fully covered is 86% of that of the whole image. Yeah I measured the pixel ratio using GIMP.
This particular case has more to do with the image size you are using rather than some programming skills. Though what you seek can be achieved.
To replicate that I created this responsive solution in codepen.
.wrapper {
max-width: 1200px;
margin: 0 auto;
}
.hero-img {
background-image: url(http://i.imgur.com/CkwLRd0.jpg);
background-size: cover;
background-position: bottom;
background-repeat: no-repeat;
width: 100%;
height: 100%;
}
.banner {
display: flex;
}
.half {
width: 50%;
height: 400px;
}
.red {
background: indianred;
}
.text-holder {
height: 86%;
}
<div class="wrapper">
<div class="banner">
<div class="half">
<div class="hero-img"></div>
</div>
<div class="half">
<div class="red text-holder"></div>
</div>
</div>
</div>
Please note that the wrapper is set to max-width: 1200px due to the relative image size used.
Let me know if it solved your issue or if you need some more help.

Resources