I'm thinking about a website design, kinda new to HTML/CSS and JS. My issue is related only to HTML and CSS. I'd like to make a sort of polygon shape that would be either transparent or white in which I can put text in and it would wrap the text according to the shape of the box. I'm attaching an image of how I'm thinking of making it but I can't seem to come to conclusion. I was thinking of making a normal polygon shape just like that and then separate the text into different classes and then wrap them and position them as they are but that seems kinda messy. Is there any better simpler way of doing this? Thanks in advance.enter image description here
I tried making it like this with a polygon shape, and then making different classes for text and then wrapping it so it fits into the shape. That honestly feels a bit messy. Any insights of how could I do that pls?
<section>
<div class="container">
<div class="clip-path-inset-square"></div>
</div>
</section>
<style>
.body {
margin: 0;
padding: 0;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
}
.container {
width: 500px;
height: 450px;
border: 5px solid lightgrey;
background: blue;
position: relative;
margin: 5px;
display: flex;
justify-content: center;
align-items: center;
}
.clip-path-inset-square {
width: 250px;
height: 250px;
background-color: brown;
clip-path: polygon(
60% 70%,
60% 30%,
100% 30%,
100% 0%,
2% 1%,
0% 100%,
100% 100%,
100% 70%
);
}
</style>
Related
I am having trouble centering a background image. At first I thought there were underlying CSS rules causing it not to work so I created a demo with minimal markup and CSS.
From all examples on SO & elsewhere it seems like I'm doing everything right. Could someone please help to see what I'm missing? I mentioned clip-path: in the title of the question, but playing with these properties doesn't seem to make a difference. Thanks in advance.
Codepen Demo:
https://codepen.io/dickkirkland/pen/rNGbqMr
Markup:
<!-- a demo of positioning dynamic images stored in a database that can vary in size for
an avatar-like presentation in applications -->
<div class="container">
<div class="member-avatar">
<img src="https://memdata-dev.herokuapp.com/images/display_image/H0266" />
</div>
</div>
CSS/SCSS:
.container {
display: flex;
justify-content: center;
background-color:#ccc;
padding:33px;
}
// clip the background to create a round shape
.member-avatar {
-webkit-clip-path: circle(50% at 50% 50%);
clip-path: circle(50% at 50% 50%);
width: 176px;
height: 176px;
background-position: center center;
}
// scale up images that are small in the database
.member-avatar img {
transform: scale(1.5);
}
There is no background image for the background position to affect.
There is an img element but that is not a background in the CSS sense.
You need to position the image so it is at the top but centered on the circle.
This snippet does this with a background and uses size cover which ensures you get things as required (whatever the size of the original image, without needing further scaling, as long as the subject is well placed similarly to the face in this one.
.container {
display: flex;
justify-content: center;
background-color: #ccc;
padding: 33px;
}
.member-avatar {
-webkit-clip-path: circle(50% at 50% 50%);
clip-path: circle(50% at 50% 50%);
width: 176px;
height: 176px;
background-position: center top;
background-image: url(https://memdata-dev.herokuapp.com/images/display_image/H0266);
background-size: cover;
}
<div class="container">
<div class="member-avatar">
</div>
</div>
Currently, I am trying to fit (crop) image on the mobile version of the website, but, with no results...
How it looks on a desktop -
How it looks on a mobile -
Image crops on mobile because position: absolute; margin-left: 50%;, but..., this page has a scroll to the left, like this -
I've tried object-fit, different positions, so on, and no success.
How should it be done?
No image is going to be able to cope with all random viewport aspect ratios.
In this particular design it seems important that the figure is looking at/moving towards the text on the left, so the common method of dealing with narrow portrait viewports by putting one half of the 'header' below the other won't make sense in this case.
One suggestion therefore is to separate out the figure from the background and position and size it in relation to the aspect ratio/size of the viewport. Bearing in mind that the text on the left has to have a certain minimal physical size in order to be readable, this snippet sets a minimum absolute width and also the percentage across the viewport that the figure will stand.
Obviously you will want to alter the actual numbers here to get the layout that is required for narrow as well as wide devices so treat the numbers used here as being just for the demo.
Also, the colored background could be a real image as stretching to use cover would work given its design, but in this snippet it is roughly drawn using CSS just to give the idea. The figure has been roughly cut out of the given image in the question and of course would need to be a better done for a published environment.
* {
padding: 0;
margin: 0;
}
.bg {
--minw: 256px;
/* minimum width we allow the left hand side (with the text) to go */
--textw: max(var(--minw), 50vw);
position: fixed;
top: 0;
left: 0;
height: 100vh;
width: 100vw;
display: inline-block;
}
.bg::before,
.bg::after {
display: inline-block;
position: absolute;
top: 0;
left: 0;
content: '';
background-repeat: no-repeat no-repeat;
}
.bg::before {
width: 100vw;
height: 100vh;
background-image: radial-gradient(circle, rgba(160, 32, 240, .8), transparent), linear-gradient(to right, rgba(0, 0, 0, 0), #00B7EB), linear-gradient(to right, rgba(255, 0, 255, .6), rgba(160, 32, 240, .8));
background-position: center center;
}
.bg::after {
background-image: url(https://i.stack.imgur.com/655zI.png);
background-size: contain;
--pc: 80%;
background-position: var(--pc) center;
--w: calc(100vw - var(--textw));
width: var(--w);
left: calc(100vw - var(--w));
margin: 5% 0;
height: calc(100vh - 10%);
}
.text {
height: 200px;
width: var(--textw);
position: relative;
top: 0;
left: 0;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.innertext {
border: solid white 2px;
color: white;
padding: 5%;
}
#media screen and (max-aspect-ratio: 1 /1) {
body::after {
--pc: 90%;
}
}
<div class="bg">
<div class="text">
<div class="innertext">HERE IS SOME TEXT</div>
</div>
</div>
Additional note: background-attachment: fixed is not fully implemented on all browsers at the moment so the backgrounds are added to pseudo elements on a div which is given position fixed.
Use two different versions based upon the screen size in picture element, or use object-fit in the css for mobile media query.
You are getting a horizontal scroll bar because of the absolute position plus the margin, this would push the image to the right of the screen(assuming 100% wide image). If you wanna keep it this way, use overflow-x: hidden on the html and body tags.
I want to have a split background with a color on the left side and a image on the right side and both should be equally big(50% each). So I know I can style the body like this to get red on 50% left of the body and blue on the right side:
background-image: linear-gradient(to right, red, red 50%, blue 50%, blue);
I would instead want something like this:
background-image: linear-gradient(to right, red, red 50%, url('image.jpg') 50%, url('image.jpg'));
Is this possible or should I take another approach?
I know I can split it up to two divs and make them take up 50% each and set whatever background I want on them but I want to have a navbar that is transparent and it should go from left all the way to the right so that's the problem with having two divs.
Thanks for the help!
You can do
background: linear-gradient(90deg, red 50%, rgba(0, 0, 0, 0) 50%), url('image.jpg');
You can use both together with commas as linear-gradient uses the background-image css property, but using a background image and linear gradient like this seems like the hard way of making this work. If you make an absolute positioned inner container in the nav a with a width of 100% and add two divs inside, those divs can both be 50% and then you can style each accordingly. Make sure the parent element is position: relative so you can set z-index to make the inner-container sit underneath your nav elements. Below is a sample of how it could work. Hope this helps.
Example
nav {
height: 240px;
width: 100%;
display: block;
position: relative;
}
.inner-container {
height: 100%;
width: 100%;
position: absolute;
display: flex;
opacity: 0.5;
z-index: 0;
}
.inner-container > div {
flex: 1 1 50%;
}
#blue-box {
background: linear-gradient(#e66465, #9198e5);
}
#img-box {
background: url(https://teamroboboogie.com/wp-content/uploads/2017/06/campo_logo_lrg.png) no-repeat;
background-size: 100% 100%;
}
ul {
margin: 0;
padding: 0;
display: block;
z-index: 1;
position: relative;
}
li {
display: inline-block;
width: 30%;
background: rebeccapurple;
color: white;
padding: 20px;
box-sizing: border-box;
cursor: pointer;
}
li:nth-child(2) {
margin: 0 5%;
}
<nav>
<div class="inner-container">
<div id="blue-box">
</div>
<div id="img-box">
</div>
</div>
<ul>
<li>This could be a button</li><!--
--><li>This could be a button</li><!--
--><li>This could be a button</li>
</ul>
</nav>
Alright, here is the thing. This is what I'm trying to accomplish, which I did so far:
The problem is I use hardcoded pixels right now, but it really needs to be more responsive. So it needs a height of 100% (not 200px like now). And the total width of the diagonal and content containers needs to be 50%, like the image above (so not hardcoded 100px like now). The main problem seems to be the diagonal, cause it almost seems I can only use pixels and not percentages. So if the content block gets more content, it will expand, but the diagonal will not, which is a problem.
It looks like a position absolute could fix it, but then I can't really place the content and diagonal blocks next to each other anymore. Now I gave them two different colors to be clear, but in the live example they need to look like one shape with the same background color.
.shape {
width:400px;
margin:0 auto;
display: block;
height: 200px;
position: relative;
background-image: url('https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcSQdX7yx0pVXUlaNF7WkbSJpZp5r0TflV3WdsojKKK1Xon_1hh08l4OL1yd');
}
.diagonal {
height:0;
border-width: 0px 0 200px 100px;
border-style:solid;
border-color: transparent transparent transparent #d71f55 ;
float: left;
}
.content {
height: 100%;
width: 100px;
background-color: #888;
float: left;
color: #fff;
}
<div class="shape">
<div class="content">
Content goes here
Like this
</div>
<div class="diagonal"></div>
</div>
EDIT:
By the way, I already tried using two backgrounds as well, like:
background-color: #f87f73;
background-image: -webkit-linear-gradient( -28deg, #f87f73 0%, #f87f73 60%, #292423 60%, #292423 60%);
background-image: linear-gradient( -28deg, #f87f73 0%, #f87f73 60%, #292423 60%, #292423 60%);
But that really got ugly. Too pixelated.
Edit 2:
Browser which needs to be supported:
OS: windows 8/10 :
** browsers: Chrome 47/48
** Firefox 43/44
** Internet Explorer 11
OS: mac OSX 10.9/10.10
** Chrome 47/48
** Firefox 43/44
** Safari 8/9
OS: android 5/6
** Chrome latest version
OS: iOS 8/9
** Safari latest version
You can use viewport related units for the border as described in Shape with a slanted side (responsive). This will allow you to make the shape 50% width and 100% height of the viewport and responsive:
* {
margin: 0;
padding: 0;
}
.shape {
width: 100%;
margin: 0 auto;
display: block;
height: 100vh;
position: relative;
background-image: url('https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcSQdX7yx0pVXUlaNF7WkbSJpZp5r0TflV3WdsojKKK1Xon_1hh08l4OL1yd');
}
.diagonal {
height: 0;
border-width: 0 0 100vh 25vw;
border-style: solid;
border-color: transparent transparent transparent #d71f55;
float: left;
}
.content {
height: 100vh;
width: 25vw;
background-color: #888;
float: left;
color: #fff;
}
<div class="shape">
<div class="content">
Content goes here Like this
</div>
<div class="diagonal"></div>
</div>
Viewport related units (vh and vw) have good browser support. For more info, see canIuse
This is probably how I would approach it. Using a hard 50/50 gradient rather than a border makes it pretty trivial. It seems to render ok in chrome but I haven't checked other browsers. If you want this inside a container remember to set the container to position: relative
.shape {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: auto;
height: auto;
display: block;
background-image: url('https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcSQdX7yx0pVXUlaNF7WkbSJpZp5r0TflV3WdsojKKK1Xon_1hh08l4OL1yd');
}
.content {
height: 100%;
width: 25%;
background-color: #888;
color: #fff;
float: left;
}
.diagonal {
height: 100%;
width: 25%;
background: linear-gradient(to bottom right, #888 50%, transparent 50%);
float: left;
border: none;
}
<div class="shape">
<div class="content">
Content goes here Like this
</div>
<div class="diagonal"></div>
</div>
I am using a gradient background to display an alternating background for absolute positioned rows.
When zooming out in Chrome the layout gets messed up.
The calculation of the gradient background size seems to be different to the calculation of the top margins.
I have created a JSFiddle to illustrate the problem: http://jsfiddle.net/4y3k2/4/. When zooming out to e.g. 75% an offset appears between the foreground and background. The offset sums up more and more so that the layout looks completely broken for the last rows.
Here is my code:
#container {
position: absolute;
height: 2000px;
width: 100px;
background: linear-gradient(red 50%, green 50%, green);
background-size: 40px 40px;
}
.row {
position: absolute;
}
<div id="container">
<div class="row" style="top: 920px;"></div>
</div>
Everything works fine on IE and Firefox.
You can do this without calculating top every single time
for each row.
Instead set the parent div to be a block and use
predefined height and width for each row while floating them to the left:
#container {
position: absolute;
height: 2000px;
width: 100px;
background: linear-gradient(red 50%, green 50%, green);
background-size: 40px 40px;
display: block;
}
.row {
float: left;
width: 100px;
height: 20px;
}
http://jsfiddle.net/4y3k2/11/