I currently have a polygon with text inside shown below
.title {
clip-path: polygon(1% 0, 100% 15%, 96% 90%, 0 75%);
background-color: blue;
color: #FFF;
font-size: 1.7em;
line-height: 50px;
height: 60px;
width: 250px;
}
<h1 class="title"> WELCOME TO</h1>
I am looking for a more browser friendly version of this so I've been looking into using an SVG image. I'm struggling to nicely code this, as you see below I have the SVG shape, after a bit of testing, I quickly realised it doesn't scale well with the browser width. I would be happy if I could just keep it the same size all the time.
Then for the text after researching I learnt about the tag inside an tag, but even that I'm struggling to format the text.
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 7 9" version="1">
<polygon points=".1 0,5 .2,4.4 1.8,0 1.6" style="fill: #253234;" />
<text x="1" y="1" fill="white" style="font-family:arial; font-size:.4">WELCOME TO</text>
</svg>
Does anyone know of a better way of doing this, that works on major browsers and devices?
if i were you i would try to achieve the same effect with only css using rotation for the container, inverting the text rotation with the same amount, then using a pseudo element (:after) with absolute positioning to achieve the non rectangular shape effect.
run the snippet for an example that you can adjust to fit your needs.
.container {
transform:rotate(3deg);
display:inline-block;
position:relative;
top:50px;
padding:20px 30px 20px 20px;
background-color:blue;
}
.container:after {
content:'';
display:block;
background:white;
width:20px;
height:110%;
position:absolute;
top:0;
right:-10px;
transform:rotate(10deg);
}
.title {
color:#fff;
display:inline-block;
font-size:18pt;
text-transform:uppercase;
font-family:arial;
transform:rotate(-3deg)
}
<div class="container"><span class="title">Welcome to </span></div>
Since the first and second version you gave differ so much, I am not that sure what it is you want to achieve. I'm going mostly with the first one.
The main trick is with the way you use the viewBox attribute (and its accompaining preserveAspectRatio). Think of the viewBox as a rectangle that is fit into the area you define with width and height. (here, spelled out in CSS.) The preserveAspectRatio describes the fitting rule: choose the largest possible size for the rectangle that fits inside the element, and move it to the left and vertically to the middle.
Everything inside the <svg> now will remain fixed in position and proportion to that rectangle. If you raise the height of the element, the size of the text will grow; and if you lower its width, eventually it will shrink, but always together with the polygon.
I've positioned the text with text-anchor: middle, which is the equivalent of text-align: center for SVG. Using a font size of 0.4 as you did is not a good idea; browsers are prone to handle values below 1 incorrect.
Finally, if you are using this in place of a <h1> tag, you should either surround it with that to retain accessability, or set appropriate ARIA attributes as shown:
.title {
height: 60px;
width: 100%;
display: block; /* not needed if surrounded by <h1> */
}
.title polygon {
fill: blue;
}
.title text {
font-family: Arial;
font-size: 24px;
fill: #FFF;
text-anchor: middle;
}
<svg class="title" viewBox="0 0 250 60" preserveAspectRatio="xMinYMid meet"
aria-role="heading" aria-level="1">
<polygon points="2.5,0 250,9 240,54 0 45" />
<text x="125" y="36">WELCOME TO</text>
</svg>
Related
I would like to make a button in the form of a signpost (rectangle with tip).
_______
| \
|_______/
I want to dynamically write text into the sign, each with different lengths.
If I try this only with a graphic as background graphic, the arrowhead is scaled with and compressed / stretched accordingly.
Therefore the approach to put the text in a normal div and attach the arrowhead as SVG using CSS :after.
The arrow should be fully filled, i.e. I don't have to deal with frame problems. (To increase the visibility I left the SVG black)
My first problem is that the arrowhead is always in the block instead of behind it. this I solved with position:absolute;. But further fine tuning fails, because I can't position based on the end of the block with left: and right:
Questions:
How do I have to position so that the triangle always connects exactly to the end of the box. (no white betwwen)
How can I scale the SVG with the size (height) of the box. (So that the edges fits) (maybe also with consideration of the paddings of the )
Or am I completely on the wrong track with the approach via :after and should rather append the arrow (as SVG file) direkt in the HTML behind the text (text ay enclose with ) and enclose all with the ? But actually I wanted to avoid that, the insert via CSS would be nicer. But if that is the more useful way, I can live with it.
.querverweis{
background-color: #005000;
color: #ffffff;
display: inline-block;
margin: 10px
margin-left: -10px
}
.querverweis:after {
content: url("data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' version='1.1' width='32' height='40' viewBox='0 0 66 100' xml:space='preserve'%3E%3Cpath d='M0 0 L66 50 L0 100 L0 0' style='fill=rgb(0,0,0)'/%3E%3C/svg%3E%0A");
position: absolute;
}
<div class="querverweis">Test</div>
As A Haworth mentions, clip-path might be simpler. To do this, add some padding to the right of the button to always have space where the arrow will live and then clip-path the whole element
.querverweis {
position: relative;
background-color: #005000;
color: #ffffff;
display: inline-block;
padding: 0.5rem 1.5rem 0.5rem 0.5rem;
clip-path: polygon(0% 0%, calc(100% - 1rem) 0, 100% 50%, calc(100% - 1rem) 100%, 0% 100%);
}
<div class="querverweis">Test</div>
<br>
<br>
<div class="querverweis">Test with more text</div>
<br>
<br>
<div class="querverweis" style="max-width:6rem">Test with multi-line text</div>
I am trying to build the following diagrams using CSS.
I have tried different methods, such as rotating borders, but everything I've tried does not lead to promising results.
What method can I use to build the following diagrams using CSS?
I'd say it would be easier for you to plot those diagrams using SVG (Scalar Vector Graphics). Here's an example of one of those diagrams I did for you to understand. You can put all of the SVG in a flexbox, CSS Grid, or table as you prefer.
<svg height="200" width="200">
<polyline points="20,20,60,60,20,100,60,60,120,60,160,20,120,60,160,100" style="fill:none;stroke:black;stroke-width:3" />
<text x="10" y="60" fill="gray">WBC</text>
<text x="80" y="50" fill="gray">HGB</text>
<text x="80" y="80" fill="gray">Hct</text>
<text x="140" y="60" fill="gray">Plt</text>
</svg>
What do the numbers mean?
The polyline provides with the functionality of drawing polygons by
making use of coordinates to move the cursor around with X and Y
co-ordinates while connecting the previous and the next coordinate.
The origin of a SVG diagram is by default at the top-left (x=0,y=0)
of your container. For this diagram, we took the initial position to
be (20,20) the first 2 coordinates in the polyline points
attribute. And then we move to (60,60) which connects the point
(20,20) to (60,60) making this:
<svg height="200" width="200">
<polyline points="20,20,60,60" style="fill:none;stroke:black;stroke-width:3" />
</svg>
Similarly, we move to (20,100) and remember to trace back, we use
(60,60) again as shown. Think of it as a pen point which can't be held
up and needs to move around while being on the sheet. The only
alternative is to trace back paths.
The style attribute style="fill:none;stroke:black;stroke-width:3"
let's you set the properties of the line which you are connecting. And
you can add text simply by using the text tag and mentioning the X
and Y coordinates` as demonstrated.
Try to tweak it around :) Hope,
it helps.
You can lookup and refer to more of this on here : https://www.w3schools.com/graphics/svg_intro.asp
Consider using HTML5 canvas to achieve this result.
Please see the following tutorial for a simple introduction: https://www.w3schools.com/html/html5_canvas.asp
The HTML5 canvas should allow you to display and manipulate both text and shapes, providing the tools needed to achieve the effect you're aiming for.
With pure CSS, you can create first-one using border and transform rotate on first and last elements and then rotate again span elements inside to return text to normal.
.el-1 {
display: flex;
}
.el-1 > div:first-child,
.el-1 > div:last-child {
width: 50px;
height: 50px;
text-align: center;
line-height: 50px;
transform: rotate(45deg);
}
.el-1 > div:first-child {
border-top: 1px solid black;
border-right: 1px solid black;
}
.el-1 > div:last-child {
border-bottom: 1px solid black;
border-left: 1px solid black;
}
.el-1 > div > span {
transform: rotate(-45deg);
display: block;
}
.inner {
width: 70px;
text-align: center;
line-height: 25px;
padding: 0 10px;
}
.inner > div:first-child {
border-bottom: 1px solid black;
}
<div class="el-1">
<div><span>A</span></div>
<div class="inner">
<div>B</div>
<div>C</div>
</div>
<div><span>D</span></div>
</div>
I've a trapezoid shapes in CSS, but the problem is that I also need the same kind of trapezoid turning the borders opposite, the first trapezoid css is something like this:
#trapezoid1 {
height: 0;
width: 350px;
border-bottom: 190px solid rgb(2, 145, 178);
border-left: 45px solid transparent;
border-right: 45px solid transparent;
padding: 0 8px 0 0;
display:block;
position:relative;
}
But I also need the second trapezoid turning the border-bottom to border-top, however in that case, the text is being flew away from the actual trapezoid.
I did border-top instead of border-bottom to turn the trapezoid opposite.
Here's the full display of the problem.. jsfiddle
Your best option is to use pseudo elements so you dont have to use absolute positioning on the text element.
Using both :before and :after will help create the desired shape. The borders are also transparent so you don't have to worry about background images being coloured over.
#trapezoid {
width: 260px;
height: 190px;
background: red;
margin-left: 45px;
position: relative;
}
#trapezoid:before {
content: '';
border-right: 45px solid red;
border-bottom: 190px solid transparent;
position: absolute;
left: -45px;
top: 0;
}
#trapezoid:after {
content: '';
border-left: 45px solid red;
border-bottom: 190px solid transparent;
position: absolute;
right: -45px;
top: 0;
}
<div id="trapezoid">
Text in here
</div>
You can also refer to one of my previews answers which give a good overview at all of the different possible ways of creating a CSS trapezoid.
Responsive CSS Trapezoid Shape
How about this:
HTML (add span tags around trap2 text)
<div id="trapezoid1">
Designing Something
</div>
<br/>
<div id="trapezoid2">
<span id="trap2-text">Designing Opposite</span><!-- NEW -->
<!-- I need the text in proper place which currently isn't -->
</div>
CSS (add one rule)
#trap2-text {
position: absolute;
top: -190px;
left: -25px;
}
DEMO
I generally like pure css shapes, but I thought SVG might make your life easier in this case so I started fiddling around with your fiddle. I'm not completely satisfied with the results but it gives some advantage like dynamic size.
Fiddle with comments: http://jsfiddle.net/bo5k36pa/8/
If you want to use this solution I highly recommend to encode your inline svgs in base64 to avoid compability and encoding problems. See this answer for details.
Explanation
The idea was to use an inline svg as background image, so it will stretch to containers of any size.
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 4 2" preserveAspectRatio="none"><path style="fill: rgb(2, 145, 178);" d="M 0.5 0 L 3.5 0 L 4 2 L 0 2 Z" /></svg>');
background-size: 100%;
The path that makes up the trapez could be modified, if different angles or shapes are required, it could even be generated dynamically using javascript. But the real bummer here is, we can't style inline svg background images. Meaning for example to change just the fill color we have to define the entire svg markup again.
Possible solutions to avoid multiple inline svgs
Use <use>. You can define <symbols> in an external svg file and reference them in an inline <svg> via their id attributes. And we can still style those symbols using CSS. However, it would require a fair amount of extra markup in every container. Something like this:
<svg viewBox="0 0 4 2" role="img" title="Trapez"><use xlink:href="path/to/images/shapes.svg#trapez"></use></svg>
Use CSS filters to change appearance. Example fiddle / Browser Support
Go back to CSS Shapes. I'd recommend to take advantage of :before and :after pseudo elements to keep such fancy appendages a bit separate from your content box.
I would like to place a responsive text block on top of an image that I have set up based on this dated tutorial and amended based on this previous question.
Unfortunately there appears to be a couple of bugs. the span.spacer used to create padding either side of the line break appears taller than the rest of the text block, and I also think it is causing the text to not align left correctly. The development page can be viewed here. You can see a taller black block at the end of the first line of text, and a taller black block at the beginning of the second line.
The CSS i'm using is
}
.image {
position: relative;
width: 100%; /* for IE 6 */
}
.image h2 {
position: absolute;
bottom: 20px;
left: 0;
width: 100%;
text-shadow: none;
}
h2 span {
color: #fff;
font-size: 110%;
width: 40%;
line-height: 110%;
padding: 0 20px;
background: rgb(0, 0, 0); /* fallback color */
background: rgba(0, 0, 0, 0.7);
}
h2 span.spacer {
padding:0 5px;
}
The HTML is
<div class="image">
<img alt="Trekking" src="http://davidkneale.com/wc/wp-content/uploads/borneo_trek_mock.jpg" />
<h2><span>Trekking:<span class='spacer'></span><br />
<span class='spacer'></span>It's a Jungle Out There</span></h2>
</div>
Any advice on a fix for this or a better way to do it much appreciated!
It is becase you have span element in another span element (they are overlaid) and CSStyle is applied to both.
I think you can modify selector to: h2>span {...},
You can use one span element for each line (each with diferent look):
<h2>
<span class="big">Trekking:</span>
<br>
<span>It's a Jungle Out There</span>
</h2>
h2 span {
color: #fff;
font-size: 110%;
line-height: normal;
padding: 0 20px;
background: rgb(0, 0, 0); /* fallback color */
background: rgba(0, 0, 0, 0.7);
display: inline-block;;
}
h2 span.big {
font-size:130%;
}
Width 40% was too short.
The reason for the increased height is the span within a span causing the font-size 110% to be applied twice. Set font-size 100% on the spacer.
You also probably want an increased line height (more like 140% than 110% with the font you're using), and a spacer padding of 10px to match the 20px of the start/end. It does feel like there should be a simpler way to do this!
You are right, this tutorial is quite outdated – I would not bother with that “spacer-span” mumbo-jumbo at all.
And while it is not possible to have a horizontal padding applied to each line of an inline element (it’ll only be applied before the first and after the last line) – it is possible to use box-shadow to achieve a similar effect (as long as only a background color is required, and not f.e. an image).
<div>
<img src="http://davidkneale.com/wc/wp-content/uploads/borneo_trek_mock.jpg">
<h2><span>Trekking:
It’s a Jungle Out There</span></h2>
</div>
div { position:relative; }
img { display:block; max-width:100%; }
h2 { position:absolute; bottom:0; left:.5em; white-space:pre; line-height:1.333; }
h2 span { padding:.125em 0 .125em .25em; background:rgba(0,0,0,.75); color:#fff;
box-shadow:-.5em 0 0 rgba(0,0,0,.75), .5em 0 0 rgba(0,0,0,.75); }
See it here in this fiddle: http://jsfiddle.net/FXJEL/
I gave the span element a padding-left here to have the first line of text be slightly moved to the right, as in your example – assuming that is a desired effect; if not, simply remove it.
And instead of using a <br> to break the text into two lines, I used
for a line break character, and white-space:pre to have it displayed as such. But feel free to change that back to using a br element if that seems more convenient.
The span element inside the h2 is necessary here to have an inline element, because only that will behave like this regarding the element dimensions; under normal conditions, one could of course make the h2 display as inline, but that does not work here, because the h2 is positioned absolutely, and that “overwrites” display:inline, and one would end up with a box that is as wide as the whole text.
I am attempting to get two images to touch with CSS.
<div>
<image src="scroll><br>
<image src="scroll>
</div>
* {
margin: 0px;
padding: 0px;
}
body {font-family:Courier New, Courier New, Courier New;
background-image: url(background.jpg);
background-repeat: repeat;
width:100%;
height:100%;
}
When using this code I get
The reason they don't touch is because of line height. Images are inline by default, meaning the gap between text lines is still there. You have to turn this off. The better way is to make the images block, rather than inline:
img { display: block }
Or inline-block.
The other way is to set line-height: 0 on the containing div
Be sure that you are also using the correct tag. Images use <img> not <image>
Am not understanding which image are you talking about, no live example given, if it's the yellow 1 than why are you using <br>?
<div>
<image src="#" />
<image src="#" />
</div>
Also be sure you have resetted the default browser styles
* {
margin: 0;
padding: 0;
}
If required also try setting line-height: 0; as Nicholas told you to do..
either your image itself has extra spacing, or use this css:
img {
padding:0;
margin:0;
}