I have a design with one large svg and three divs with text, absolutely positioned with CSS. I need the divs to keep their position in relation to the svg regardless of what the screen size is. That is, I want the text blocks to always stay aligned with the "branches". How do I do that?
Link to Codepen
div {
text-align: center;
position: relative;
}
.box-1,
.box-2,
.box-3 {
position: absolute;
width: 200px;
text-align: left;
}
.box-1 {
top: 50px;
left: 33%;
}
.box-2 {
top: 650px;
left: 52%;
}
.box-3 {
top: 1210px;
left: 36%;
}
.left {
text-align: right;
}
<div>
<svg
width="185"
height="1668"
fill="none"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M39.5 1665c-19.95 2.85 41.323-1.26 64.771-2.89 3.419-.23 5.362-4.82 4.327-8.09-14.809-46.76 97.758-206.14 69.902-341.52-11.147-54.17-45.229-110.52-81-155.5-29.944-37.66-66.9-57.98-80.5-113-4.3-17.39-7.5-61 0-101 7.48-39.898 75.652-305.146 75.999-306.495l.004-.017c.299-1.343 25.703-115.554 35.497-210.988 17.272-168.304-21.4-281.623-76.296-423C95.73 126.455 138.393 276.328 117 463.5c-15.937 139.438-77.961 332.565-86.5 368-18.986 129-54 199 5.5 271.5s115.046 146.4 126 209.5c27.348 157.54-98 349-122.5 352.5z"
fill="#EAECF0"
stroke="#E9EBEF"
strokeWidth="4"
strokeLinejoin="round"
/>
<path
d="M82 1252.94c29.227 11.7 82.878 10.06 82.878 49.65l-3.649 7.89C155 1269.5 95.918 1268.2 82 1252.94zM53.699 105.984c19.085 10.888 35.112 33.394 49.806 52.952v-15.085c-5.59-14.883-38.466-35.764-49.806-42.914-4.816-3.037-14.605-3.284 0 5.047zM78.5 715c-10.345 8.248-21.099 16.711-23.44 30.98l2.968 8.728C64 730.258 97.5 707 111.234 699.579 100.824 702.026 87.1 708.144 78.5 715z"
fill="#E9EBEF"
/>
</svg>
<div class="box-1 left">
<h3>Text</h3>
<p>Lorem ipsum lorem ipsum lorem ipsum lorem ipsum</p>
</div>
<div class="box-2">
<h3>Text</h3>
<p>Lorem ipsum lorem ipsum lorem ipsum lorem ipsum</p>
</div>
<div class="box-3 left">
<h3>Text</h3>
<p>Lorem ipsum lorem ipsum lorem ipsum lorem ipsum</p>
</div>
</div>
Your text is positioned towards the left edge of the surrounding div in percent. If you wan to svg to behave the same, you have to position it as well.
I added css that does that. The main rationale is to treat the elements that are supposed to behave the same the same way.
Update:
You can use padding on the .text-box elements to influence the position of the text. Again, the box is positioned in the exact way as the svg (by percentage of the viewport width). To fine tune the position on in relation to the svg canvas, use something that adds a fixed offset to the percentage wise positioning.
(The .inner elements are only there to display the padding with a background. You can remove them when you're doing this.)
.container {
position: relative;
}
.text-box,
svg {
position: absolute;
left: 33%;
}
svg {
border: 1px solid red;
}
.text-box {
width: 200px;
text-align: right;
border: 1px solid green;
}
.text-box .inner {
background: rgba(255, 255, 0, 0.1);
}
.box-1 {
top: 50px;
padding-left: 20px;
}
.box-2 {
top: 650px;
padding-left: 40px;
}
.box-3 {
top: 1210px;
padding-left: 60px;
}
<div class="container"> <svg width="185" height="1668" fill="none" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">
<path
d="M39.5 1665c-19.95 2.85 41.323-1.26 64.771-2.89 3.419-.23 5.362-4.82 4.327-8.09-14.809-46.76 97.758-206.14 69.902-341.52-11.147-54.17-45.229-110.52-81-155.5-29.944-37.66-66.9-57.98-80.5-113-4.3-17.39-7.5-61 0-101 7.48-39.898 75.652-305.146 75.999-306.495l.004-.017c.299-1.343 25.703-115.554 35.497-210.988 17.272-168.304-21.4-281.623-76.296-423C95.73 126.455 138.393 276.328 117 463.5c-15.937 139.438-77.961 332.565-86.5 368-18.986 129-54 199 5.5 271.5s115.046 146.4 126 209.5c27.348 157.54-98 349-122.5 352.5z"
fill="#EAECF0"
stroke="#E9EBEF"
strokeWidth="4"
strokeLinejoin="round"
/>
<path d="M82 1252.94c29.227 11.7 82.878 10.06 82.878 49.65l-3.649 7.89C155 1269.5 95.918 1268.2 82 1252.94zM53.699 105.984c19.085 10.888 35.112 33.394 49.806 52.952v-15.085c-5.59-14.883-38.466-35.764-49.806-42.914-4.816-3.037-14.605-3.284 0 5.047zM78.5 715c-10.345 8.248-21.099 16.711-23.44 30.98l2.968 8.728C64 730.258 97.5 707 111.234 699.579 100.824 702.026 87.1 708.144 78.5 715z"
fill="#E9EBEF"
/>
</svg>
<div class="text-box box-1 left">
<div class="inner">
<h3>Text</h3>
<p>Lorem ipsum lorem ipsum lorem ipsum lorem ipsum</p>
<p>20px padding to the left</p>
</div>
</div>
<div class="text-box box-2">
<div class="inner">
<h3>Text</h3>
<p>Lorem ipsum lorem ipsum lorem ipsum lorem ipsum</p>
<p>40px padding to the left</p>
</div>
</div>
<div class="text-box box-3 left">
<div class="inner">
<h3>Text</h3>
<p>Lorem ipsum lorem ipsum lorem ipsum lorem ipsum</p>
<p>60px padding to the left</p>
</div>
</div>
</div>
When using an inline SVG as a clickable element, clicking it twice may select nearby text.
How can this be prevented without forcing user-select on all nearby elements?
.wrap {
height: 100px;
}
.icon {
height: 100%;
pointer-events: bounding-box;
cursor: pointer;
}
<div class="wrap">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 136 136">
<defs/>
<path fill="none" stroke="rgb(160,70,255)" stroke-width="3" d="M68 134.43A66.43 66.43 0 101.5 68 66.46 66.46 0 0068 134.43zM123.77 68H12.23M68 12.3v111.41"/>
</svg>
</div>
<div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit</div>
Is this what you mean? ( Added user-select: none; )
.wrap {
height: 100px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.icon {
height: 100%;
pointer-events: bounding-box;
cursor: pointer;
}
<div class="wrap">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 136 136">
<defs/>
<path fill="none" stroke="rgb(160,70,255)" stroke-width="3" d="M68 134.43A66.43 66.43 0 101.5 68 66.46 66.46 0 0068 134.43zM123.77 68H12.23M68 12.3v111.41"/>
</svg>
</div>
<div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit</div>
I got a place on my CSS Grid where I am inserting a paragraph of about 15 characters long, I would like to add a background element to it and I want it to have some personality so am using a inline SVG content.
I tried to place it at the bottom with a position:relative but when you change the view-port size it doesn't scale well. I wrapped the SVG code in a container:
.marquee-container {
height: 0;
position: absolute;
width: 500px;
}
And the styles of the SVG:
.svg-marquee {
fill: teal;
stroke-width: 4;
stroke-miterlimit: 10;
cursor: pointer;
transition: .5s;
}
This is the HTML Markup
<div class="home-works">
<div class="head">
<h1>Entries</h1>
</div>
<img class="thumbnail" src="img/profile-picture.png" width="100%"/>
<div class="main-content">
<div class="marquee-container">
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
x="0px" y="0px" viewBox="0 0 634 175" style="enable-background:new 0 0 634 175;"
xml:space="preserve">
<path class="svg-marquee" d="M595.9,173C317,173,317,153,38.1,153C27.3,153,2,157.6,2,151C2,87.5,34.8,87.5,34.8,24c0-6.6-7.5-22,3.3-22
C317,2,317,22,595.9,22c10.8,0,36.1-4.6,36.1,2c0,63.5-32.8,63.5-32.8,127C599.2,157.6,606.7,173,595.9,173z"/>
</svg>
</div>
<div class="post">
<h3>title</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Tempore placeat
maiores ad ullam illo, blanditiis ipsam libero! Aspernatur, mollitia suscipit?
</p>
</div>
</div>
</div>
My item is inside a CSS Grid Layout where post is the class I am using to style the contents of the paragraph. Which is not inside any grid-template-areas, its just a class within an area already defined.
.post {
text-align: left;
position: relative;
z-index: 1;
}
So the scaling doesn't go well, I would like to place the element at the background of the paragraph to be contained, what is the best approach?
.marquee-container {
height: 0;
position: absolute;
width: 500px;
}
.svg-marquee {
fill: teal;
stroke-width: 4;
stroke-miterlimit: 10;
cursor: pointer;
transition: .5s;
}
.post {
text-align: left;
position: relative;
z-index: 1;
}
<div class="home-works">
<div class="head">
<h1>Entries</h1>
</div>
<img class="thumbnail" src="img/profile-picture.png" width="100%" />
<div class="main-content">
<div class="marquee-container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/" x="0px" y="0px" viewBox="0 0 634 175" style="enable-background:new 0 0 634 175;" xml:space="preserve">
<path class="svg-marquee" d="M595.9,173C317,173,317,153,38.1,153C27.3,153,2,157.6,2,151C2,87.5,34.8,87.5,34.8,24c0-6.6-7.5-22,3.3-22
C317,2,317,22,595.9,22c10.8,0,36.1-4.6,36.1,2c0,63.5-32.8,63.5-32.8,127C599.2,157.6,606.7,173,595.9,173z"/>
</svg>
</div>
<div class="post">
<h3>title</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Tempore placeat maiores ad ullam illo, blanditiis ipsam libero! Aspernatur, mollitia suscipit?
</p>
</div>
</div>
</div>
Since you are positioning the .marquee-container absolutely.
You need a parent to have position set to relative, So, add position: relative on the parent .main-content.
I don't understand why you set the .marquee-container height to 0.
I would suggest set it's height to auto and have a bottom: 0;, (As you wanted it to be aligned to bottom of the container).
Set the width to 100% since you want it to be scalable. also add a negative z-index so that the element doesn't cover up the contents.
Check the snippet below.
.main-content {
position: relative;
}
.marquee-container {
position: absolute;
bottom: 0;
height: auto;
width: 100%;
z-index: -5;
}
.svg-marquee {
fill: teal;
stroke-width: 4;
stroke-miterlimit: 10;
cursor: pointer;
transition: .5s;
}
.post {
text-align: left;
position: relative;
z-index: 1;
}
<div class="home-works">
<div class="head">
<h1>Entries</h1>
</div>
<img class="thumbnail" src="img/profile-picture.png" width="100%" />
<div class="main-content">
<div class="marquee-container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/" x="0px" y="0px" viewBox="0 0 634 175" style="enable-background:new 0 0 634 175;" xml:space="preserve">
<path class="svg-marquee" d="M595.9,173C317,173,317,153,38.1,153C27.3,153,2,157.6,2,151C2,87.5,34.8,87.5,34.8,24c0-6.6-7.5-22,3.3-22
C317,2,317,22,595.9,22c10.8,0,36.1-4.6,36.1,2c0,63.5-32.8,63.5-32.8,127C599.2,157.6,606.7,173,595.9,173z"/>
</svg>
</div>
<div class="post">
<h3>title</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Tempore placeat maiores ad ullam illo, blanditiis ipsam libero! Aspernatur, mollitia suscipit?
</p>
</div>
</div>
</div>
I have a shape I'm trying to put on top of a text box with a background image. This shape will go in different sized containers and scale responsively. The issue I'm having is the background image scales as well, and I would like for it to stay the same size without using a clip path. Please see the code for what I'm talking about. This is driving me crazy!
.container {
width: 75%;
}
.box {
background-image: url("https://s22.postimg.org/dhkk3e8sh/Blue_881.jpg");
padding-top: 5px;
padding-left: 25px;
padding-right: 20px;
padding-bottom: 5px;
margin-top: -5px;
}
p {
color: white;
}
<div class="container">
<svg width="100%" height="auto" viewBox="375 265 1268 45.3">
<defs>
<pattern id="img1" height="30%" width="30%"
patternContentUnits="objectBoundingBox"
viewBox="0 0 1 1" preserveAspectRatio="xMidYMid slice">
<image height="1" width="1" preserveAspectRatio="xMidYMid slice"
xlink:href="https://s22.postimg.org/dhkk3e8sh/Blue_881.jpg" />
</pattern>
</defs>
<path d="M369,291.8v19.7h1280v-22.7c0,0-137-21.6-277-21.6c-308,0-534,34.9-726,34.9C460,302.2,369,291.8,369,291.8z" fill="url(#img1)" />
</svg>
<div class="box">
<p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nec tamen ille erat sapiens quis enim hoc aut quando aut ubi aut unde
</p>
</div>
If you change the percentage size of the container, you'll see what I'm talking about.
Thanks for the help!
For a start you will need to get rid of the viewBox in the SVG. That causes the SVG to get scaled, and that affects anything in the SVG. You'll also want the pattern to be 1:1, so that means switching to patternContentUnits="userSpaceOnUse" and have the pattern use the image at actual size.
We are also using overflow:hidden so that the non-scaling SVG will not force the parent SVG to be wider.
This gets you close. The pattern is now 1:1 but it doesn't exactly line up with the HTML one because they have differing pattern origins. You can adjust that by tweaking the x and y attributes of the pattern until it lines up correctly. I'll leave that to you.
.container {
width: 75%;
overflow: hidden;
}
.box {
background-image: url("https://s22.postimg.org/dhkk3e8sh/Blue_881.jpg");
padding-top: 5px;
padding-left: 25px;
padding-right: 20px;
padding-bottom: 5px;
margin-top: -5px;
}
p {
color: white;
}
<div class="container">
<svg width="1268" height="45.3">
<defs>
<pattern id="img1" patternUnits="userSpaceOnUse" width="881" height="192">
<image width="881" height="192"
xlink:href="https://s22.postimg.org/dhkk3e8sh/Blue_881.jpg" />
</pattern>
</defs>
<path transform="translate(-375 -265)"
d="M369,291.8v19.7h1280v-22.7c0,0-137-21.6-277-21.6c-308,0-534,34.9-726,34.9C460,302.2,369,291.8,369,291.8z" fill="url(#img1)" />
</svg>
<div class="box">
<p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nec tamen ille erat sapiens quis enim hoc aut quando aut ubi aut unde
</p>
</div>
I'd like to position something relatively absolutely, e.g. taking it out of the document flow and adjusting its position a few pixels. What's a neat way to do this?
Just use margin to shift the absolutely positioned element.
HTML:
<p>Lorem ipsum dolar sit amet.</p>
<p class="move">Lorem ipsum dolar sit amet.</p>
<p>Lorem ipsum dolar sit amet.</p>
CSS:
p.move { color:red; position:absolute; margin:5px 0 0 5px; }
Demo: jsfiddle.net/KXCkV
You could put your relatively positioned item within an absolutely positioned container and use top, left, right, or bottom to move it wherever you need to.
This is an example of what you need to do:
<div style="position: relative; width: 500px; height: 200px;">
<div style="position: absolute; left: 0; top: 0;">Upper Left</div>
<div style="position: absolute; right: 0; bottom: 0;">Lower Right</div>
</div>
Only way I could think to do this is to have the element styled in the document on page load and then finding its position and changing the style to position:absolute, setting the top: and left: properties programatically based on it's original location.