I cannot find a good solution to this without using a vuetify fork, which isn't stable and appears to be the older version anyway. I will link to it in the comments.
The only way I can think to do this is to line up two data tables side by side, which creates problems in itself. I know there are other plugins/libraries that allow this, but I would really prefer to stick with vuetify. Has anyone had success with doing this?
My project is to create a grid that allows the user to set up a rotation. Each column (after the first one) is a dynamically created week (Friday's date is column header) that shows if there is an opening in a given organization. The struggle is to get enough weeks to show up on the screen at once. The first column is the organization. So, I want to know what organization my row is in for a given week as I scroll to the right. That's why I need to freeze the first column.
I'm open to other solutions - like a different way to show the header, perhaps, that would allow me to fit in 52 weeks worth of dates.
I am also searching for a solution to this. The nearest I have found is this complex bit of CSS Source
<style>
table > tbody > tr > td:nth-child(1),
table > thead > tr > th:nth-child(1) {
position: sticky !important;
position: -webkit-sticky !important;
left: 0;
z-index: 9998;
background: white;
}
table > thead > tr > th:nth-child(1) {
z-index: 9999;
}
</style>
However, it doesn't quite work for my case.
I have something like this
Account Jan Feb Mar
123456 50 51 52
123458 38 39 32
123600 20 21 22
So what I am looking for is the Excel equivalent of putting a freeze panes on the Jan,123456 intersection, so that the months stay in place when scrolling down, and the Account column stays in place when scrolling to the right.
I set the fixed-header and :height property on the v-data-table so that the header does not scroll vertically and so that it has a vertical scroll bar. The horizontal scroll bar seems to happen automatically and is specific to the table rather than the page.
Without the CSS the vertical scrolling works, though obviously not the horizontal scrolling as the Account column scrolls off screen to the left.
With the CSS the account numbers stay in position, but the headings still scroll to the left, so eg Jan replaces Account. Also when scrolling down, the Account Numbers scroll up to overwrite Account. It is closer to a solution than the basics provided by Vuetify.
I also saw the example from someone who had cloned vuetify and modified it to include fixed columns and grouping. However, I was not sure whether that was vuetify 1.5 or 2 and I have already had issues with seeing examples on 1.5 and then finding that they don't work on vue 2 which I am using as there were so many breaking changes. Like you I am also wary of adopting something that may not be supported.
I am surprised that Vuetify did not include this. It must be a pretty common requirement. I have seen an enhancement request for Vuetify 3, but it is too early to adopt that and presumably it would also mean adopting Vue 3.
Regards
Paul Simon
I finally found an approach to this that works. Another approach
However, I cannot really claim it as an answer to the original question as it only works by abandoning the use of a v-data-table altogether. I ended up just putting a standard table in between v-spacer in my vuetify card. Any attempt to use even a v-simple-table added a second unnecessary horizontal scroll bar which ruined the effect.
The bit of CSS linked above does at least give fixed header(s) and fixed column(s) with none of the issues around scrolling up over the top left corner cell of other approaches I have seen.
It is also very easy to mark which headers you want fixed (usually all) and, in particular, which columns you want fixed. Note that the fixed columns should use 'th' rather than 'td'. This is ideal for my purpose since my data source is multi-dimensional and returns row headers and then cells with numbers eg
Actual Actual Budget Budget
Country Product Jan Feb Jan Feb
UK Widget1 50 60 70 20
UK Widget2 60 80 90 100
USA Widget1 90 80 10 90
In the example above all the following are 'th'
Actual, Budget, Jan, Feb
Country, Product
Only the number cells are 'td'
As you can see, all you need to do is to mark the 'th' in the html with class="fixed" so unlike other approaches it works for an arbitrary number of columns rather than just the left most column.
I am an expert in multi-dimensional modelling, and certainly not an expert in CSS, but I modified the CSS in the linked example a little. My CSS is as follows:
<style scoped>
.table {
background-color: white;
margin: auto;
width:90%;
max-width:100%;
border-collapse: separate;
display: block;
overflow-x: scroll;
}
thead,
tbody {
display: inline-block;
}
thead {
position: sticky;
top: 1px;
z-index: 2;
}
tbody {
height: 200px;
}
th {
background-color: lightgrey;
border-left: 1px;
border-right: 1px;
border-color: black;
}
td,
th {
min-width: 100px;
max-width: 100px;
word-wrap: break-word;
}
.fixed {
position: sticky;
width: 5em;
left: 0;
top: auto;
z-index: 1;
}
td:not(.fixed) {
z-index: 0;
}
</style>
Instead of giving a fixed width for the table, I used %. I know that not all browsers support this but this is going to be an internal application. It is not a shopping site.
I also took the z-indexes down from 9999,999,0 to 2,1,0 as without this it tended to wind up on top of the Vuetify footer when scrolling down.
Regards
Paul Simon
Android and iOS render fonts in vastly different ways. I'd like to be able to get their renders looking a little more similar, so I need to change the font-sizes and weights throughout my entire app depending on whether it's on iOS or android.
Obviously, going through every place font-size or weight is defined and adding a conditional for is out of the question, and (fortunately) I already have all my font sizes and weights defined by sass variables.
Regardless of whether or not there is a better solution than conditional sass variables, I would like to know:
How can I conditionally select sass variables in nativescript?
I know that modules will use MyModule.ios.css or MyModule.android.css depending on the os. Can I take advantage of that?
Yes, you are on right track. You can have MyVariable.android.scss and MyVariable.ios.scss to define different values for Sass variable. In my code sharing project I have MyVariable.scss as well that I use for HTML(Web).
I have created a sample playground for you here.
In my home.component.ios.scss
$labelfontSize: 10;
$labelfontColor: red;
.home-panel{
vertical-align: center;
font-size: 20;
margin: 15;
}
.description-label{
margin-bottom: 15;
color: $labelfontColor;
font-size: $labelfontSize;
}
and in my home.component.android.scss
$labelfontSize: 18;
$labelfontColor: green;
.home-panel{
vertical-align: center;
font-size: 20;
margin: 15;
}
.description-label{
margin-bottom: 15;
color: $labelfontColor;
font-size: $labelfontSize;
}
It shows red text in ios while in android text is green.
I'm wondering, why this double border on table TDs won't show in Chrome but only in FF? Any ideas what could be the work around? Thanks!
http://jsfiddle.net/yQQLk/1/
Not sure why you're using box-shadow to produce a double border, when the border property itself already supports a double border on its own. Just use the following CSS instead of what you've got:
td {
border-bottom: 3px double red;
}
Note you'll need to increase the size of the border to 3px so that both of the lines show up (with 1px, it sometimes doesn't show up at all when you specify double).
The other advantage is that this will work in all browsers, including older ones which don't support box-shadow.
Increase your border thickness to to see a more obvious demonstration of the rendering differences between the two browsers. It seems that in FF, the box-shadow is overlaid on top of the border, in Chrome it hides underneath.
You could use another approach - perhaps use a border-bottom combined with a text-decoration: underline.
Try this, it works in both the browsers:
td {
-moz-box-shadow: 0 1px 0 #000;
-webkit-box-shadow: 0 1px 0 #000;
border-bottom: 1px solid red;
box-shadow: 0 2px 0 #000;
}
I guess, this is the problem: box-shadow: 0 1px 0 #000;
Today I was designing a transparent PNG background that would only sit in the top left of a div, and the rest of the div would maintain a gradient background for all transparent areas of the PNG, and the rest of the div itself.
It might be better to explain through the code I thought might work:
#mydiv .isawesome {
/* Basic color for old browsers, and a small image that sits in the top left corner of the div */
background: #B1B8BD url('../images/sidebar_angle.png') 0 0 no-repeat;
/* The gradient I would like to have applied to the whole div, behind the PNG mentioned above */
background: -moz-linear-gradient(top, #ADB2B6 0%, #ABAEB3 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ADB2B6), color-stop(100%,#ABAEB3));
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ADB2B6', endColorstr='#ABAEB3',GradientType=0 );
}
What I've been finding is that most browsers pick one or the other - most choosing the gradient since its further down the CSS file.
I know some of the guys around here will say "just apply the gradient to the PNG you're making" - but thats not ideal because the div will maintain a dynamic height - sometimes being very short, sometimes being very tall. I know this gradient isn't essential but I thought it might be worth asking y'all what you thought.
Is it possible to have a background image, while keeping the rest of the background as a gradient?
Keep in mind that a CSS gradient is actually an image value, not a color value as some might expect. Therefore, it corresponds to background-image specifically, and not background-color, or the entire background shorthand.
Essentially, what you're really trying to do is layering two background images: a bitmap image over a gradient. To do this, you specify both of them in the same declaration, separating them using a comma. Specify the image first, followed by the gradient. If you specify a background color, that color will always be painted underneath the bottom-most image, which means a gradient will cover it just fine, and it will work even in the case of a fallback.
Because you're including vendor prefixes, you will need to do this once for every prefix, once for prefixless, and once for fallback (without the gradient). To avoid having to repeat the other values, use the longhand properties1 instead of the background shorthand:
#mydiv .isawesome {
background-color: #B1B8BD;
background-position: 0 0;
background-repeat: no-repeat;
/* Fallback */
background-image: url('../images/sidebar_angle.png');
/* CSS gradients */
background-image: url('../images/sidebar_angle.png'),
-moz-linear-gradient(top, #ADB2B6 0%, #ABAEB3 100%);
background-image: url('../images/sidebar_angle.png'),
-webkit-gradient(linear, left top, left bottom, color-stop(0%, #ADB2B6), color-stop(100%, #ABAEB3));
background-image: url('../images/sidebar_angle.png'),
linear-gradient(to bottom, #ADB2B6, #ABAEB3);
/* IE */
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ADB2B6', endColorstr='#ABAEB3', GradientType=0);
}
Unfortunately this doesn't work correctly in IE as it uses filter for the gradient, which it always paints over the background.
To work around IE's issue you can place the filter and the background image in separate elements. That would obviate the power of CSS3 multiple backgrounds, though, since you can just do layering for all browsers, but that's a trade-off you'll have to make. If you don't need to support versions of IE that don't implement standardized CSS gradients, you have nothing to worry about.
1 Technically, the background-position and background-repeat declarations apply to both layers here because the gaps are filled in by repeating the values instead of clamped, but since background-position is its initial value and background-repeat doesn't matter for a gradient covering the entire element, it doesn't matter too much. The details of how layered background declarations are handled can be found here.
You can use Transparency and gradients. Gradients support transparency. You can use this, for example, when stacking multiple backgrounds, to create fading effects on background images.
background: linear-gradient(to right, rgba(255,255,255,0) 20%,
rgba(255,255,255,1)), url(http://foo.com/image.jpg);
The order of the image and gradient is very KEY here, i want to make that clear. The gradient/image combo works best like this...
background: -webkit-gradient(linear, top, rgba(0,0,0,0.5), rgba(200,20,200,0.5)), url('../images/plus.png');
background-image will also work...
background-image: -webkit-gradient(linear, top, rgba(0,0,0,0.5), rgba(200,20,200,0.5)), url('../images/plus.png');
the gradient needs to come first... to go on top. The absolute key here though is that the gradient uses at least 1 RGBA color... the color(s) need to be transparent to let the image come through. (rgba(20,20,20,***0.5***)). putting the gradient first in you css places the gradient on top of the image, so the lower the alpha setting on you RGBAs the more you see the image.
Now on the other hand if you use the reverse order the PNG needs to have transparent properties, just like the gradient, to let the gradient shine through. The image goes on top so your PNG needs to be saved as a 24 bit in photoshop with alpha areas... or a 32 bit in fireworks with alpha areas (or a gif i guess... barf), so you can see the gradient underneath. In this case the gradient can use HEX RGB or RGBA.
The key difference here is the look. The image will be much more vibrant when on top. When underneath you have the ability to tune the RGBA values in the browser to get the desired effect... instead of editing and saving back and forth from your image editing software.
Hope this helps, excuse my over simplification.
This is possible using multiple background syntax:
.example3 {
background-image: url(../images/plus.png), -moz-linear-gradient(top, #cbe3ba, #a6cc8b);
background-image: url(../images/plus.png), -webkit-gradient(linear, left top, left bottom, from(#cbe3ba), to(#a6cc8b));
}
I read about this at Here's One Solution.
UPDATED
* {
margin: 0;
padding: 0;
}
html,
body {
width: 100%;
height: 100%;
}
.hero {
width: 100%;
height: 100%;
min-width: 100%;
min-height: 100%;
position: relative;
}
.hero::before {
background-image: url(https://images.unsplash.com/photo-1566640269407-436c75fc9495?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80);
background-size: cover;
content: "";
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -2;
opacity: 0.4;
}
<div class="hero flex-center">
<div class="hero-message">
<h1 class="hero-title">Your text</h1>
<h1 class="hero-sub-title">Your text2</h1>
</div>
</div>
<div class="not-hero flex-center bg-info">
<div class="not-hero-message">
<h1 class="hero-title">Your text</h1>
</div>
</div>
** It's working**
Transparent images are not yet a CSS standard, yet they are supported by most modern browsers. However, this is part of the W3C CSS3 recommendation. Implementation varies from one client to another, so you will have to use more than one syntax for cross-browser compatibility.
http://www.handycss.com/effects/transparent-image-in-css/
I have a problem with IE.
I have a fixed div like this:
#fixed {
position: fixed;
top: 0px;
left: 0px;
z-index: 9998;
width: 100%;
height: 40px;
}
Inside this div I want to place another div that has a height that is higher than its holder (higher than 40px). So I put a relative or an absolute div inside it and it works splendid in all browsers except IE, at least IE8.
But in IE8 the child div gets cut because of the height of 40px specified for it's holder.
Is there any workaround to this problem? I'm starting to get gray hairs..
Quick reply: have you tried setting the clip property of the contained div to it's own size?
Another workaround would be (if, say you have a container div with left/right margins auto and position: relative) to have the second div outside the fixed div in your HTML, then position it fixed within the container div instead - since it's also fixed, you can then set top/bottom and left/right positions to suit.